mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Reuse tool.Blender.add_layout_hotkey_operator
Now all tools are using a general method and it should be easier to maintain the consistency between the tools. Fixes #6238. ping @trhyder just in case
This commit is contained in:
@@ -23,7 +23,7 @@ import bonsai.bim.module.type.prop as type_prop
|
||||
import ifcopenshell.util.unit
|
||||
from bpy.types import WorkSpaceTool
|
||||
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData
|
||||
from typing import Union
|
||||
from functools import partial
|
||||
|
||||
|
||||
def load_custom_icons():
|
||||
@@ -330,29 +330,7 @@ def add_header_apply_button(layout, text, apply_operator, cancel_operator, ui_co
|
||||
row.label(text="Tools")
|
||||
|
||||
|
||||
def add_layout_hotkey_operator(
|
||||
layout: bpy.types.UILayout, text: str, hotkey: str, description: Union[str, None], ui_context: str = ""
|
||||
) -> bpy.types.OperatorProperties:
|
||||
parts = hotkey.split("_")
|
||||
modifier, key = parts
|
||||
op_text = "" if ui_context == "TOOL_HEADER" else text
|
||||
custom_icon = custom_icon_previews.get(text.upper().replace(" ", "_"), custom_icon_previews["IFC"]).icon_id
|
||||
modifier_icon, modifier_str = tool.Blender.KEY_MODIFIERS.get(modifier, ("NONE", ""))
|
||||
|
||||
row = layout if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
op = row.operator("bim.cad_hotkey", text=op_text, icon_value=custom_icon)
|
||||
|
||||
if ui_context != "TOOL_HEADER" and len(parts) == 2:
|
||||
layout = layout.row(align=True) # Create a new line for hotkey display
|
||||
layout.label(text="", icon=modifier_icon)
|
||||
layout.label(text="", icon=f"EVENT_{key}")
|
||||
|
||||
hotkey_description = f"Hotkey: {modifier_str} {key}"
|
||||
description = "\n\n".join(filter(None, [hotkey_description if description else ""]))
|
||||
op.hotkey = hotkey
|
||||
op.description = description or hotkey_description
|
||||
|
||||
return op
|
||||
add_layout_hotkey_operator = partial(tool.Blender.add_layout_hotkey_operator, tool_name="cad", module_name=__name__)
|
||||
|
||||
|
||||
custom_icon_previews = None
|
||||
|
||||
@@ -24,6 +24,7 @@ import bonsai.tool as tool
|
||||
from bonsai.bim.helper import prop_with_search
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bpy.types import WorkSpaceTool
|
||||
from functools import partial
|
||||
|
||||
|
||||
class CoveringTool(WorkSpaceTool):
|
||||
@@ -45,9 +46,7 @@ class CoveringTool(WorkSpaceTool):
|
||||
CoveringToolUI.draw(context, layout, ifc_element_type=cls.ifc_element_type)
|
||||
|
||||
|
||||
def add_layout_hotkey(layout: bpy.types.UILayout, text: str, hotkey: str, description: str) -> None:
|
||||
args = ("covering", layout, text, hotkey, description)
|
||||
tool.Blender.add_layout_hotkey_operator(*args)
|
||||
add_layout_hotkey = partial(tool.Blender.add_layout_hotkey_operator, tool_name="covering", module_name=__name__)
|
||||
|
||||
|
||||
class CoveringToolUI:
|
||||
|
||||
@@ -27,7 +27,7 @@ import ifcopenshell.util.representation
|
||||
from bonsai.bim.module.drawing.data import DecoratorData, AnnotationData
|
||||
from bonsai.bim.helper import prop_with_search
|
||||
from bpy.types import WorkSpaceTool
|
||||
from typing import Union
|
||||
from functools import partial
|
||||
|
||||
|
||||
class LaunchAnnotationTypeManager(bpy.types.Operator):
|
||||
@@ -135,23 +135,9 @@ class AnnotationTool(WorkSpaceTool):
|
||||
AnnotationToolUI.draw(context, layout)
|
||||
|
||||
|
||||
def add_layout_hotkey_operator(
|
||||
layout: bpy.types.UILayout, text: str, hotkey: str, description: Union[str, None]
|
||||
) -> tuple[bpy.types.OperatorProperties, bpy.types.UILayout]:
|
||||
modifiers = {
|
||||
"A": "EVENT_ALT",
|
||||
"S": "EVENT_SHIFT",
|
||||
}
|
||||
modifier, key = hotkey.split("_")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="", icon=modifiers[modifier])
|
||||
row.label(text="", icon=f"EVENT_{key}")
|
||||
|
||||
op = row.operator("bim.annotation_hotkey", text=text)
|
||||
op.hotkey = hotkey
|
||||
op.description = description
|
||||
return op, row
|
||||
add_layout_hotkey_operator = partial(
|
||||
tool.Blender.add_layout_hotkey_operator, tool_name="annotation", module_name=__name__
|
||||
)
|
||||
|
||||
|
||||
# TODO: move to operator
|
||||
|
||||
@@ -30,6 +30,7 @@ from bonsai.bim.module.model.data import AuthoringData, ItemData
|
||||
from bonsai.bim.module.system.data import PortData
|
||||
from bonsai.bim.module.model.prop import get_ifc_class
|
||||
from typing import Optional, Union
|
||||
from functools import partial
|
||||
|
||||
|
||||
def load_custom_icons():
|
||||
@@ -365,43 +366,7 @@ class CableTool(BimTool):
|
||||
ifc_element_type = "IfcCableSegmentType"
|
||||
|
||||
|
||||
def add_layout_hotkey_operator(
|
||||
layout: bpy.types.UILayout,
|
||||
text: str,
|
||||
hotkey: str,
|
||||
description: Union[str, None],
|
||||
ui_context: str = "",
|
||||
*,
|
||||
operator: str = "bim.hotkey",
|
||||
) -> bpy.types.OperatorProperties:
|
||||
"""
|
||||
:param operator: Operator to display in UI. Displaying the specific operator in UI can be useful
|
||||
to provide poll error messages.
|
||||
"""
|
||||
parts = hotkey.split("_") if hotkey else []
|
||||
modifier, key = (parts + ["", ""])[:2]
|
||||
|
||||
op_text = "" if ui_context == "TOOL_HEADER" else text
|
||||
custom_icon = custom_icon_previews.get(text.upper().replace(" ", "_"), custom_icon_previews["IFC"]).icon_id
|
||||
modifier_icon, modifier_str = tool.Blender.KEY_MODIFIERS.get(modifier, ("NONE", ""))
|
||||
|
||||
row = layout.row(align=True)
|
||||
op = row.operator(operator, text=op_text, icon_value=custom_icon)
|
||||
|
||||
if ui_context != "TOOL_HEADER":
|
||||
row.label(text="", icon=modifier_icon)
|
||||
row.label(text="", icon=f"EVENT_{key}" if key else "BLANK1")
|
||||
|
||||
hotkey_description = f"Hotkey: {modifier_str} {key}".strip()
|
||||
description = "\n\n".join(filter(None, [description, hotkey_description]))
|
||||
|
||||
if operator == "bim.hotkey":
|
||||
op.hotkey = hotkey
|
||||
if ui_context == "TOOL_HEADER":
|
||||
op.description = text + "\n" + description
|
||||
else:
|
||||
op.description = description
|
||||
return op
|
||||
add_layout_hotkey_operator = partial(tool.Blender.add_layout_hotkey_operator, tool_name="bim", module_name=__name__)
|
||||
|
||||
|
||||
def format_ifc_camel_case(string):
|
||||
|
||||
@@ -23,6 +23,7 @@ import bonsai.tool as tool
|
||||
from bonsai.bim.module.model.data import AuthoringData
|
||||
from bpy.types import WorkSpaceTool
|
||||
import bonsai.core.spatial
|
||||
from functools import partial
|
||||
|
||||
|
||||
class SpatialTool(WorkSpaceTool):
|
||||
@@ -49,9 +50,7 @@ class SpatialTool(WorkSpaceTool):
|
||||
SpatialToolUI.draw(context, layout)
|
||||
|
||||
|
||||
def add_layout_hotkey(layout: bpy.types.UILayout, text: str, hotkey: str, description: str) -> None:
|
||||
args = ("spatial", layout, text, hotkey, description)
|
||||
tool.Blender.add_layout_hotkey_operator(*args)
|
||||
add_layout_hotkey = partial(tool.Blender.add_layout_hotkey_operator, tool_name="spatial", module_name=__name__)
|
||||
|
||||
|
||||
class SpatialToolUI:
|
||||
|
||||
@@ -21,6 +21,7 @@ import os
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import WorkSpaceTool
|
||||
from functools import partial
|
||||
|
||||
|
||||
class StructuralTool(WorkSpaceTool):
|
||||
@@ -41,9 +42,7 @@ class StructuralTool(WorkSpaceTool):
|
||||
StructuralToolUI.draw(context, layout)
|
||||
|
||||
|
||||
def add_layout_hotkey(layout: bpy.types.UILayout, text: str, hotkey: str, description: str) -> None:
|
||||
args = ("structural", layout, text, hotkey, description)
|
||||
tool.Blender.add_layout_hotkey_operator(*args)
|
||||
add_layout_hotkey = partial(tool.Blender.add_layout_hotkey_operator, tool_name="structural", module_name=__name__)
|
||||
|
||||
|
||||
# NOTES before adding new operators:
|
||||
|
||||
@@ -500,18 +500,55 @@ class Blender(bonsai.core.tool.Blender):
|
||||
|
||||
@classmethod
|
||||
def add_layout_hotkey_operator(
|
||||
cls, tool_name: str, layout: bpy.types.UILayout, text: str, hotkey: str, description: str
|
||||
cls,
|
||||
layout: bpy.types.UILayout,
|
||||
text: str,
|
||||
hotkey: str,
|
||||
description: str,
|
||||
ui_context: str = "",
|
||||
*,
|
||||
tool_name: str,
|
||||
module_name: str,
|
||||
operator: Optional[str] = None,
|
||||
) -> tuple[bpy.types.OperatorProperties, bpy.types.UILayout]:
|
||||
"""
|
||||
:param module_name: Provide `__name__` of the current module,
|
||||
so method could pick up icon previews based on the module's `custom_icon_previews` attribute.
|
||||
:param operator: Operator to display in UI. Displaying the specific operator in UI can be useful
|
||||
to provide poll error messages.
|
||||
"""
|
||||
if tool_name == "bim":
|
||||
hotkey_operator = "bim.hotkey"
|
||||
else:
|
||||
hotkey_operator = f"bim.{tool_name}_hotkey"
|
||||
operator_to_use = operator or hotkey_operator
|
||||
|
||||
modifier, key = hotkey.split("_")
|
||||
|
||||
row = layout.row(align=True)
|
||||
op_text = "" if ui_context == "TOOL_HEADER" else text
|
||||
modifier_icon, modifier_str = cls.KEY_MODIFIERS.get(modifier, ("NONE", ""))
|
||||
row.label(text="", icon=modifier_icon)
|
||||
row.label(text="", icon=f"EVENT_{key}")
|
||||
|
||||
op = row.operator(f"bim.{tool_name}_hotkey", text=text)
|
||||
op.hotkey = hotkey
|
||||
op.description = description
|
||||
row = layout if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
module = sys.modules[module_name]
|
||||
icon_previews: Union[bpy.utils.previews.ImagePreviewCollection, None]
|
||||
icon_previews = getattr(module, "custom_icon_previews", None)
|
||||
if icon_previews:
|
||||
custom_icon = icon_previews.get(text.upper().replace(" ", "_"), icon_previews["IFC"]).icon_id
|
||||
op = row.operator(operator_to_use, text=op_text, icon_value=custom_icon)
|
||||
else:
|
||||
op = row.operator(operator_to_use, text=op_text)
|
||||
if ui_context != "TOOL_HEADER":
|
||||
row.label(text="", icon=modifier_icon)
|
||||
row.label(text="", icon=f"EVENT_{key}")
|
||||
|
||||
if operator_to_use == hotkey_operator:
|
||||
hotkey_description = f"Hotkey: {modifier_str} {key}".strip()
|
||||
description = "\n\n".join(filter(None, [description, hotkey_description]))
|
||||
|
||||
op.hotkey = hotkey
|
||||
if ui_context == "TOOL_HEADER":
|
||||
op.description = text + "\n" + description
|
||||
else:
|
||||
op.description = description
|
||||
return op, row
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user