diff --git a/src/bonsai/bonsai/bim/module/drawing/operator.py b/src/bonsai/bonsai/bim/module/drawing/operator.py index 8b30737176..fa17be9fb5 100644 --- a/src/bonsai/bonsai/bim/module/drawing/operator.py +++ b/src/bonsai/bonsai/bim/module/drawing/operator.py @@ -3305,9 +3305,8 @@ class AddTextLiteral(bpy.types.Operator): attr.data_type = "string" attr.string_value = literal_attr_values[attr_name] - box_alignment_mask = [False] * 9 - box_alignment_mask[6] = True # bottom_left box_alignment - literal_props.box_alignment = box_alignment_mask + literal_props.align_vertical = "bottom" + literal_props.align_horizontal = "left" return {"FINISHED"} @@ -4178,10 +4177,7 @@ class SelectSimilarTextLiteralValue(bpy.types.Operator): should_select = True break elif self.attribute_type == "box_alignment": - box_alignment_attr = next( - (attr for attr in literal.attributes if attr.name == "BoxAlignment"), None - ) - if box_alignment_attr and box_alignment_attr.string_value == self.literal_value: + if literal.get_box_alignment() == self.literal_value: should_select = True break diff --git a/src/bonsai/bonsai/bim/module/drawing/prop.py b/src/bonsai/bonsai/bim/module/drawing/prop.py index cc597a4802..6019c480b9 100644 --- a/src/bonsai/bonsai/bim/module/drawing/prop.py +++ b/src/bonsai/bonsai/bim/module/drawing/prop.py @@ -673,20 +673,6 @@ class BIMCameraProperties(PropertyGroup): return ortho_scale, aspect_ratio -DEFAULT_BOX_ALIGNMENT = [False] * 6 + [True] + [False] * 2 -BOX_ALIGNMENT_POSITIONS = [ - "top-left", - "top-middle", - "top-right", - "middle-left", - "center", - "middle-right", - "bottom-left", - "bottom-middle", - "bottom-right", -] - - class ElementValueRow(PropertyGroup): """Represents a single element value row with category, key, and formatted value""" @@ -789,40 +775,38 @@ def get_category_items_with_counts(self, context): class LiteralProps(PropertyGroup): - def set_box_alignment(self, new_value): - markers = new_value.count(True) - if not markers: - return - - if markers > 1: - prev_value = self.get("box_alignment", DEFAULT_BOX_ALIGNMENT) - # looking for the first value changed to positive - first_changed_value = next((i for i in range(9) if new_value[i] and new_value[i] != prev_value[i]), None) - - # if nothing have changed we just keep the previous value - if first_changed_value is None: - return - new_value = [False] * 9 - new_value[first_changed_value] = True - - self["box_alignment"] = new_value - position_string = BOX_ALIGNMENT_POSITIONS[next(i for i in range(9) if new_value[i])] - self.attributes["BoxAlignment"].set_value(position_string) - - def get_box_alignment(self): - return self.get("box_alignment", DEFAULT_BOX_ALIGNMENT) - attributes: CollectionProperty(name="Attributes", type=Attribute) - box_alignment: BoolVectorProperty( - name="Box alignment", size=9, set=set_box_alignment, get=get_box_alignment, default=DEFAULT_BOX_ALIGNMENT - ) ifc_definition_id: IntProperty(name="IFC definition ID", default=0) + align_horizontal: EnumProperty( + items=[ + ("left", "Left", "", "ALIGN_LEFT", 0), + ("middle", "Middle", "", "ALIGN_CENTER", 1), + ("right", "Right", "", "ALIGN_RIGHT", 2), + ], + default="left", + name="Horizontal Alignment", + ) + align_vertical: EnumProperty( + items=[ + ("top", "Top", "", "ALIGN_TOP", 0), + ("middle", "Middle", "", "ALIGN_MIDDLE", 1), + ("bottom", "Bottom", "", "ALIGN_BOTTOM", 2), + ], + default="middle", + name="Vertical Alignment", + ) + + def get_box_alignment(self) -> str: + alignment = self.align_vertical + "-" + self.align_horizontal + if alignment == "middle-middle": + alignment = "center" + return alignment def get_literal_edited_data(self) -> dict[str, str]: text_data = { "CurrentValue": self.attributes["Literal"].string_value, "Literal": self.attributes["Literal"].string_value, - "BoxAlignment": self.attributes["BoxAlignment"].string_value, + "BoxAlignment": self.get_box_alignment(), } return text_data @@ -860,12 +844,19 @@ class LiteralProps(PropertyGroup): if TYPE_CHECKING: attributes: bpy.types.bpy_prop_collection_idprop[Attribute] value: str - box_alignment: tuple[bool, bool, bool, bool, bool, bool, bool, bool, bool] ifc_definition_id: int + align_horizontal: str + align_vertical: str element_value_rows: bpy.types.bpy_prop_collection_idprop[ElementValueRow] category_for_adding: str +def update_text_alignment(self, context): + for literal_props in self.literals: + literal_props.align_horizontal = self.align_horizontal + literal_props.align_vertical = self.align_vertical + + class BIMTextProperties(PropertyGroup): is_editing: BoolProperty(name="Is Editing", default=False) literals: CollectionProperty(name="Literals", type=LiteralProps) @@ -899,6 +890,7 @@ class BIMTextProperties(PropertyGroup): ], default="left", name="Horizontal Alignment", + update=update_text_alignment, ) align_vertical: EnumProperty( items=[ @@ -908,6 +900,7 @@ class BIMTextProperties(PropertyGroup): ], default="middle", name="Vertical Alignment", + update=update_text_alignment, ) if TYPE_CHECKING: diff --git a/src/bonsai/bonsai/bim/module/drawing/ui.py b/src/bonsai/bonsai/bim/module/drawing/ui.py index 1b6a11cd75..796c36b484 100644 --- a/src/bonsai/bonsai/bim/module/drawing/ui.py +++ b/src/bonsai/bonsai/bim/module/drawing/ui.py @@ -781,33 +781,10 @@ class BIM_PT_text(Panel): if other_attributes: bonsai.bim.helper.draw_attributes(other_attributes, box) - row = box.row(align=True) - cols = [row.column(align=True) for j in range(3)] - for j in range(9): - cols[j % 3].prop( - literal_props, - "box_alignment", - text="", - index=j, - icon="RADIOBUT_ON" if literal_props.box_alignment[j] else "RADIOBUT_OFF", - ) - - col = row.column(align=True) - alignment_label_row = col.row(align=True) - alignment_label_row.label(text=" Text box alignment:") - - box_alignment_value = ( - literal_props.attributes[ - next( - (idx for idx, attr in enumerate(literal_props.attributes) if attr.name == "BoxAlignment"), - -1, - ) - ].string_value - if any(attr.name == "BoxAlignment" for attr in literal_props.attributes) - else "N/A" - ) - - col.label(text=f" {box_alignment_value}") + row = box.row() + row.label(text="Alignment") + row.prop(literal_props, "align_horizontal", text="", expand=True) + row.prop(literal_props, "align_vertical", text="", expand=True) def draw(self, context): obj = context.active_object diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index b8ec26fd37..a78fd67ed2 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -603,6 +603,10 @@ class Drawing(bonsai.core.tool.Drawing): props = tool.Drawing.get_text_props(obj) for literal_props in props.literals: literal_data = bonsai.bim.helper.export_attributes(literal_props.attributes) + alignment = literal_props.align_vertical + "-" + literal_props.align_horizontal + if alignment == "middle-middle": + alignment = "center" + literal_data["BoxAlignment"] = alignment literals.append(literal_data) return literals @@ -1176,22 +1180,26 @@ class Drawing(bonsai.core.tool.Drawing): @classmethod def import_text_attributes(cls, obj: bpy.types.Object) -> None: - from bonsai.bim.module.drawing.prop import BOX_ALIGNMENT_POSITIONS - props = cls.get_text_props(obj) props.literals.clear() ifc_literals = cls.get_text_literal(obj, return_list=True) assert isinstance(ifc_literals, list) + + if ifc_literals: + first_alignment = getattr(ifc_literals[0], "BoxAlignment", None) or "bottom-left" + if first_alignment == "center": + first_alignment = "middle-middle" + props.align_vertical, props.align_horizontal = first_alignment.split("-") + for ifc_literal in ifc_literals: literal_props = props.literals.add() bonsai.bim.helper.import_attributes(ifc_literal, literal_props.attributes) - box_alignment_mask = [False] * 9 - position_string = literal_props.attributes["BoxAlignment"].string_value - box_alignment_mask[BOX_ALIGNMENT_POSITIONS.index(position_string)] = True - - literal_props.box_alignment = box_alignment_mask # pyright: ignore[reportAttributeAccessIssue] + alignment = getattr(ifc_literal, "BoxAlignment", None) or "bottom-left" + if alignment == "center": + alignment = "middle-middle" + literal_props.align_vertical, literal_props.align_horizontal = alignment.split("-") literal_props.ifc_definition_id = ifc_literal.id() from bonsai.bim.module.drawing.data import DecoratorData diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py index 06091ff8c4..1d6e9e6e0f 100644 --- a/src/bonsai/test/tool/test_drawing.py +++ b/src/bonsai/test/tool/test_drawing.py @@ -666,10 +666,13 @@ class TestImportTextAttributes(NewFile): literal_props = props.literals[0] assert literal_props.ifc_definition_id == item.id() - assert literal_props.box_alignment[:] == tuple([False] * 6 + [True] + [False] * 2) assert literal_props.attributes["Literal"].string_value == "Literal" assert literal_props.attributes["Path"].enum_value == "RIGHT" assert literal_props.attributes["BoxAlignment"].string_value == "bottom-left" + assert literal_props.align_vertical == "bottom" + assert literal_props.align_horizontal == "left" + assert props.align_vertical == "bottom" + assert props.align_horizontal == "left" class TestReplaceTextLiteralVariables(NewFile):