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
This commit is contained in:
Gorgious
2022-07-19 22:17:39 +02:00
parent 650e5b0cd3
commit dd041478b3
4 changed files with 20 additions and 6 deletions
+15 -1
View File
@@ -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
@@ -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"
@@ -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)
+2 -3
View File
@@ -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)