161 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			161 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import bpy
							 | 
						||
| 
								 | 
							
								from bpy.props import *
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__all__ = ['LnxTraitPropWarning', 'LnxTraitPropListItem', 'LNX_UL_PropList']
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PROP_TYPE_ICONS = {
							 | 
						||
| 
								 | 
							
								    "String": "SORTALPHA",
							 | 
						||
| 
								 | 
							
								    "Int": "CHECKBOX_DEHLT",
							 | 
						||
| 
								 | 
							
								    "Float": "RADIOBUT_OFF",
							 | 
						||
| 
								 | 
							
								    "Bool": "CHECKMARK",
							 | 
						||
| 
								 | 
							
								    "Vec2": "ORIENTATION_VIEW",
							 | 
						||
| 
								 | 
							
								    "Vec3": "ORIENTATION_GLOBAL",
							 | 
						||
| 
								 | 
							
								    "Vec4": "MESH_ICOSPHERE",
							 | 
						||
| 
								 | 
							
								    "Object": "OBJECT_DATA",
							 | 
						||
| 
								 | 
							
								    "CameraObject": "CAMERA_DATA",
							 | 
						||
| 
								 | 
							
								    "LightObject": "LIGHT_DATA",
							 | 
						||
| 
								 | 
							
								    "MeshObject": "MESH_DATA",
							 | 
						||
| 
								 | 
							
								    "SpeakerObject": "OUTLINER_DATA_SPEAKER"
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def filter_objects(item, b_object):
							 | 
						||
| 
								 | 
							
								    if item.type == "CameraObject":
							 | 
						||
| 
								 | 
							
								        return b_object.type == "CAMERA"
							 | 
						||
| 
								 | 
							
								    if item.type == "LightObject":
							 | 
						||
| 
								 | 
							
								        return b_object.type == "LIGHT"
							 | 
						||
| 
								 | 
							
								    if item.type == "MeshObject":
							 | 
						||
| 
								 | 
							
								        return b_object.type == "MESH"
							 | 
						||
| 
								 | 
							
								    if item.type == "SpeakerObject":
							 | 
						||
| 
								 | 
							
								        return b_object.type == "SPEAKER"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if item.type == "Object":
							 | 
						||
| 
								 | 
							
								        return True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxTraitPropWarning(bpy.types.PropertyGroup):
							 | 
						||
| 
								 | 
							
								    propName: StringProperty(name="Property Name")
							 | 
						||
| 
								 | 
							
								    warning: StringProperty(name="Warning")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxTraitPropListItem(bpy.types.PropertyGroup):
							 | 
						||
| 
								 | 
							
								    """Group of properties representing an item in the list."""
							 | 
						||
| 
								 | 
							
								    name: StringProperty(
							 | 
						||
| 
								 | 
							
								        name="Name",
							 | 
						||
| 
								 | 
							
								        description="The name of this property",
							 | 
						||
| 
								 | 
							
								        default="Untitled")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    type: EnumProperty(
							 | 
						||
| 
								 | 
							
								        items=(
							 | 
						||
| 
								 | 
							
								            # (Haxe Type, Display Name, Description)
							 | 
						||
| 
								 | 
							
								            ("String", "String", "String Type"),
							 | 
						||
| 
								 | 
							
								            ("Int", "Integer", "Integer Type"),
							 | 
						||
| 
								 | 
							
								            ("Float", "Float", "Float Type"),
							 | 
						||
| 
								 | 
							
								            ("Bool", "Boolean", "Boolean Type"),
							 | 
						||
| 
								 | 
							
								            ("Vec2", "Vec2", "2D Vector Type"),
							 | 
						||
| 
								 | 
							
								            ("Vec3", "Vec3", "3D Vector Type"),
							 | 
						||
| 
								 | 
							
								            ("Vec4", "Vec4", "4D Vector Type"),
							 | 
						||
| 
								 | 
							
								            ("Object", "Object", "Object Type"),
							 | 
						||
| 
								 | 
							
								            ("CameraObject", "Camera Object", "Camera Object Type"),
							 | 
						||
| 
								 | 
							
								            ("LightObject", "Light Object", "Light Object Type"),
							 | 
						||
| 
								 | 
							
								            ("MeshObject", "Mesh Object", "Mesh Object Type"),
							 | 
						||
| 
								 | 
							
								            ("SpeakerObject", "Speaker Object", "Speaker Object Type")),
							 | 
						||
| 
								 | 
							
								        name="Type",
							 | 
						||
| 
								 | 
							
								        description="The type of this property",
							 | 
						||
| 
								 | 
							
								        default="String",
							 | 
						||
| 
								 | 
							
								        override={"LIBRARY_OVERRIDABLE"}
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # === VALUES ===
							 | 
						||
| 
								 | 
							
								    value_string: StringProperty(name="Value", default="", override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_int: IntProperty(name="Value", default=0, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_float: FloatProperty(name="Value", default=0.0, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_bool: BoolProperty(name="Value", default=False, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_vec2: FloatVectorProperty(name="Value", size=2, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_vec3: FloatVectorProperty(name="Value", size=3, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_vec4: FloatVectorProperty(name="Value", size=4, override={"LIBRARY_OVERRIDABLE"})
							 | 
						||
| 
								 | 
							
								    value_object: PointerProperty(
							 | 
						||
| 
								 | 
							
								        name="Value", type=bpy.types.Object, poll=filter_objects,
							 | 
						||
| 
								 | 
							
								        override={"LIBRARY_OVERRIDABLE"}
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def set_value(self, val):
							 | 
						||
| 
								 | 
							
								        # Would require way too much effort, so it's out of scope here.
							 | 
						||
| 
								 | 
							
								        if self.type.endswith("Object"):
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.type == "Int":
							 | 
						||
| 
								 | 
							
								            self.value_int = int(val)
							 | 
						||
| 
								 | 
							
								        elif self.type == "Float":
							 | 
						||
| 
								 | 
							
								            self.value_float = float(val)
							 | 
						||
| 
								 | 
							
								        elif self.type == "Bool":
							 | 
						||
| 
								 | 
							
								            self.value_bool = val == "true"
							 | 
						||
| 
								 | 
							
								        elif self.type in ("Vec2", "Vec3", "Vec4"):
							 | 
						||
| 
								 | 
							
								            if isinstance(val, str):
							 | 
						||
| 
								 | 
							
								                dimensions = int(self.type[-1])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                # Parse "new VecX(...)"
							 | 
						||
| 
								 | 
							
								                val = val.split("(")[1].split(")")[0].split(",")
							 | 
						||
| 
								 | 
							
								                val = [value.strip() for value in val]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                # new VecX() without parameters
							 | 
						||
| 
								 | 
							
								                if len(val) == 1 and val[0] == "":
							 | 
						||
| 
								 | 
							
								                    # Use default value
							 | 
						||
| 
								 | 
							
								                    return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                # new VecX() with less parameters than its dimensions
							 | 
						||
| 
								 | 
							
								                while len(val) < dimensions:
							 | 
						||
| 
								 | 
							
								                    val.append(0.0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                val = [float(value) for value in val]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            setattr(self, "value_" + self.type.lower(), val)
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            self.value_string = str(val)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def get_value(self):
							 | 
						||
| 
								 | 
							
								        if self.type == "Int":
							 | 
						||
| 
								 | 
							
								            return self.value_int
							 | 
						||
| 
								 | 
							
								        if self.type == "Float":
							 | 
						||
| 
								 | 
							
								            return self.value_float
							 | 
						||
| 
								 | 
							
								        if self.type == "Bool":
							 | 
						||
| 
								 | 
							
								            return self.value_bool
							 | 
						||
| 
								 | 
							
								        if self.type in ("Vec2", "Vec3", "Vec4"):
							 | 
						||
| 
								 | 
							
								            return list(getattr(self, "value_" + self.type.lower()))
							 | 
						||
| 
								 | 
							
								        if self.type.endswith("Object"):
							 | 
						||
| 
								 | 
							
								            if self.value_object is not None:
							 | 
						||
| 
								 | 
							
								                return self.value_object.name
							 | 
						||
| 
								 | 
							
								            return ""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return self.value_string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LNX_UL_PropList(bpy.types.UIList):
							 | 
						||
| 
								 | 
							
								    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
							 | 
						||
| 
								 | 
							
								        item_value_ref = "value_" + item.type.lower()
							 | 
						||
| 
								 | 
							
								        custom_icon = PROP_TYPE_ICONS[item.type]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        sp = layout.split(factor=0.3)
							 | 
						||
| 
								 | 
							
								        sp.label(text=item.type, icon=custom_icon)
							 | 
						||
| 
								 | 
							
								        sp = sp.split(factor=0.6)
							 | 
						||
| 
								 | 
							
								        sp.label(text=item.name)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Make sure your code supports all 3 layout types
							 | 
						||
| 
								 | 
							
								        if self.layout_type in {'DEFAULT', 'COMPACT'}:
							 | 
						||
| 
								 | 
							
								            if item.type.endswith("Object"):
							 | 
						||
| 
								 | 
							
								                sp.prop_search(item, "value_object", context.scene, "objects", text="", icon=custom_icon)
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                use_emboss = item.type in ("Bool", "String")
							 | 
						||
| 
								 | 
							
								                sp.prop(item, item_value_ref, text="", emboss=use_emboss)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        elif self.layout_type in {'GRID'}:
							 | 
						||
| 
								 | 
							
								            layout.alignment = 'CENTER'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__REG_CLASSES = (
							 | 
						||
| 
								 | 
							
								    LnxTraitPropWarning,
							 | 
						||
| 
								 | 
							
								    LnxTraitPropListItem,
							 | 
						||
| 
								 | 
							
								    LNX_UL_PropList,
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								register, unregister = bpy.utils.register_classes_factory(__REG_CLASSES)
							 |