From d8eb765906798cdb4fbdd0a4297e71e52ea80751 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 16 Mar 2023 13:38:39 +0500 Subject: [PATCH] BIM Tool - hotkey for editing text annotation Added hotkey in BIM Tool for editing active text annotation (It's binded on Shift + E). --- src/blenderbim/blenderbim/bim/helper.py | 10 +++- .../blenderbim/bim/module/drawing/__init__.py | 1 + .../blenderbim/bim/module/drawing/operator.py | 54 ++++++++++++++++++- .../blenderbim/bim/module/drawing/ui.py | 3 ++ .../blenderbim/bim/module/model/workspace.py | 16 ++++++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 940dc80c40..ef74fbfedb 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -31,9 +31,15 @@ import blenderbim.tool as tool from blenderbim.bim.ifc import IfcStore -def draw_attributes(props, layout, copy_operator=None): - for attribute in props: +def draw_attributes(props, layout, copy_operator=None, popup_active_attribute=None): + """you can set attribute active in popup with `active_attribute` + meaning you will be able to type into attribute's field without having to click + on it first + """ + for attribute in props: row = layout.row(align=True) + if attribute == popup_active_attribute: + row.activate_init = True draw_attribute(attribute, row, copy_operator) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/__init__.py b/src/blenderbim/blenderbim/bim/module/drawing/__init__.py index 9046efd317..403850fc51 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/__init__.py @@ -45,6 +45,7 @@ classes = ( operator.DuplicateDrawing, operator.EditAssignedProduct, operator.EditText, + operator.EditTextPopup, operator.EditVectorStyle, operator.EnableEditingAssignedProduct, operator.EnableEditingText, diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index f1e8db553d..d1a6ff0eed 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -39,7 +39,7 @@ import blenderbim.bim.module.drawing.annotation as annotation import blenderbim.bim.module.drawing.sheeter as sheeter import blenderbim.bim.module.drawing.scheduler as scheduler import blenderbim.bim.module.drawing.helper as helper -from blenderbim.bim.module.drawing.data import DecoratorData +from blenderbim.bim.module.drawing.data import DecoratorData, TextData import blenderbim.bim.export_ifc from lxml import etree from mathutils import Vector @@ -1359,6 +1359,57 @@ class AddSectionsAnnotations(bpy.types.Operator): return {"FINISHED"} +class EditTextPopup(bpy.types.Operator): + bl_idname = "bim.edit_text_popup" + bl_label = "Edit Text" + first_run: bpy.props.BoolProperty(default=True) + + def draw(self, context): + # shares most of the code with BIM_PT_text.draw() + # need to keep them in sync or move to some common function + + if not TextData.is_loaded: + TextData.load() + props = context.active_object.BIMTextProperties + + # skip BoxAlignment since we're going to format it ourselves + attributes = [a for a in props.attributes if a.name != "BoxAlignment"] + # set first attribute with text to be active by default + blenderbim.bim.helper.draw_attributes(attributes, self.layout, popup_active_attribute=attributes[0]) + row = self.layout.row(align=True) + row.prop(props, "font_size") + + # a bit hacky way to align box alignment widget + rows = [self.layout.row(align=True) for i in range(3)] + for i in range(9): + if i % 3 == 0: + split = rows[i // 3].split(factor=0.1, align=True) + split.column() + split.prop(props, "box_alignment", text="", index=i) + + text_lines = ["Text box alignment:", props.attributes["BoxAlignment"].string_value, ""] + for i in range(3): + split = rows[i].split(factor=0.1, align=False) + split.column() + split.label(text=text_lines[i]) + + def cancel(self, context): + # disable editing when dialog is closed + bpy.ops.bim.disable_editing_text() + + def execute(self, context): + # can't use invoke() because this operator + # will be run indirectly by hotkey + # so we use execute() and track whether it's the first run of the operator + if self.first_run: + bpy.ops.bim.enable_editing_text() + self.first_run = False + return context.window_manager.invoke_props_dialog(self) + else: + bpy.ops.bim.edit_text() + return {'FINISHED'} + + class EditText(bpy.types.Operator, Operator): bl_idname = "bim.edit_text" bl_label = "Edit Text" @@ -1366,6 +1417,7 @@ class EditText(bpy.types.Operator, Operator): def _execute(self, context): core.edit_text(tool.Ifc, tool.Drawing, obj=context.active_object) + tool.Blender.update_viewport() class EnableEditingText(bpy.types.Operator, Operator): diff --git a/src/blenderbim/blenderbim/bim/module/drawing/ui.py b/src/blenderbim/blenderbim/bim/module/drawing/ui.py index 0a0ab1e961..6e3d65b699 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/ui.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/ui.py @@ -346,6 +346,9 @@ class BIM_PT_text(Panel): props = context.active_object.BIMTextProperties if props.is_editing: + # shares most of the code with EditTextPopup.draw() + # need to keep them in sync or move to some common function + row = self.layout.row(align=True) row.operator("bim.edit_text", icon="CHECKMARK") row.operator("bim.disable_editing_text", icon="CANCEL", text="") diff --git a/src/blenderbim/blenderbim/bim/module/model/workspace.py b/src/blenderbim/blenderbim/bim/module/model/workspace.py index b3c88a2923..a926a638c3 100644 --- a/src/blenderbim/blenderbim/bim/module/model/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/model/workspace.py @@ -25,6 +25,7 @@ import blenderbim.bim.module.type.prop as type_prop from blenderbim.bim.helper import prop_with_search, close_operator_panel from bpy.types import WorkSpaceTool from blenderbim.bim.module.model.data import AuthoringData, RailingData, RoofData +from blenderbim.bim.module.drawing.data import TextData from blenderbim.bim.module.model import prop @@ -333,6 +334,14 @@ class BimToolUI: row.label(text="", icon="EVENT_SHIFT") row.label(text="", icon="EVENT_E") row.operator("bim.hotkey", text="Edit Roof Path").hotkey = "S_E" + elif ( + (TextData.is_loaded or not TextData.load()) + and TextData.data["attributes"] + ): + row = cls.layout.row(align=True) + row.label(text="", icon="EVENT_SHIFT") + row.label(text="", icon="EVENT_E") + row.operator("bim.hotkey", text="Edit text").hotkey = "S_E" row = cls.layout.row(align=True) row.label(text="", icon="EVENT_SHIFT") @@ -568,6 +577,13 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator): bpy.context.object.select_set(True) bpy.ops.bim.enable_editing_roof_path() + elif ( + (TextData.is_loaded or not TextData.load()) + and TextData.data["attributes"] + ): + bpy.context.object.select_set(True) + bpy.ops.bim.edit_text_popup() + def hotkey_S_F(self): if not bpy.context.selected_objects: return