From dd041478b3eeb1ba0617537f4289de7bc006ee73 Mon Sep 17 00:00:00 2001 From: Gorgious Date: Tue, 19 Jul 2022 22:17:39 +0200 Subject: [PATCH] Add utility method to retrieve dynamic enum items without needing a reference to the callback This is useful because trying to directly access a dynamic enum with an empty items list throws an error in the console + Remove prop search from template_type in pset ui which has only 2 elements --- src/blenderbim/blenderbim/bim/helper.py | 16 +++++++++++++++- src/blenderbim/blenderbim/bim/module/pset/ui.py | 2 +- .../blenderbim/bim/module/root/operator.py | 3 ++- src/blenderbim/blenderbim/bim/operator.py | 5 ++--- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 6b11944f87..db2c706c2e 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -108,7 +108,7 @@ def export_attributes(props, callback=None): return attributes -def prop_with_search(layout, data, prop_name, **kwargs): +def prop_with_search(layout, data, prop_name, **kwargs): # kwargs are layout.prop arguments (text, icon, etc.) row = layout.row(align=True) # Magick courtesy of https://blender.stackexchange.com/a/203443/86891 @@ -118,6 +118,20 @@ def prop_with_search(layout, data, prop_name, **kwargs): op.prop_name = prop_name +def get_enum_items(data, prop_name, context): + # Retrieve items from a dynamic EnumProperty, which is otherwise not supported + # Or throws an error in the console when the items callback returns an empty list + # See https://blender.stackexchange.com/q/215781/86891 + prop = data.__annotations__[prop_name] + items = prop.keywords.get("items") + if items is None: + return + if not isinstance(items, (list, tuple)): + # items are retrieved through a callback, not a static list : + items = items(data, context) + return items + + class IfcHeaderExtractor: def __init__(self, filepath: str): self.filepath = filepath diff --git a/src/blenderbim/blenderbim/bim/module/pset/ui.py b/src/blenderbim/blenderbim/bim/module/pset/ui.py index a0b1984fb4..2efe7e1167 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/ui.py +++ b/src/blenderbim/blenderbim/bim/module/pset/ui.py @@ -490,7 +490,7 @@ class BIM_PT_add_edit_custom_properties(Panel): if prop.template_type == "IfcPropertySingleValue": row.prop(prop, prop.get_value_name(), text="") prop_with_search(row, prop, "primary_measure_type", text="") - prop_with_search(row, prop, "template_type", text="") + row.prop(prop, "template_type", text="") op = row.operator("bim.remove_property_to_edit", icon="X", text="") op.index = index op.option = "AddEditProperties" diff --git a/src/blenderbim/blenderbim/bim/module/root/operator.py b/src/blenderbim/blenderbim/bim/module/root/operator.py index ff37c90c98..c3d5170335 100644 --- a/src/blenderbim/blenderbim/bim/module/root/operator.py +++ b/src/blenderbim/blenderbim/bim/module/root/operator.py @@ -31,6 +31,7 @@ import blenderbim.core.root as core import blenderbim.tool as tool from ifcopenshell.api.void.data import Data as VoidData from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import get_enum_items class Operator: @@ -131,7 +132,7 @@ class AssignClass(bpy.types.Operator, Operator): ifc_class = self.ifc_class or props.ifc_class predefined_type = self.userdefined_type if self.predefined_type == "USERDEFINED" else self.predefined_type ifc_context = self.context_id - if not ifc_context and props.__annotations__["contexts"].keywords.get("items")(props, context): + if not ifc_context and get_enum_items(props, "contexts", context): ifc_context = int(props.contexts or "0") or None if ifc_context: ifc_context = tool.Ifc.get().by_id(ifc_context) diff --git a/src/blenderbim/blenderbim/bim/operator.py b/src/blenderbim/blenderbim/bim/operator.py index 0f1f230287..ad1ab0553a 100644 --- a/src/blenderbim/blenderbim/bim/operator.py +++ b/src/blenderbim/blenderbim/bim/operator.py @@ -27,6 +27,7 @@ from . import schema from blenderbim.bim.ifc import IfcStore from blenderbim.bim.prop import StrProperty from blenderbim.bim.ui import IFCFileSelector +from blenderbim.bim.helper import get_enum_items from mathutils import Vector, Matrix, Euler from math import radians @@ -545,11 +546,9 @@ class BIM_OT_enum_property_search(bpy.types.Operator): def invoke(self, context, event): self.clear_collections() self.data = context.data - items = self.data.__annotations__[self.prop_name].keywords.get("items") + items = get_enum_items(self.data, self.prop_name, context) if items is None: return {"FINISHED"} - if not isinstance(items, list): - items = items(self.data, context) self.add_items_regular(items) self.add_items_suggestions() return context.window_manager.invoke_props_dialog(self)