mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Add search bar with simple filter function to the type manager
This commit is contained in:
@@ -57,20 +57,22 @@ class AuthoringData:
|
||||
cls.data["ifc_element_type"] = cls.ifc_element_type
|
||||
cls.data["ifc_classes"] = cls.ifc_classes()
|
||||
cls.data["ifc_class_current"] = cls.ifc_class_current()
|
||||
cls.data["relating_type_id"] = cls.relating_type_id() # only after .ifc_classes()
|
||||
cls.data["relating_type_id_current"] = cls.relating_type_id_current() # only after .ifc_classes()
|
||||
cls.data["relating_type_name"] = cls.relating_type_name() # only after .relating_type_id()
|
||||
cls.data["relating_type_description"] = cls.relating_type_description() # only after .relating_type_id()
|
||||
cls.data["predefined_type"] = cls.predefined_type() # only after .relating_type_id()
|
||||
|
||||
# Only after .ifc_classes()
|
||||
# Make sure .ifc_classes() was run before next lines
|
||||
cls.data["filtered_type_elements"] = cls.filtered_type_elements()
|
||||
# Make sure .filtered_type_elements() was run before next lines
|
||||
cls.data["relating_type_id"] = cls.relating_type_id()
|
||||
# Make sure .relating_type_id() was run before next lines
|
||||
cls.data["relating_type_id_current"] = cls.relating_type_id_current()
|
||||
cls.data["relating_type_name"] = cls.relating_type_name()
|
||||
cls.data["relating_type_description"] = cls.relating_type_description()
|
||||
cls.data["predefined_type"] = cls.predefined_type()
|
||||
cls.data["total_types"] = cls.total_types()
|
||||
cls.data["total_pages"] = cls.total_pages()
|
||||
cls.data["total_pages"] = cls.total_pages() # Only after .total_types()
|
||||
cls.data["next_page"] = cls.next_page()
|
||||
cls.data["prev_page"] = cls.prev_page()
|
||||
cls.data["paginated_relating_types"] = cls.paginated_relating_types()
|
||||
|
||||
cls.data["type_thumbnail"] = cls.type_thumbnail() # Only after .relating_type_id()
|
||||
cls.data["type_thumbnail"] = cls.type_thumbnail()
|
||||
cls.data["is_voidable_element"] = cls.is_voidable_element()
|
||||
cls.data["has_visible_openings"] = cls.has_visible_openings()
|
||||
cls.data["has_visible_boundaries"] = cls.has_visible_boundaries()
|
||||
@@ -114,13 +116,11 @@ class AuthoringData:
|
||||
|
||||
@classmethod
|
||||
def total_types(cls):
|
||||
ifc_class = cls.data["ifc_class_current"]
|
||||
return len(tool.Ifc.get().by_type(ifc_class)) if ifc_class else 0
|
||||
return len(cls.data["filtered_type_elements"])
|
||||
|
||||
@classmethod
|
||||
def total_pages(cls):
|
||||
ifc_class = cls.data["ifc_class_current"]
|
||||
total_types = len(tool.Ifc.get().by_type(ifc_class)) if ifc_class else 0
|
||||
total_types = cls.data["total_types"]
|
||||
return math.ceil(total_types / cls.types_per_page)
|
||||
|
||||
@classmethod
|
||||
@@ -134,12 +134,19 @@ class AuthoringData:
|
||||
return cls.props.type_page - 1
|
||||
|
||||
@classmethod
|
||||
def paginated_relating_types(cls):
|
||||
def filtered_type_elements(cls):
|
||||
ifc_class = cls.data["ifc_class_current"]
|
||||
if not ifc_class:
|
||||
return []
|
||||
elements = list(tool.Ifc.get().by_type(ifc_class))
|
||||
if cls.props.search_name:
|
||||
elements = [e for e in elements if cls.props.search_name.lower() in (e.Name or "Unnamed").lower()]
|
||||
return natsorted(elements, key=lambda s: (s.Name or "Unnamed").lower())
|
||||
|
||||
@classmethod
|
||||
def paginated_relating_types(cls):
|
||||
results = []
|
||||
elements = natsorted(tool.Ifc.get().by_type(ifc_class), key=lambda e: e.Name or "Unnamed")
|
||||
elements = cls.data["filtered_type_elements"]
|
||||
elements = elements[(cls.props.type_page - 1) * cls.types_per_page : cls.props.type_page * cls.types_per_page]
|
||||
for element in elements:
|
||||
predefined_type = ifcopenshell.util.element.get_predefined_type(element)
|
||||
@@ -266,13 +273,8 @@ class AuthoringData:
|
||||
|
||||
@classmethod
|
||||
def relating_type_id(cls):
|
||||
results = []
|
||||
ifc_class = cls.data["ifc_class_current"]
|
||||
if ifc_class:
|
||||
elements = natsorted(tool.Ifc.get().by_type(ifc_class), key=lambda s: (s.Name or "Unnamed").lower())
|
||||
results.extend(elements)
|
||||
return [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in results]
|
||||
return []
|
||||
elements = cls.data["filtered_type_elements"]
|
||||
return [(str(e.id()), e.Name or "Unnamed", e.Description or "") for e in elements]
|
||||
|
||||
@classmethod
|
||||
def relating_type_id_current(cls):
|
||||
|
||||
@@ -566,7 +566,9 @@ class LoadTypeThumbnails(bpy.types.Operator, tool.Ifc.Operator):
|
||||
processing = set()
|
||||
# Only process at most one paginated class at a time.
|
||||
# Large projects have hundreds of types which can lead to unnecessary lag.
|
||||
queue = sorted(tool.Ifc.get().by_type(self.ifc_class), key=lambda e: e.Name or "Unnamed")
|
||||
if not AuthoringData.is_loaded:
|
||||
AuthoringData.load()
|
||||
queue = AuthoringData.data["filtered_type_elements"]
|
||||
if self.limit:
|
||||
queue = queue[self.offset : self.offset + self.limit]
|
||||
else:
|
||||
|
||||
@@ -97,11 +97,26 @@ def update_slab_direction_decorator(self, context):
|
||||
SlabDirectionDecorator.uninstall()
|
||||
|
||||
|
||||
def update_search_name(self, context):
|
||||
AuthoringData.load()
|
||||
# Total number of pages may decrease when using the search bar :
|
||||
if self.type_page > AuthoringData.data["total_pages"]:
|
||||
self.type_page = AuthoringData.data["total_pages"]
|
||||
bpy.ops.bim.load_type_thumbnails(ifc_class=self.ifc_class)
|
||||
|
||||
|
||||
class BIMModelProperties(PropertyGroup):
|
||||
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
||||
relating_type_id: bpy.props.EnumProperty(
|
||||
items=get_relating_type_id, name="Relating Type", update=update_relating_type_id
|
||||
)
|
||||
search_name: bpy.props.StringProperty(
|
||||
name="Search Name",
|
||||
default="",
|
||||
description="Use this property to filter the list of available types",
|
||||
update=update_search_name,
|
||||
options={"SKIP_SAVE", "TEXTEDIT_UPDATE"},
|
||||
)
|
||||
menu_relating_type_id: bpy.props.IntProperty()
|
||||
icon_id: bpy.props.IntProperty()
|
||||
updating: bpy.props.BoolProperty(default=False)
|
||||
|
||||
@@ -108,12 +108,10 @@ class LaunchTypeManager(bpy.types.Operator):
|
||||
def draw(self, context):
|
||||
props = context.scene.BIMModelProperties
|
||||
row = self.layout.row(align=True)
|
||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}"
|
||||
if AuthoringData.data["total_types"] > 1:
|
||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}s"
|
||||
else:
|
||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type']}"
|
||||
text += "s"
|
||||
row.label(text=text, icon="FILE_VOLUME")
|
||||
# prop_with_search(row, props, "ifc_class", text="", should_click_ok_to_validate=True)
|
||||
row.menu("BIM_MT_type_manager_menu", text="", icon="PREFERENCES")
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.launch_add_element", text=f"Create New {AuthoringData.data['ifc_element_type']}", icon="ADD")
|
||||
@@ -121,9 +119,6 @@ class LaunchTypeManager(bpy.types.Operator):
|
||||
columns = self.layout.column_flow(columns=3)
|
||||
row = columns.row(align=True)
|
||||
row.alignment = "CENTER"
|
||||
### In case you want something here in the future
|
||||
|
||||
###
|
||||
|
||||
row = columns.row(align=True)
|
||||
row.alignment = "RIGHT"
|
||||
@@ -136,6 +131,8 @@ class LaunchTypeManager(bpy.types.Operator):
|
||||
op = row.operator("bim.change_type_page", icon="TRIA_RIGHT", text="")
|
||||
op.page = AuthoringData.data["next_page"]
|
||||
|
||||
self.layout.prop(props, "search_name", icon="VIEWZOOM", text="")
|
||||
|
||||
flow = self.layout.grid_flow(row_major=True, columns=3, even_columns=True, even_rows=True, align=True)
|
||||
|
||||
for relating_type in AuthoringData.data["paginated_relating_types"]:
|
||||
|
||||
Reference in New Issue
Block a user