mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +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)
|
props = tool.Drawing.get_text_props(obj)
|
||||||
text_data = DecoratorData.data["text"].get(obj.name, None)
|
text_data = DecoratorData.data["text"].get(obj.name, None)
|
||||||
if props.is_editing:
|
if props.is_editing:
|
||||||
# Still use original `text_data`, because of the "Symbol".
|
text_data = props.get_text_edited_data()
|
||||||
text_data = text_data | props.get_text_edited_data()
|
|
||||||
literals_data = text_data["Literals"]
|
literals_data = text_data["Literals"]
|
||||||
symbol = text_data["Symbol"]
|
symbol = text_data["Symbol"]
|
||||||
newline_at = text_data["Newline_At"]
|
newline_at = text_data["Newline_At"]
|
||||||
|
|||||||
@@ -738,12 +738,43 @@ class BIMTextProperties(PropertyGroup):
|
|||||||
name="Font Size",
|
name="Font Size",
|
||||||
)
|
)
|
||||||
newline_at: IntProperty(name="Newline At")
|
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:
|
if TYPE_CHECKING:
|
||||||
is_editing: bool
|
is_editing: bool
|
||||||
literals: bpy.types.bpy_prop_collection_idprop[LiteralProps]
|
literals: bpy.types.bpy_prop_collection_idprop[LiteralProps]
|
||||||
font_size: str
|
font_size: str
|
||||||
newline_at: int
|
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]:
|
def get_text_edited_data(self) -> dict[str, Any]:
|
||||||
"""should be called only if `is_editing`
|
"""should be called only if `is_editing`
|
||||||
@@ -758,6 +789,7 @@ class BIMTextProperties(PropertyGroup):
|
|||||||
"Literals": literals_data,
|
"Literals": literals_data,
|
||||||
"FontSize": float(self.font_size),
|
"FontSize": float(self.font_size),
|
||||||
"Newline_At": int(self.newline_at),
|
"Newline_At": int(self.newline_at),
|
||||||
|
"Symbol": self.get_symbol(),
|
||||||
}
|
}
|
||||||
return text_data
|
return text_data
|
||||||
|
|
||||||
|
|||||||
@@ -591,6 +591,12 @@ class BIM_PT_text(Panel):
|
|||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(props, "newline_at")
|
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):
|
for i, literal_props in enumerate(props.literals):
|
||||||
box = self.layout.box()
|
box = self.layout.box()
|
||||||
row = self.layout.row(align=True)
|
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:
|
def edit_text(drawing: type[tool.Drawing], obj: bpy.types.Object) -> None:
|
||||||
drawing.synchronise_ifc_and_text_attributes(obj)
|
drawing.synchronise_ifc_and_text_attributes(obj)
|
||||||
drawing.update_text_size_pset(obj)
|
drawing.update_text_size_pset(obj)
|
||||||
drawing.update_newline_at(obj)
|
drawing.update_newline_at_and_symbol(obj)
|
||||||
drawing.disable_editing_text(obj)
|
drawing.disable_editing_text(obj)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ class Drawing:
|
|||||||
def sync_object_placement(cls, obj): pass
|
def sync_object_placement(cls, obj): pass
|
||||||
def synchronise_ifc_and_text_attributes(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_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
|
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_prop)
|
||||||
return repr(bpy_struct)
|
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
|
@classmethod
|
||||||
def resolve_data_path_to_data_attr(cls, data_path: str) -> tuple[bpy.types.bpy_struct, str]:
|
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
|
# 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
|
@classmethod
|
||||||
def get_document_props(cls) -> DocProperties:
|
def get_document_props(cls) -> DocProperties:
|
||||||
assert (scene := bpy.context.scene)
|
assert (scene := bpy.context.scene)
|
||||||
@@ -434,8 +455,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
|
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
|
||||||
props = tool.Drawing.get_text_props(obj)
|
props = tool.Drawing.get_text_props(obj)
|
||||||
props.is_editing = False
|
obj.property_unset(tool.Blender.get_props_attribute_name(props))
|
||||||
props.literals.clear()
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
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)
|
text_data = DecoratorData.get_text_data(obj)
|
||||||
props.font_size = str(text_data["FontSize"])
|
props.font_size = str(text_data["FontSize"])
|
||||||
props.newline_at = text_data["Newline_At"]
|
props.newline_at = text_data["Newline_At"]
|
||||||
|
props.set_symbol(text_data["Symbol"])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def import_assigned_product(cls, obj: bpy.types.Object) -> None:
|
def import_assigned_product(cls, obj: bpy.types.Object) -> None:
|
||||||
@@ -1214,10 +1235,12 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@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)
|
props = cls.get_text_props(obj)
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
newline_at = int(props.newline_at)
|
newline_at = int(props.newline_at)
|
||||||
|
symbol = props.get_symbol()
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
pset = tool.Pset.get_element_pset(element, "EPset_Annotation")
|
pset = tool.Pset.get_element_pset(element, "EPset_Annotation")
|
||||||
if not pset:
|
if not pset:
|
||||||
@@ -1225,7 +1248,10 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
ifcopenshell.api.pset.edit_pset(
|
ifcopenshell.api.pset.edit_pset(
|
||||||
ifc_file,
|
ifc_file,
|
||||||
pset=pset,
|
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
|
# TODO below this point is highly experimental prototype code with no tests
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class TestEditText:
|
|||||||
def test_run(self, drawing):
|
def test_run(self, drawing):
|
||||||
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
|
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
|
||||||
drawing.update_text_size_pset("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()
|
drawing.disable_editing_text("obj").should_be_called()
|
||||||
subject.edit_text(drawing, obj="obj")
|
subject.edit_text(drawing, obj="obj")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user