2023-11-16 22:41:03 +08:00
|
|
|
import bpy
|
2025-01-08 13:21:35 +08:00
|
|
|
from bpy.types import Context, Event
|
|
|
|
from . import UTIL_functions
|
2023-11-16 22:41:03 +08:00
|
|
|
|
|
|
|
## Intent
|
|
|
|
# Operator is not allowed to register Pointer Properties.
|
|
|
|
# The solution is register pointer properties in Scene and reference it when drawing operator window.
|
|
|
|
# This module contains all pointer properties used by other operators.
|
|
|
|
|
2025-01-08 13:21:35 +08:00
|
|
|
#region Blender Type Defines
|
|
|
|
|
|
|
|
class BBP_PG_bmap_encoding(bpy.types.PropertyGroup):
|
|
|
|
encoding: bpy.props.StringProperty(
|
|
|
|
name = "Encoding",
|
|
|
|
default = ""
|
|
|
|
) # type: ignore
|
|
|
|
|
|
|
|
class BBP_UL_bmap_encoding(bpy.types.UIList):
|
|
|
|
def draw_item(self, context, layout: bpy.types.UILayout, data, item: BBP_PG_bmap_encoding, icon, active_data, active_propname):
|
|
|
|
layout.prop(item, 'encoding', emboss = False, text = '', icon = 'FONT_DATA')
|
|
|
|
|
2023-11-16 22:41:03 +08:00
|
|
|
class BBP_PG_ptrprop_resolver(bpy.types.PropertyGroup):
|
|
|
|
rail_uv_material: bpy.props.PointerProperty(
|
|
|
|
name = "Material",
|
|
|
|
description = "The material used for rail",
|
|
|
|
type = bpy.types.Material,
|
2024-12-30 17:53:42 +08:00
|
|
|
) # type: ignore
|
2023-11-16 22:41:03 +08:00
|
|
|
|
|
|
|
export_collection: bpy.props.PointerProperty(
|
|
|
|
type = bpy.types.Collection,
|
|
|
|
name = "Collection",
|
|
|
|
description = "The collection exported. Nested collections allowed."
|
2024-12-30 17:53:42 +08:00
|
|
|
) # type: ignore
|
2023-11-16 22:41:03 +08:00
|
|
|
|
|
|
|
export_object: bpy.props.PointerProperty(
|
|
|
|
type = bpy.types.Object,
|
|
|
|
name = "Object",
|
|
|
|
description = "The object exported"
|
2024-12-30 17:53:42 +08:00
|
|
|
) # type: ignore
|
2023-11-16 22:41:03 +08:00
|
|
|
|
2025-01-08 13:21:35 +08:00
|
|
|
ioport_encodings: bpy.props.CollectionProperty(
|
|
|
|
type = BBP_PG_bmap_encoding
|
|
|
|
) # type: ignore
|
|
|
|
active_ioport_encodings: bpy.props.IntProperty() # type: ignore
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2023-11-16 22:41:03 +08:00
|
|
|
def get_ptrprop_resolver() -> BBP_PG_ptrprop_resolver:
|
|
|
|
return bpy.context.scene.bbp_ptrprop_resolver
|
|
|
|
|
2025-01-08 13:21:35 +08:00
|
|
|
def get_ioport_encodings() -> UTIL_functions.CollectionVisitor[BBP_PG_bmap_encoding]:
|
|
|
|
return UTIL_functions.CollectionVisitor(get_ptrprop_resolver().ioport_encodings)
|
|
|
|
def get_active_ioport_encoding() -> int:
|
|
|
|
return get_ptrprop_resolver().active_ioport_encodings
|
|
|
|
def set_active_ioport_encoding(val: int) -> None:
|
|
|
|
get_ptrprop_resolver().active_ioport_encodings = val
|
|
|
|
|
|
|
|
#region Blender Operator Defines for Encodings
|
|
|
|
|
|
|
|
class BBP_OT_add_ioport_encodings(bpy.types.Operator):
|
|
|
|
"""Add item at the tail of encodings list used by BMap for Virtools file read and write."""
|
|
|
|
bl_idname = "bbp.add_ioport_encodings"
|
|
|
|
bl_label = "Add in Encodings List"
|
|
|
|
bl_options = {'UNDO'}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context: bpy.types.Context) -> bool:
|
|
|
|
return True
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
encodings.add()
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
|
|
class BBP_OT_rm_ioport_encodings(bpy.types.Operator):
|
|
|
|
"""Remove selected item in encodings list used by BMap for Virtools file read and write."""
|
|
|
|
bl_idname = "bbp.rm_ioport_encodings"
|
|
|
|
bl_label = "Remove from Encodings List"
|
|
|
|
bl_options = {'UNDO'}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context: bpy.types.Context) -> bool:
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
index = get_active_ioport_encoding()
|
|
|
|
return index >= 0 and index < len(encodings)
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
encodings.remove(get_active_ioport_encoding())
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
|
|
class BBP_OT_up_ioport_encodings(bpy.types.Operator):
|
|
|
|
"""Move selected item up in encodings list used by BMap for Virtools file read and write."""
|
|
|
|
bl_idname = "bbp.up_ioport_encodings"
|
|
|
|
bl_label = "Move Up in Encodings List"
|
|
|
|
bl_options = {'UNDO'}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context: bpy.types.Context) -> bool:
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
index = get_active_ioport_encoding()
|
|
|
|
return index >= 1 and index < len(encodings)
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
index = get_active_ioport_encoding()
|
|
|
|
encodings.move(index, index - 1)
|
|
|
|
set_active_ioport_encoding(index - 1)
|
|
|
|
return {'FINISHED'}
|
2023-11-16 22:41:03 +08:00
|
|
|
|
2025-01-08 13:21:35 +08:00
|
|
|
class BBP_OT_down_ioport_encodings(bpy.types.Operator):
|
|
|
|
"""Move selected item down in encodings list used by BMap for Virtools file read and write."""
|
|
|
|
bl_idname = "bbp.down_ioport_encodings"
|
|
|
|
bl_label = "Move Down in Encodings List"
|
|
|
|
bl_options = {'UNDO'}
|
2023-11-16 22:41:03 +08:00
|
|
|
|
2025-01-08 13:21:35 +08:00
|
|
|
@classmethod
|
|
|
|
def poll(cls, context: bpy.types.Context) -> bool:
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
index = get_active_ioport_encoding()
|
|
|
|
return index >= 0 and index < len(encodings) - 1
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
index = get_active_ioport_encoding()
|
|
|
|
encodings.move(index, index + 1)
|
|
|
|
set_active_ioport_encoding(index + 1)
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
|
|
class BBP_OT_clear_ioport_encodings(bpy.types.Operator):
|
|
|
|
"""Clear the encodings list used by BMap for Virtools file read and write."""
|
|
|
|
bl_idname = "bbp.clear_ioport_encodings"
|
|
|
|
bl_label = "Clear Encodings List"
|
|
|
|
bl_options = {'UNDO'}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def poll(cls, context: bpy.types.Context) -> bool:
|
|
|
|
return True
|
|
|
|
|
|
|
|
def invoke(self, context, event):
|
|
|
|
wm = context.window_manager
|
|
|
|
return wm.invoke_confirm(self, event)
|
|
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
encodings.clear()
|
|
|
|
set_active_ioport_encoding(0)
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
class PtrPropResolver():
|
|
|
|
"""
|
|
|
|
All outside code should use this class static methods to fetch property data or draw property.
|
|
|
|
All function inside in this module should not be called directly.
|
|
|
|
"""
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_rail_uv_material() -> bpy.types.Material:
|
|
|
|
return get_ptrprop_resolver().rail_uv_material
|
|
|
|
@staticmethod
|
|
|
|
def draw_rail_uv_material(layout: bpy.types.UILayout) -> None:
|
|
|
|
layout.prop(get_ptrprop_resolver(), 'rail_uv_material')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_export_collection() -> bpy.types.Collection:
|
|
|
|
return get_ptrprop_resolver().export_collection
|
|
|
|
@staticmethod
|
|
|
|
def draw_export_collection(layout: bpy.types.UILayout) -> None:
|
|
|
|
layout.prop(get_ptrprop_resolver(), 'export_collection')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_export_object() -> bpy.types.Object:
|
|
|
|
return get_ptrprop_resolver().export_object
|
|
|
|
@staticmethod
|
|
|
|
def draw_export_object(layout: bpy.types.UILayout) -> None:
|
|
|
|
layout.prop(get_ptrprop_resolver(), 'export_object')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_ioport_encodings() -> tuple[str, ...]:
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
return tuple(i.encoding for i in encodings)
|
|
|
|
@staticmethod
|
|
|
|
def set_ioport_encodings(user_encodings: tuple[str, ...]) -> None:
|
|
|
|
encodings = get_ioport_encodings()
|
|
|
|
# clear and apply user encoding one by one
|
|
|
|
encodings.clear()
|
|
|
|
for user_encoding in user_encodings:
|
|
|
|
item = encodings.add()
|
|
|
|
item.encoding = user_encoding
|
|
|
|
@staticmethod
|
|
|
|
def draw_ioport_encodings(layout: bpy.types.UILayout) -> None:
|
|
|
|
target = get_ptrprop_resolver()
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
# draw main list
|
|
|
|
row.template_list(
|
|
|
|
"BBP_UL_bmap_encoding", "",
|
|
|
|
target, "ioport_encodings",
|
|
|
|
target, "active_ioport_encodings",
|
|
|
|
rows = 6, maxrows = 6,
|
|
|
|
sort_reverse = False, sort_lock = True # disable sort feature because the order od this encoding list is crucial
|
|
|
|
)
|
|
|
|
|
|
|
|
# draw sidebar
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.operator(BBP_OT_add_ioport_encodings.bl_idname, icon='ADD', text='')
|
|
|
|
col.operator(BBP_OT_rm_ioport_encodings.bl_idname, icon='REMOVE', text='')
|
|
|
|
col.separator()
|
|
|
|
col.operator(BBP_OT_up_ioport_encodings.bl_idname, icon='TRIA_UP', text='')
|
|
|
|
col.operator(BBP_OT_down_ioport_encodings.bl_idname, icon='TRIA_DOWN', text='')
|
|
|
|
col.separator()
|
|
|
|
col.operator(BBP_OT_clear_ioport_encodings.bl_idname, icon='TRASH', text='')
|
2023-11-16 22:41:03 +08:00
|
|
|
|
2024-02-12 11:42:09 +08:00
|
|
|
def register() -> None:
|
2025-01-08 13:21:35 +08:00
|
|
|
bpy.utils.register_class(BBP_PG_bmap_encoding)
|
|
|
|
bpy.utils.register_class(BBP_UL_bmap_encoding)
|
2023-11-16 22:41:03 +08:00
|
|
|
bpy.utils.register_class(BBP_PG_ptrprop_resolver)
|
2025-01-08 13:21:35 +08:00
|
|
|
|
|
|
|
bpy.utils.register_class(BBP_OT_add_ioport_encodings)
|
|
|
|
bpy.utils.register_class(BBP_OT_rm_ioport_encodings)
|
|
|
|
bpy.utils.register_class(BBP_OT_up_ioport_encodings)
|
|
|
|
bpy.utils.register_class(BBP_OT_down_ioport_encodings)
|
|
|
|
bpy.utils.register_class(BBP_OT_clear_ioport_encodings)
|
|
|
|
|
2023-11-16 22:41:03 +08:00
|
|
|
bpy.types.Scene.bbp_ptrprop_resolver = bpy.props.PointerProperty(type = BBP_PG_ptrprop_resolver)
|
|
|
|
|
2024-02-12 11:42:09 +08:00
|
|
|
def unregister() -> None:
|
2023-11-16 22:41:03 +08:00
|
|
|
del bpy.types.Scene.bbp_ptrprop_resolver
|
2025-01-08 13:21:35 +08:00
|
|
|
|
|
|
|
bpy.utils.unregister_class(BBP_OT_clear_ioport_encodings)
|
|
|
|
bpy.utils.unregister_class(BBP_OT_down_ioport_encodings)
|
|
|
|
bpy.utils.unregister_class(BBP_OT_up_ioport_encodings)
|
|
|
|
bpy.utils.unregister_class(BBP_OT_rm_ioport_encodings)
|
|
|
|
bpy.utils.unregister_class(BBP_OT_add_ioport_encodings)
|
|
|
|
|
2023-11-16 22:41:03 +08:00
|
|
|
bpy.utils.unregister_class(BBP_PG_ptrprop_resolver)
|
2025-01-08 13:21:35 +08:00
|
|
|
bpy.utils.unregister_class(BBP_UL_bmap_encoding)
|
|
|
|
bpy.utils.unregister_class(BBP_PG_bmap_encoding)
|