From 888ab85548d535b339dd9d9bae7b71c9b3375dfe Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Thu, 11 Dec 2025 02:41:52 +0100 Subject: [PATCH] Refactor UI helpers into helper module for better organization --- src/bonsai/bonsai/bim/helper.py | 145 ++++++++++++++++++++++++++ src/bonsai/bonsai/bim/operator.py | 10 +- src/bonsai/bonsai/bim/ui.py | 168 +++--------------------------- 3 files changed, 164 insertions(+), 159 deletions(-) diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py index 873d368fad..6ba13dbb4d 100644 --- a/src/bonsai/bonsai/bim/helper.py +++ b/src/bonsai/bonsai/bim/helper.py @@ -784,3 +784,148 @@ def draw_filter( op.group_index = i op.index = j op.module = module + +# ============================================================================ +# UI Panel Visibility Helpers +# ============================================================================ + +def get_tab_names(): + from bonsai.bim.prop import get_tab + enum_items = get_tab(None, None) + # Exclude None separators and the BLENDER tab (not part of BIM tab system) + return [item[0] for item in enum_items if item is not None and item[0] != "BLENDER"] + + +def get_panel_tab_name(panel_class): + if hasattr(panel_class, 'bim_tab_name'): + return panel_class.bim_tab_name + return "PROJECT" # Default fallback + + +def should_show_panel(panel_id, panel_tab_name, context): + if tool.Blender.is_tab(context, "BOOKMARK"): + return is_panel_bookmarked(panel_id) and get_panel_visibility(panel_id, "BOOKMARK") + + if tool.Blender.is_tab(context, panel_tab_name): + return get_tab_visibility(panel_tab_name) and get_panel_visibility(panel_id, panel_tab_name) + + return False + + +def get_tab_visibility(tab_name): + bim_props = tool.Blender.get_bim_props() + tab_vis = bim_props.tab_visibilities.get(tab_name) + return tab_vis.is_visible if tab_vis else True + + +def set_tab_visibility(tab_name, visible): + bim_props = tool.Blender.get_bim_props() + tab_vis = bim_props.tab_visibilities.get(tab_name) + if tab_vis: + tab_vis.is_visible = visible + else: + new_tab = bim_props.tab_visibilities.add() + new_tab.name = tab_name + new_tab.is_visible = visible + + +def get_panel_visibility(panel_id, current_tab=None): + panel_config = get_panel_config(panel_id) + if panel_config: + if current_tab == "BOOKMARK": + return panel_config.is_visible_in_bookmarks + else: + return panel_config.is_visible_in_tab + return True + + +def is_panel_bookmarked(panel_id): + panel_config = get_panel_config(panel_id) + if panel_config: + return panel_config.is_bookmarked + return False + + +def get_panel_config(panel_id, create_if_missing=False): + try: + bim_props = tool.Blender.get_bim_props() + except (AttributeError, AssertionError): + return None + + for prop in bim_props.panel_properties: + if prop.name == panel_id: + return prop + + if create_if_missing: + try: + prop = bim_props.panel_properties.add() + prop.name = panel_id + prop.is_visible_in_tab = True + prop.is_visible_in_bookmarks = True + prop.is_bookmarked = False + return prop + except AttributeError: + pass + + return None + + + +def get_all_tab_panels(force_refresh=False): + panels = {tab_name: [] for tab_name in get_tab_names() if tab_name != "BOOKMARK"} + panels["BOOKMARK"] = [] + + + bim_props = tool.Blender.get_bim_props() + for prop in bim_props.panel_properties: + panel_class = getattr(bpy.types, prop.name, None) + if panel_class: + tab_name = get_panel_tab_name(panel_class) + if tab_name and tab_name != "BOOKMARK": + bl_label = getattr(panel_class, "bl_label", prop.name) + panels[tab_name].append({"bl_idname": prop.name, "bl_label": bl_label}) + + if prop.is_bookmarked: + panel_class = getattr(bpy.types, prop.name, None) + if panel_class: + bl_label = getattr(panel_class, "bl_label", prop.name) + panels["BOOKMARK"].append({"bl_idname": prop.name, "bl_label": bl_label}) + + if not panels["BOOKMARK"]: + panels["BOOKMARK"] = [{}] + + return panels + + +def initialize_tab_visibilities(): + bim_props = tool.Blender.get_bim_props() + + if len(bim_props.tab_visibilities) > 0: + return + + for tab_name in get_tab_names(): + tab_vis = bim_props.tab_visibilities.add() + tab_vis.name = tab_name + tab_vis.is_visible = True + + +def initialize_panel_properties(): + + bim_props = tool.Blender.get_bim_props() + + if len(bim_props.panel_properties) > 0: + return + + for attr_name in dir(bpy.types): + if attr_name.startswith("BIM_PT_tab_"): + panel_class = getattr(bpy.types, attr_name) + if not hasattr(panel_class, 'bl_idname'): + continue + + panel_id = panel_class.bl_idname + + prop = bim_props.panel_properties.add() + prop.name = panel_id + prop.is_visible_in_tab = True + prop.is_visible_in_bookmarks = True + prop.is_bookmarked = False diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index 5f6eec8d59..5569f0ea1d 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -33,7 +33,7 @@ import bonsai.bim import bonsai.tool as tool import bonsai.bim.handler from enum import Enum -from bonsai.bim.ui import get_all_tab_panels, get_tab_visibility, set_tab_visibility, get_tab_names, get_panel_config, initialize_panel_properties, initialize_tab_visibilities +from bonsai.bim.helper import get_all_tab_panels, get_tab_visibility, set_tab_visibility, get_tab_names, get_panel_config, initialize_panel_properties, initialize_tab_visibilities from bpy_extras.io_utils import ImportHelper from bonsai.bim import import_ifc from bonsai.bim.prop import StrProperty @@ -1728,7 +1728,7 @@ class BIM_OT_toggle_panel_visibility(bpy.types.Operator): active_tab = getattr(context.scene, "active_tab_name", None) or getattr(tool.Blender.get_bim_props(), "tab", None) is_bookmark_tab = active_tab == "BOOKMARK" - panel_config = get_panel_config(panel_name) + panel_config = get_panel_config(panel_name, create_if_missing=True) if panel_config: if is_bookmark_tab: panel_config.is_visible_in_bookmarks = not panel_config.is_visible_in_bookmarks @@ -1762,7 +1762,7 @@ class BIM_OT_bookmark_panel(bpy.types.Operator): def execute(self, context): panel_name = self.action.replace("BOOKMARK_", "") - panel_config = get_panel_config(panel_name) + panel_config = get_panel_config(panel_name, create_if_missing=True) if panel_config: panel_config.is_bookmarked = not panel_config.is_bookmarked @@ -1808,7 +1808,7 @@ class BIM_OT_manage_tab_panels(bpy.types.Operator): item.name = panel_name item["bl_label"] = panel_label - panel_config = get_panel_config(panel_name) + panel_config = get_panel_config(panel_name, create_if_missing=True) if panel_config: if self.tab_name == "BOOKMARK": item["visible"] = panel_config.is_visible_in_bookmarks @@ -1830,7 +1830,7 @@ class BIM_OT_manage_tab_panels(bpy.types.Operator): def execute(self, context): for item in context.scene.tab_panels: - panel_config = get_panel_config(item.name) + panel_config = get_panel_config(item.name, create_if_missing=True) if panel_config: if self.tab_name == "BOOKMARK": panel_config.is_visible_in_bookmarks = item["visible"] diff --git a/src/bonsai/bonsai/bim/ui.py b/src/bonsai/bonsai/bim/ui.py index 8968821244..76cb29b991 100644 --- a/src/bonsai/bonsai/bim/ui.py +++ b/src/bonsai/bonsai/bim/ui.py @@ -35,7 +35,20 @@ from bonsai import get_debug_info import bonsai.bim import bonsai.tool as tool from ifcopenshell.util.file import IfcHeaderExtractor -from bonsai.bim.prop import Attribute, get_tab +from bonsai.bim.prop import Attribute +from bonsai.bim.helper import ( + get_tab_names, + get_panel_tab_name, + should_show_panel, + get_tab_visibility, + set_tab_visibility, + get_panel_visibility, + is_panel_bookmarked, + get_panel_config, + get_all_tab_panels, + initialize_tab_visibilities, + initialize_panel_properties, +) from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDProperty from bonsai.bim.module.pset.prop import IfcProperty from bonsai.bim.module.model.prop import ( @@ -62,159 +75,6 @@ if TYPE_CHECKING: from bonsai.bim.module.project.prop import BIMProjectProperties -def get_tab_names(): - enum_items = get_tab(None, None) - return [item[0] for item in enum_items if item is not None] - -def get_panel_tab_name(panel_class): - if hasattr(panel_class, 'bim_tab_name'): - return panel_class.bim_tab_name - return "PROJECT" # Default fallback - - -def should_show_panel(panel_id, panel_tab_name, context): - if tool.Blender.is_tab(context, "BOOKMARK"): - return is_panel_bookmarked(panel_id) and get_panel_visibility(panel_id, "BOOKMARK") - - if tool.Blender.is_tab(context, panel_tab_name): - return get_tab_visibility(panel_tab_name) and get_panel_visibility(panel_id, panel_tab_name) - - return False - -def initialize_tab_visibilities(): - """Initialize tab visibility collection with all tabs set to visible by default.""" - try: - bim_props = tool.Blender.get_bim_props() - except (AttributeError, AssertionError): - # Context not available during registration, skip initialization - return - - if len(bim_props.tab_visibilities) > 0: - return - - for tab_name in get_tab_names(): - tab_vis = bim_props.tab_visibilities.add() - tab_vis.name = tab_name - tab_vis.is_visible = True - - -def initialize_panel_properties(): - try: - bim_props = tool.Blender.get_bim_props() - - if len(bim_props.panel_properties) > 0: - return - - for attr_name in dir(bpy.types): - if attr_name.startswith("BIM_PT_tab_"): - try: - panel_class = getattr(bpy.types, attr_name) - if not hasattr(panel_class, 'bl_idname'): - continue - - panel_id = panel_class.bl_idname - - prop = bim_props.panel_properties.add() - prop.name = panel_id - prop.is_visible_in_tab = True - prop.is_visible_in_bookmarks = True - prop.is_bookmarked = False - except: - pass - except: - pass - -def get_panel_config(panel_id): - try: - bim_props = tool.Blender.get_bim_props() - - for prop in bim_props.panel_properties: - if prop.name == panel_id: - return prop - - prop = bim_props.panel_properties.add() - prop.name = panel_id - prop.is_visible_in_tab = True - prop.is_visible_in_bookmarks = True - prop.is_bookmarked = False - return prop - except: - return None - -def get_all_tab_panels(force_refresh=False): - panels = {tab_name: [] for tab_name in get_tab_names() if tab_name != "BOOKMARK"} - panels["BOOKMARK"] = [] - - try: - bim_props = tool.Blender.get_bim_props() - for prop in bim_props.panel_properties: - try: - panel_class = getattr(bpy.types, prop.name, None) - if panel_class: - tab_name = get_panel_tab_name(panel_class) - if tab_name and tab_name != "BOOKMARK": - bl_label = getattr(panel_class, "bl_label", prop.name) - panels[tab_name].append({"bl_idname": prop.name, "bl_label": bl_label}) - except: - pass - - if prop.is_bookmarked: - try: - panel_class = getattr(bpy.types, prop.name, None) - if panel_class: - bl_label = getattr(panel_class, "bl_label", prop.name) - panels["BOOKMARK"].append({"bl_idname": prop.name, "bl_label": bl_label}) - except: - pass - except: - pass - - if not panels["BOOKMARK"]: - panels["BOOKMARK"] = [{}] - - return panels - - -def get_tab_visibility(tab_name): - bim_props = tool.Blender.get_bim_props() - tab_vis = bim_props.tab_visibilities.get(tab_name) - return tab_vis.is_visible if tab_vis else True - - -def set_tab_visibility(tab_name, visible): - bim_props = tool.Blender.get_bim_props() - tab_vis = bim_props.tab_visibilities.get(tab_name) - if tab_vis: - tab_vis.is_visible = visible - else: - # Create if doesn't exist - new_tab = bim_props.tab_visibilities.add() - new_tab.name = tab_name - new_tab.is_visible = visible - - -def get_panel_visibility(panel_id, current_tab=None): - try: - panel_config = get_panel_config(panel_id) - if panel_config: - if current_tab == "BOOKMARK": - return panel_config.is_visible_in_bookmarks - else: - return panel_config.is_visible_in_tab - except: - pass - return True - -def is_panel_bookmarked(panel_id): - try: - panel_config = get_panel_config(panel_id) - if panel_config: - return panel_config.is_bookmarked - except: - pass - return False - - class IFCFileSelector: layout: bpy.types.UILayout