Files
open-wc/reference/blender-wow-studio-3.4-1.1.0_Experimental/io_scene_wmo/ui/preferences.py
T

390 lines
14 KiB
Python

from ..config import ADDON_MODULE_NAME
from typing import Optional, List, Tuple
import bpy
def get_addon_preferences() -> 'WBS_AP_Preferences':
"""
Gets current Blender addon preferences for this addon in any context.
:return: Addon preferences.
"""
return bpy.context.preferences.addons[ADDON_MODULE_NAME].preferences
def get_project_preferences() -> Optional['WBS_PG_ProjectPreferences']:
"""
Gets current project preferences in any context.
:return: Project preferences or None.
"""
addon_preferences = get_addon_preferences()
if not len(addon_preferences.projects):
raise UserWarning("No active project. Check WBS settings.")
return addon_preferences.projects[addon_preferences.active_project_index]
class WBS_UL_Projects(bpy.types.UIList):
""" UI List displaying currently saved projects. """
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
split = layout.split(factor=0.3)
split.prop(item, "name", text="", emboss=False, translate=False
, icon='RADIOBUT_ON' if index == data.active_project_index else 'RADIOBUT_OFF')
def invoke(self, context, event):
...
class WBS_PG_ExportMethodSetting(bpy.types.PropertyGroup):
""" Property group for individual export method settings. """
name: bpy.props.StringProperty(
name="Export Setting Name",
description="Name of the export folder setting"
)
value: bpy.props.StringProperty(
name="Export Directory Path",
description="Value of the export folder setting",
subtype='DIR_PATH'
)
class WBS_PG_ProjectPreferences(bpy.types.PropertyGroup):
""" Property group holding data for project preferences set. """
wow_path: bpy.props.StringProperty(
name="WoW Client Path",
subtype='DIR_PATH'
)
wmv_path: bpy.props.StringProperty(
name="WoW Model Viewer Log Path",
subtype='FILE_PATH'
)
wow_export_path: bpy.props.StringProperty(
name="WoW Export Runtimelog Path",
subtype='FILE_PATH'
)
noggit_red_path: bpy.props.StringProperty(
name="Noggit Red log Path",
subtype='FILE_PATH'
)
time_import_method: bpy.props.EnumProperty(
name="Time Conversion Import Method",
items=[
('Convert', "Convert to 30 FPS", "(WBS Method)"),
('Keep Original', "Keep_Original", "Don't convert timestamps"),
],
default='Convert',
description="Choose the preferred method for timestamp import."
)
import_method: bpy.props.EnumProperty(
name="Import Method",
items=[
('WMV', "WMV", "Use WoW Model Viewer"),
('WowExport', "WowExport", "Use WoW Export"),
('NoggitRed', "NoggitRed", "Use Noggit Red"),
],
default='WMV',
description="Choose the preferred method of import for WoW files."
)
export_method_settings: bpy.props.CollectionProperty(
type=WBS_PG_ExportMethodSetting,
name="Export Folder Settings",
description="Settings for the export methods"
)
export_dir_path: bpy.props.StringProperty(
name="Export Directory Path",
description="A directory for WBS to export M2/WBS, could be ascension Data client, or a patch folder inside it.",
subtype="DIR_PATH"
)
active_export_method_index: bpy.props.IntProperty(default=0)
def update_export_dir_path(self, context):
method = self.export_method_settings[int(self.export_method_enum)]
self.active_export_method_index = int(self.export_method_enum)
self.export_dir_path = method.value
def export_method_items(self, context) -> List[Tuple[str, str, str]]:
return [(str(i), method.name, "") for i, method in enumerate(self.export_method_settings)]
export_method_enum: bpy.props.EnumProperty(
name="Export Method",
description="Select Export Method",
items=export_method_items,
update=update_export_dir_path
)
cache_dir_path: bpy.props.StringProperty(
name="Cache Directory Path",
description="Any folder that can be used to store textures and other temporary files.",
subtype="DIR_PATH"
)
project_dir_path: bpy.props.StringProperty(
name="Project Directory Path",
description="A directory Blender saves WoW files to and treats it as top-priority patch.",
subtype="DIR_PATH"
)
merge_vertices: bpy.props.BoolProperty(
name="Merge Vertices Algorythm when quick saving M2's",
description="Use the merge vertices algorythm when quick saving m2's with topbar button",
default=True
)
verbosity_level: bpy.props.EnumProperty(
name="Log Verbosity",
description="Controls how detailed output messages should be",
items=[
('1', "ERROR", "Only show critical errors"),
('2', "WARNING", "Show warnings and errors"),
('3', "INFO", "Show general info, warnings, and errors"),
('4', "DEBUG", "Show all messages including debug output"),
],
default='3',
options=set()
)
scene_type: bpy.props.EnumProperty(
name="Default Scene Type",
description="Controls which scene type should be the default",
items=[
('M2', "M2", "Default to M2"),
('WMO', "WMO", "Default to WMO"),
],
default='WMO',
options=set()
)
class WBS_OT_ProjectListActions(bpy.types.Operator):
"""
Moves items up and down the list of projects, adds or removes.
"""
bl_idname = "wbs.project_list_action"
bl_label = "List Actions"
bl_description = "Move items up and down, add and remove"
bl_options = {'REGISTER', 'INTERNAL'}
action: bpy.props.EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
('REMOVE', "Remove", ""),
('ADD', "Add", ""),
('DUPLICATE', "Duplicate", "")))
@classmethod
def description(cls, context, properties):
match properties.action:
case 'UP':
return "Move project up the list"
case 'DOWN':
return "Move project down the list"
case 'ADD':
return "Add new project"
case 'DUPLICATE':
return "Duplicate current project"
case 'REMOVE':
return "Remove project from the list"
case _:
raise NotImplementedError()
def duplicate_project(self, source, target):
target.name = f"{source.name}_copy"
target.verbosity_level = source.verbosity_level
target.scene_type = source.scene_type
target.wow_path = source.wow_path
target.wmv_path = source.wmv_path
target.wow_export_path = source.wow_export_path
target.noggit_red_path = source.noggit_red_path
target.time_import_method = source.time_import_method
target.import_method = source.import_method
target.cache_dir_path = source.cache_dir_path
target.project_dir_path = source.project_dir_path
target.export_dir_path = source.export_dir_path
target.merge_vertices = source.merge_vertices
for setting in source.export_method_settings:
new_setting = target.export_method_settings.add()
new_setting.name = setting.name
new_setting.value = setting.value
def invoke(self, context, event):
addon_prefs = get_addon_preferences()
idx = addon_prefs.active_project_index
match self.action:
case 'DOWN':
if idx < len(addon_prefs.projects) - 1:
addon_prefs.projects.move(idx, idx + 1)
addon_prefs.active_project_index += 1
case 'UP':
if idx >= 1:
addon_prefs.projects.move(idx, idx - 1)
addon_prefs.active_project_index -= 1
case 'REMOVE':
if len(addon_prefs.projects):
addon_prefs.active_project_index -= 1
addon_prefs.projects.remove(idx)
case 'ADD':
item = addon_prefs.projects.add()
item.name = 'New project'
addon_prefs.active_project_index = len(addon_prefs.projects) - 1
case 'DUPLICATE':
if len(addon_prefs.projects):
source = addon_prefs.projects[idx]
target = addon_prefs.projects.add()
self.duplicate_project(source, target)
addon_prefs.active_project_index = len(addon_prefs.projects) - 1
return {"FINISHED"}
class WBS_UL_Export(bpy.types.UIList):
""" UI List displaying currently saved export methods. """
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
split = layout.split(factor=0.3)
split.prop(item, "name", text="", emboss=False, translate=False
, icon='RADIOBUT_ON' if index == data.active_export_method_index else 'RADIOBUT_OFF')
def invoke(self, context, event):
...
class WBS_OT_ExportMethodActions(bpy.types.Operator):
"""
Adds or removes export method settings.
"""
bl_idname = "wbs.export_method_action"
bl_label = "Export Method Actions"
bl_description = "Add or remove export method settings"
bl_options = {'REGISTER', 'INTERNAL'}
action: bpy.props.EnumProperty(
items=(
('UP', "Up", ""),
('DOWN', "Down", ""),
('ADD', "Add", ""),
('REMOVE', "Remove", "")))
@classmethod
def description(cls, context, properties):
match properties.action:
case 'UP':
return "Move project up the list"
case 'DOWN':
return "Move project down the list"
case 'ADD':
return "Add new export method setting"
case 'REMOVE':
return "Remove selected export method setting"
case _:
raise NotImplementedError()
def invoke(self, context, event):
proj_prefs = get_project_preferences()
idx = proj_prefs.active_export_method_index
match self.action:
case 'DOWN':
if idx < len(proj_prefs.export_method_settings) - 1:
proj_prefs.export_method_settings.move(idx, idx + 1)
proj_prefs.active_export_method_index += 1
case 'UP':
if idx >= 1:
proj_prefs.export_method_settings.move(idx, idx - 1)
proj_prefs.active_export_method_index -= 1
case 'ADD':
item = proj_prefs.export_method_settings.add()
item.name = 'New setting'
item.value = ''
proj_prefs.active_export_method_index = len(proj_prefs.export_method_settings) - 1
case 'REMOVE':
if len(proj_prefs.export_method_settings):
proj_prefs.export_method_settings.remove(idx)
proj_prefs.active_export_method_index -= 1
return {"FINISHED"}
class WBS_AP_Preferences(bpy.types.AddonPreferences):
"""
Stores global preferences for the addon.
"""
bl_idname = 'io_scene_wmo'
projects: bpy.props.CollectionProperty(
type=WBS_PG_ProjectPreferences,
name='Projects',
description='Project presets.',
options=set()
)
active_project_index: bpy.props.IntProperty(default=0)
def draw(self, context: bpy.types.Context):
layout = self.layout
row = layout.row()
row.template_list('WBS_UL_Projects', '', self, 'projects', self, 'active_project_index', rows=2)
col = row.column(align=True)
col.operator("wbs.project_list_action", text="Create project").action = 'ADD'
col.operator("wbs.project_list_action", text="Duplicate project").action = 'DUPLICATE'
col.operator("wbs.project_list_action", text="Remove project").action = 'REMOVE'
col.separator()
col.operator("wbs.project_list_action", icon='TRIA_UP', text="").action = 'UP'
col.operator("wbs.project_list_action", icon='TRIA_DOWN', text="").action = 'DOWN'
col.separator()
if proj_prefs := get_project_preferences():
col = layout.column(align=True)
col.label(text='Project settings:', icon='SETTINGS')
box = col.box()
box.prop(proj_prefs, 'wow_path')
box.prop(proj_prefs, 'time_import_method')
box.prop(proj_prefs, 'import_method')
if proj_prefs.import_method == 'WMV':
box.prop(proj_prefs, 'wmv_path')
elif proj_prefs.import_method == 'WowExport':
box.prop(proj_prefs, 'wow_export_path')
elif proj_prefs.import_method == 'NoggitRed':
box.prop(proj_prefs, 'noggit_red_path')
box.prop(proj_prefs, 'cache_dir_path')
box.prop(proj_prefs, 'project_dir_path')
box.prop(proj_prefs, 'export_method_enum', text='Export Directory Path')
box.prop(proj_prefs, "verbosity_level")
box.prop(proj_prefs, "scene_type")
col = layout.column(align=True)
col.label(text='Export Folder Settings:', icon='SETTINGS')
row = col.row()
row.template_list('WBS_UL_Export', '', proj_prefs, 'export_method_settings', proj_prefs, 'active_export_method_index')
sub_col = row.column(align=True)
sub_col.operator("wbs.export_method_action", text="", icon='ADD').action = 'ADD'
sub_col.operator("wbs.export_method_action", text="", icon='REMOVE').action = 'REMOVE'
sub_col.operator("wbs.export_method_action", icon='TRIA_UP', text="").action = 'UP'
sub_col.operator("wbs.export_method_action", icon='TRIA_DOWN', text="").action = 'DOWN'
if proj_prefs.export_method_settings:
setting = proj_prefs.export_method_settings[proj_prefs.active_export_method_index]
box = col.box()
box.prop(setting, 'name')
box.prop(setting, 'value')
col.separator()
col = layout.column(align=True)
col.label(text='M2 Quick Save Settings:', icon='SETTINGS')
box = col.box()
box.prop(proj_prefs, 'merge_vertices', text='Merge Vertices')