mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
change .poll for overridden panels instead of creating new classes
Needed to avoid errors disabling addons that have overridden panels
This commit is contained in:
@@ -23,6 +23,7 @@ import bpy.utils.previews
|
||||
import blenderbim
|
||||
import importlib
|
||||
from . import handler, ui, prop, operator, helper
|
||||
from typing import Callable, Union
|
||||
|
||||
try:
|
||||
from blenderbim.translations import translations_dict
|
||||
@@ -187,7 +188,7 @@ addon_keymaps = []
|
||||
icons = None
|
||||
is_registering = False
|
||||
last_commit_hash = "8888888"
|
||||
overridden_scene_panels = dict()
|
||||
original_scene_panels_polls: dict[bpy.types.Panel, Union[Callable, None]] = dict()
|
||||
|
||||
|
||||
def on_register(scene):
|
||||
@@ -295,10 +296,17 @@ def unregister():
|
||||
km.keymap_items.remove(kmi)
|
||||
addon_keymaps.clear()
|
||||
|
||||
for panel in tuple(overridden_scene_panels.keys()):
|
||||
original_panel, override_panel = overridden_scene_panels[panel]
|
||||
bpy.utils.unregister_class(override_panel)
|
||||
bpy.utils.register_class(original_panel)
|
||||
del overridden_scene_panels[panel]
|
||||
for panel, poll in tuple(original_scene_panels_polls.items()):
|
||||
if poll is None:
|
||||
del panel.poll
|
||||
else:
|
||||
panel.poll = poll
|
||||
# panel might be already unregisterd during blender exit
|
||||
# or if it's addon was disabled
|
||||
if panel.is_registered:
|
||||
# reregister to activate new poll
|
||||
bpy.utils.unregister_class(panel)
|
||||
bpy.utils.register_class(panel)
|
||||
del original_scene_panels_polls[panel]
|
||||
|
||||
bpy.app.translations.unregister("blenderbim")
|
||||
|
||||
@@ -260,34 +260,25 @@ def poll_check_blender_tab(cls, context):
|
||||
return tool.Blender.is_tab(context, "BLENDER")
|
||||
|
||||
|
||||
def get_override_scene_panel(panel_name):
|
||||
original_panel = getattr(bpy.types, panel_name)
|
||||
|
||||
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"
|
||||
def override_scene_panel(original_panel: bpy.types.Panel) -> None:
|
||||
polls = blenderbim.bim.original_scene_panels_polls
|
||||
|
||||
# override poll method
|
||||
poll = getattr(override_panel, "poll", None)
|
||||
if poll is None:
|
||||
override_panel.poll = poll_check_blender_tab
|
||||
if not hasattr(original_panel, "poll"):
|
||||
polls[original_panel] = None
|
||||
original_panel.poll = poll_check_blender_tab
|
||||
else:
|
||||
polls[original_panel] = original_panel.poll
|
||||
|
||||
@classmethod
|
||||
def wrapped_poll(cls, context):
|
||||
return super(override_panel, cls).poll(context) and poll_check_blender_tab.__func__(cls, context)
|
||||
return polls[cls](context) and poll_check_blender_tab.__func__(cls, context)
|
||||
|
||||
override_panel.poll = wrapped_poll
|
||||
original_panel.poll = wrapped_poll
|
||||
|
||||
return override_panel
|
||||
|
||||
|
||||
OVERRIDE_SCENE_PANELS = tool.Blender.get_scene_panels_list()
|
||||
# reregister to activate new poll
|
||||
bpy.utils.unregister_class(original_panel)
|
||||
bpy.utils.register_class(original_panel)
|
||||
|
||||
|
||||
@persistent
|
||||
@@ -328,12 +319,8 @@ def load_post(scene):
|
||||
# To improve usability for new users, we hijack the scene properties
|
||||
# tab. We override default scene properties panels with our own poll
|
||||
# to hide them unless the user has chosen to view Blender properties.
|
||||
for panel in OVERRIDE_SCENE_PANELS:
|
||||
if panel in blenderbim.bim.overridden_scene_panels:
|
||||
for panel in tool.Blender.get_scene_panels_list():
|
||||
if panel in blenderbim.bim.original_scene_panels_polls:
|
||||
continue
|
||||
override_panel = get_override_scene_panel(panel)
|
||||
original_panel = getattr(bpy.types, panel)
|
||||
bpy.utils.register_class(override_panel)
|
||||
bpy.utils.unregister_class(original_panel)
|
||||
blenderbim.bim.overridden_scene_panels[panel] = (original_panel, override_panel)
|
||||
override_scene_panel(panel)
|
||||
tool.Blender.setup_tabs()
|
||||
|
||||
@@ -877,7 +877,7 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def get_scene_panels_list(cls) -> tuple[str, ...]:
|
||||
def get_scene_panels_list(cls) -> tuple[bpy.types.Panel, ...]:
|
||||
# example default blender scene panels can be found in
|
||||
# https://projects.blender.org/blender/blender/src/branch/main/scripts/startup/bl_ui/properties_scene.py#L421
|
||||
scene_panels: list[str] = []
|
||||
@@ -887,6 +887,9 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
# filter only panels
|
||||
if not hasattr(item, "bl_rna") or not isinstance(item.bl_rna, bpy.types.Panel):
|
||||
continue
|
||||
# ignore bbim panels
|
||||
if item.__module__.startswith("blenderbim"):
|
||||
continue
|
||||
# filter scene panels
|
||||
if getattr(item, "bl_context", None) != "scene":
|
||||
continue
|
||||
@@ -896,7 +899,8 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
panels_to_parents[item_name] = parent_panel
|
||||
|
||||
scene_panels = cls.sort_panels_for_register(scene_panels, panels_to_parents)
|
||||
return tuple(scene_panels)
|
||||
final_panels = [getattr(bpy.types, p) for p in scene_panels]
|
||||
return tuple(final_panels)
|
||||
|
||||
@classmethod
|
||||
def sort_panels_for_register(cls, items: list[str], items_to_parents: dict[str, str]) -> list[str]:
|
||||
|
||||
Reference in New Issue
Block a user