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