armory/blender/arm/props_traits_props.py
2021-08-04 22:56:11 +02:00

161 lines
5.5 KiB
Python

import bpy
from bpy.props import *
__all__ = ['ArmTraitPropWarning', 'ArmTraitPropListItem', 'ARM_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 ArmTraitPropWarning(bpy.types.PropertyGroup):
propName: StringProperty(name="Property Name")
warning: StringProperty(name="Warning")
class ArmTraitPropListItem(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")
# === VALUES ===
value_string: StringProperty(name="Value", default="")
value_int: IntProperty(name="Value", default=0)
value_float: FloatProperty(name="Value", default=0.0)
value_bool: BoolProperty(name="Value", default=False)
value_vec2: FloatVectorProperty(name="Value", size=2)
value_vec3: FloatVectorProperty(name="Value", size=3)
value_vec4: FloatVectorProperty(name="Value", size=4)
value_object: PointerProperty(
name="Value", type=bpy.types.Object, poll=filter_objects)
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 ARM_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'
def register():
bpy.utils.register_class(ArmTraitPropWarning)
bpy.utils.register_class(ArmTraitPropListItem)
bpy.utils.register_class(ARM_UL_PropList)
def unregister():
bpy.utils.unregister_class(ARM_UL_PropList)
bpy.utils.unregister_class(ArmTraitPropListItem)
bpy.utils.unregister_class(ArmTraitPropWarning)