diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index 90e2b2ca0e..e1b11998c7 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -293,9 +293,14 @@ def unregister(): "SCENE_PT_audio", "SCENE_PT_keying_sets", "SCENE_PT_simulation", - "SCENE_PT_custom_props", + "SCENE_PT_custom_props", # 4.0 + # after SCENE_PT_keying_sets + "SCENE_PT_keying_set_paths" "SCENE_PT_keyframing_settings", ]: try: bpy.utils.unregister_class(getattr(handler, f"Override_{panel}")) except: + # NOTE: breaks Blender UI on unregister + # since default Blender panels are unregistered on load_post + # unregistering our override panels removes them from Blender completely pass diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py index c27bcbdb35..32a1f2d703 100644 --- a/src/blenderbim/blenderbim/bim/handler.py +++ b/src/blenderbim/blenderbim/bim/handler.py @@ -253,85 +253,38 @@ def viewport_shading_changed_callback(area): bpy.context.scene.BIMStylesProperties.active_style_type = "External" -if getattr(bpy.types, "SCENE_PT_scene"): +@classmethod +def poll_check_blender_tab(cls, context): + return tool.Blender.is_tab(context, "BLENDER") - class Override_SCENE_PT_scene(bpy.types.SCENE_PT_scene): - bl_idname = "SCENE_PT_scene_override" + +def get_override_scene_panel(panel_name): + original_panel = getattr(bpy.types, panel_name, None) + if original_panel is None: + return + + override_panel = type(f"Override_{panel_name}", (original_panel,), {}) + override_panel.bl_idname = f"{panel_name}_override" + + # some blender panel depend on other and register_class will throw an error + # if we won't override their `bl_parent_id` + bl_parent_id = getattr(override_panel, "bl_parent_id", None) + if bl_parent_id is not None: + override_panel.bl_parent_id = f"{bl_parent_id}_override" + + # override poll method + poll = getattr(override_panel, "poll", None) + if poll is None: + override_panel.poll = poll_check_blender_tab + else: @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") + def wrapped_poll(cls, context): + return super(override_panel, cls).poll(context) and poll_check_blender_tab.__func__(cls, context) + override_panel.poll = wrapped_poll -if getattr(bpy.types, "SCENE_PT_unit"): - - class Override_SCENE_PT_unit(bpy.types.SCENE_PT_unit): - bl_idname = "SCENE_PT_unit_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -if getattr(bpy.types, "SCENE_PT_physics"): - - class Override_SCENE_PT_physics(bpy.types.SCENE_PT_physics): - bl_idname = "SCENE_PT_physics_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -if getattr(bpy.types, "SCENE_PT_rigid_body_world"): - - class Override_SCENE_PT_rigid_body_world(bpy.types.SCENE_PT_rigid_body_world): - bl_idname = "SCENE_PT_rigid_body_world_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -if getattr(bpy.types, "SCENE_PT_audio"): - - class Override_SCENE_PT_audio(bpy.types.SCENE_PT_audio): - bl_idname = "SCENE_PT_audio_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -if getattr(bpy.types, "SCENE_PT_keying_sets"): - - class Override_SCENE_PT_keying_sets(bpy.types.SCENE_PT_keying_sets): - bl_idname = "SCENE_PT_keying_sets_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -if getattr(bpy.types, "SCENE_PT_custom_props"): - - class Override_SCENE_PT_custom_props(bpy.types.SCENE_PT_custom_props): - bl_idname = "SCENE_PT_custom_props_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") - - -# available on Blender 4.0+ -if getattr(bpy.types, "SCENE_PT_simulation", None): - - class Override_SCENE_PT_simulation(bpy.types.SCENE_PT_simulation): - bl_idname = "SCENE_PT_simulation_override" - - @classmethod - def poll(cls, context): - return tool.Blender.is_tab(context, "BLENDER") + return override_panel @persistent @@ -379,16 +332,21 @@ def load_post(scene): "SCENE_PT_rigid_body_world", "SCENE_PT_audio", "SCENE_PT_keying_sets", - "SCENE_PT_simulation", + "SCENE_PT_simulation", # 4.0+ "SCENE_PT_custom_props", + # after SCENE_PT_keying_sets + "SCENE_PT_keying_set_paths", + "SCENE_PT_keyframing_settings", ]: - if getattr(bpy.types, panel, None): - try: - bpy.utils.register_class(globals()[f"Override_{panel}"]) - bpy.utils.unregister_class(getattr(bpy.types, panel)) - except: - pass - + try: + override_panel = get_override_scene_panel(panel) + if override_panel is None: + continue + original_panel = getattr(bpy.types, panel) + bpy.utils.register_class(override_panel) + bpy.utils.unregister_class(original_panel) + except Exception: # some panels belong to different Blender versions + pass # https://blender.stackexchange.com/questions/140644/how-can-make-the-state-of-a-boolean-property-relative-to-the-3d-view-area for screen in bpy.data.screens: if len(screen.BIMAreaProperties) == 20: