mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Option to change text symbol from general text editing UI
Example - https://files.catbox.moe/kxyepa.mp4
This commit is contained in:
@@ -601,8 +601,7 @@ class BaseDecorator:
|
||||
props = tool.Drawing.get_text_props(obj)
|
||||
text_data = DecoratorData.data["text"].get(obj.name, None)
|
||||
if props.is_editing:
|
||||
# Still use original `text_data`, because of the "Symbol".
|
||||
text_data = text_data | props.get_text_edited_data()
|
||||
text_data = props.get_text_edited_data()
|
||||
literals_data = text_data["Literals"]
|
||||
symbol = text_data["Symbol"]
|
||||
newline_at = text_data["Newline_At"]
|
||||
|
||||
@@ -738,12 +738,43 @@ class BIMTextProperties(PropertyGroup):
|
||||
name="Font Size",
|
||||
)
|
||||
newline_at: IntProperty(name="Newline At")
|
||||
symbol: EnumProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Symbol",
|
||||
description="Symbol from symbols.svg to use for this text.",
|
||||
items=[(s, s, "") for s in ["NO SYMBOL", "CUSTOM SYMBOL"] + tool.Drawing.DEFAULT_SYMBOLS],
|
||||
default="NO SYMBOL",
|
||||
)
|
||||
custom_symbol: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Custom Symbol",
|
||||
description="Non-default symbol to use for this text.",
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_editing: bool
|
||||
literals: bpy.types.bpy_prop_collection_idprop[LiteralProps]
|
||||
font_size: str
|
||||
newline_at: int
|
||||
symbol: Union[str, Literal["NO SYMBOL", "CUSTOM SYMBOL"]]
|
||||
custom_symbol: str
|
||||
|
||||
def get_symbol(self) -> Union[str, None]:
|
||||
if self.symbol == "NO SYMBOL":
|
||||
return None
|
||||
elif self.symbol == "CUSTOM SYMBOL":
|
||||
return self.custom_symbol or None
|
||||
else:
|
||||
return self.symbol
|
||||
|
||||
def set_symbol(self, symbol: Union[str, None]):
|
||||
if not symbol:
|
||||
self.property_unset("symbol")
|
||||
self.property_unset("custom_symbol")
|
||||
elif symbol in tool.Drawing.DEFAULT_SYMBOLS:
|
||||
self.symbol = symbol
|
||||
self.property_unset("custom_symbol")
|
||||
else:
|
||||
self.symbol = "CUSTOM SYMBOL"
|
||||
self.custom_symbol = symbol
|
||||
|
||||
def get_text_edited_data(self) -> dict[str, Any]:
|
||||
"""should be called only if `is_editing`
|
||||
@@ -758,6 +789,7 @@ class BIMTextProperties(PropertyGroup):
|
||||
"Literals": literals_data,
|
||||
"FontSize": float(self.font_size),
|
||||
"Newline_At": int(self.newline_at),
|
||||
"Symbol": self.get_symbol(),
|
||||
}
|
||||
return text_data
|
||||
|
||||
|
||||
@@ -591,6 +591,12 @@ class BIM_PT_text(Panel):
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "newline_at")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "symbol")
|
||||
if props.symbol == "CUSTOM SYMBOL":
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(props, "custom_symbol", text="")
|
||||
|
||||
for i, literal_props in enumerate(props.literals):
|
||||
box = self.layout.box()
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
@@ -39,7 +39,7 @@ def disable_editing_text(drawing: type[tool.Drawing], obj: bpy.types.Object) ->
|
||||
def edit_text(drawing: type[tool.Drawing], obj: bpy.types.Object) -> None:
|
||||
drawing.synchronise_ifc_and_text_attributes(obj)
|
||||
drawing.update_text_size_pset(obj)
|
||||
drawing.update_newline_at(obj)
|
||||
drawing.update_newline_at_and_symbol(obj)
|
||||
drawing.disable_editing_text(obj)
|
||||
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ class Drawing:
|
||||
def sync_object_placement(cls, obj): pass
|
||||
def synchronise_ifc_and_text_attributes(cls, obj): pass
|
||||
def update_embedded_svg_location(cls, uri, old_location, new_location): pass
|
||||
def update_newline_at(cls, obj): pass
|
||||
def update_newline_at_and_symbol(cls, obj): pass
|
||||
def update_text_size_pset(cls, obj): pass
|
||||
|
||||
|
||||
|
||||
@@ -1581,6 +1581,11 @@ class Blender(bonsai.core.tool.Blender):
|
||||
return repr(bpy_prop)
|
||||
return repr(bpy_struct)
|
||||
|
||||
@classmethod
|
||||
def get_props_attribute_name(cls, props: bpy.types.PropertyGroup) -> str:
|
||||
"""E.g. `bpy.data.objects['IfcAnnotation/TEXT'].BIMTextProperties` -> `BIMTextProperties`"""
|
||||
return repr(props).rpartition(".")[-1]
|
||||
|
||||
@classmethod
|
||||
def resolve_data_path_to_data_attr(cls, data_path: str) -> tuple[bpy.types.bpy_struct, str]:
|
||||
"""
|
||||
|
||||
@@ -110,6 +110,27 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
}
|
||||
# fmt: on
|
||||
|
||||
DEFAULT_SYMBOLS = [
|
||||
"rectangle-tag",
|
||||
"triangle-tag",
|
||||
"hexagon-tag",
|
||||
"capsule-tag",
|
||||
"circle-tag",
|
||||
"door-tag",
|
||||
"window-tag",
|
||||
"space-tag",
|
||||
"elevation-arrow",
|
||||
"elevation-tag",
|
||||
"section-arrow",
|
||||
"section-tag",
|
||||
"dot",
|
||||
"setout-tag",
|
||||
"setout-point",
|
||||
"control-point",
|
||||
"traverse-point",
|
||||
"spot-elevation",
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_document_props(cls) -> DocProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
@@ -434,8 +455,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
@classmethod
|
||||
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
|
||||
props = tool.Drawing.get_text_props(obj)
|
||||
props.is_editing = False
|
||||
props.literals.clear()
|
||||
obj.property_unset(tool.Blender.get_props_attribute_name(props))
|
||||
|
||||
@classmethod
|
||||
def disable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
||||
@@ -1077,6 +1097,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
text_data = DecoratorData.get_text_data(obj)
|
||||
props.font_size = str(text_data["FontSize"])
|
||||
props.newline_at = text_data["Newline_At"]
|
||||
props.set_symbol(text_data["Symbol"])
|
||||
|
||||
@classmethod
|
||||
def import_assigned_product(cls, obj: bpy.types.Object) -> None:
|
||||
@@ -1214,10 +1235,12 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def update_newline_at(cls, obj: bpy.types.Object) -> None:
|
||||
def update_newline_at_and_symbol(cls, obj: bpy.types.Object) -> None:
|
||||
props = cls.get_text_props(obj)
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
assert element
|
||||
newline_at = int(props.newline_at)
|
||||
symbol = props.get_symbol()
|
||||
ifc_file = tool.Ifc.get()
|
||||
pset = tool.Pset.get_element_pset(element, "EPset_Annotation")
|
||||
if not pset:
|
||||
@@ -1225,7 +1248,10 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
ifcopenshell.api.pset.edit_pset(
|
||||
ifc_file,
|
||||
pset=pset,
|
||||
properties={"Newline_At": newline_at},
|
||||
properties={
|
||||
"Newline_At": newline_at,
|
||||
"Symbol": symbol,
|
||||
},
|
||||
)
|
||||
|
||||
# TODO below this point is highly experimental prototype code with no tests
|
||||
|
||||
@@ -37,7 +37,7 @@ class TestEditText:
|
||||
def test_run(self, drawing):
|
||||
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
|
||||
drawing.update_text_size_pset("obj").should_be_called()
|
||||
drawing.update_newline_at("obj").should_be_called()
|
||||
drawing.update_newline_at_and_symbol("obj").should_be_called()
|
||||
drawing.disable_editing_text("obj").should_be_called()
|
||||
subject.edit_text(drawing, obj="obj")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user