Raumstempel-Stile: Active-Stil-Tracking

UserString dossier_raum_stil_id auf der raum_outline. Wird gesetzt:
- bei APPLY_RAUM_STIL → schreibt sid auf alle Ziel-Raeume
- bei SAVE_RAUM_STIL mit applyToIds=[…] → schreibt neue sid auf
  uebergebene Raeume (Frontend nutzt das beim "+ Speichern…"-Flow um
  den aktuellen Raum mit dem neuen Stil zu verknuepfen)

_read_meta liest stil_id mit → State-Emit feldet "stilId" zum Raum.
Frontend's Stil-Dropdown markiert dadurch automatisch den aktiven Stil
(via activeStilId = raum.stilId).

Manuelle Edits (UPDATE_ELEMENT) touchen stil_id NICHT — User kann
seinen Stil leicht tweaken ohne dass die Verknuepfung verloren geht.
Wenn der Tweak weit weg ist, kann er den Stil aktualisieren via
"+ Aktuelle Settings als Stil speichern" (uebernimmt dann mit der
NEUEN stil_id).
This commit is contained in:
2026-05-26 23:23:42 +02:00
parent 3c28d2e29c
commit eff0878f53
3 changed files with 40 additions and 5 deletions
+36 -2
View File
@@ -332,6 +332,9 @@ _RAUM_LAYOUT_DEFAULT = [["nummer", "name"], ["funktion"], ["area"]]
# Per-Document Storage-Key fuer Raumstempel-Stile (Presets). # Per-Document Storage-Key fuer Raumstempel-Stile (Presets).
_KEY_RAUM_STILE = "dossier_raum_stempel_stile" _KEY_RAUM_STILE = "dossier_raum_stempel_stile"
# Auf der Raum-Outline: id des zuletzt angewendeten Stils. Damit das UI
# anzeigen kann welcher Stil aktiv ist.
_KEY_RAUM_STIL_ID = "dossier_raum_stil_id"
# Felder die ein Stil persistiert (= alles was die Optik bestimmt). Nicht # Felder die ein Stil persistiert (= alles was die Optik bestimmt). Nicht
# enthalten: Name/Nummer/Funktion (inhaltlich pro Raum), area/umfang (aus # enthalten: Name/Nummer/Funktion (inhaltlich pro Raum), area/umfang (aus
@@ -3075,6 +3078,8 @@ def _read_meta(obj):
# Texthoehen-Modus (default "fix" — Backwards-Compat) # Texthoehen-Modus (default "fix" — Backwards-Compat)
r_txt_modus = a.GetUserString(_KEY_RAUM_TXT_MODUS) or "fix" r_txt_modus = a.GetUserString(_KEY_RAUM_TXT_MODUS) or "fix"
if r_txt_modus not in ("fix", "masstab"): r_txt_modus = "fix" if r_txt_modus not in ("fix", "masstab"): r_txt_modus = "fix"
# Aktiver Stempel-Stil (id des zuletzt applizierten Stils)
r_stil_id = a.GetUserString(_KEY_RAUM_STIL_ID) or ""
# Field-Layout — parsed JSON list of rows # Field-Layout — parsed JSON list of rows
r_layout_raw = a.GetUserString(_KEY_RAUM_LAYOUT) or "" r_layout_raw = a.GetUserString(_KEY_RAUM_LAYOUT) or ""
r_layout = [] r_layout = []
@@ -3196,6 +3201,7 @@ def _read_meta(obj):
"raum_stamp_dy": r_stamp_dy, "raum_stamp_dy": r_stamp_dy,
"raum_layout": r_layout, "raum_layout": r_layout,
"raum_txt_modus": r_txt_modus, "raum_txt_modus": r_txt_modus,
"raum_stil_id": r_stil_id,
"wand_layered": w_layered, "wand_layered": w_layered,
"wand_layers": w_layers, "wand_layers": w_layers,
"wand_layer_idx": w_layer_idx, "wand_layer_idx": w_layer_idx,
@@ -6661,6 +6667,7 @@ class ElementeBridge(panel_base.BaseBridge):
"showSia": bool(meta.get("raum_show_sia", False)), "showSia": bool(meta.get("raum_show_sia", False)),
"layout": meta.get("raum_layout") or [], "layout": meta.get("raum_layout") or [],
"txtModus": meta.get("raum_txt_modus", "fix"), "txtModus": meta.get("raum_txt_modus", "fix"),
"stilId": meta.get("raum_stil_id", ""),
"area": area, "area": area,
"areaFmt": _format_area(area, rnd_eff), "areaFmt": _format_area(area, rnd_eff),
"umfang": perim, "umfang": perim,
@@ -8537,8 +8544,11 @@ class ElementeBridge(panel_base.BaseBridge):
def _cmd_save_raum_stil(self, p): def _cmd_save_raum_stil(self, p):
"""Speichert einen Raumstempel-Stil. Payload: """Speichert einen Raumstempel-Stil. Payload:
{id?: string, name: string, settings: {font, bold, italic, txtH, {id?: string, name: string, settings: {font, bold, italic, txtH,
txtModus, align, rundung, fuellung, showSia, layout}} txtModus, align, rundung, fuellung, showSia, layout},
Wenn id leer neuer Stil mit uuid. State-Emit anschliessend. applyToIds?: [raum_id, ...]}
Wenn id leer neuer Stil mit uuid. applyToIds optional: nach dem
Speichern wird stil_id auf die genannten Raeume geschrieben (damit
Frontend "Stil aktiv" anzeigen kann). State-Emit anschliessend.
""" """
doc = Rhino.RhinoDoc.ActiveDoc doc = Rhino.RhinoDoc.ActiveDoc
if doc is None: return if doc is None: return
@@ -8563,6 +8573,20 @@ class ElementeBridge(panel_base.BaseBridge):
if save_raum_stempel_stile(doc, stile): if save_raum_stempel_stile(doc, stile):
print("[ELEMENTE] Stempel-Stil '{}' ({}) gespeichert".format( print("[ELEMENTE] Stempel-Stil '{}' ({}) gespeichert".format(
name, sid)) name, sid))
# Apply to listed rooms — schreibt nur stilId, nicht die Settings
# (die sind ja schon am Raum, sonst waeren sie nicht gespeichert
# worden — wir spiegeln nur die Verknuepfung).
apply_to = p.get("applyToIds") or []
if isinstance(apply_to, list):
for eid in apply_to:
try:
src_obj, _src_meta = _find_source(doc, eid)
if src_obj is None: continue
attrs = src_obj.Attributes.Duplicate()
attrs.SetUserString(_KEY_RAUM_STIL_ID, sid)
doc.Objects.ModifyAttributes(src_obj.Id, attrs, True)
except Exception as ex:
print("[ELEMENTE] save-stil apply-to {}: {}".format(eid, ex))
self._send_state() self._send_state()
def _cmd_delete_raum_stil(self, p): def _cmd_delete_raum_stil(self, p):
@@ -8604,6 +8628,16 @@ class ElementeBridge(panel_base.BaseBridge):
patch = dict(patch_base) patch = dict(patch_base)
patch["id"] = eid patch["id"] = eid
self._update_wall(patch) self._update_wall(patch)
# Stil-Id direkt auf die Outline schreiben damit UI
# markieren kann welcher Stil aktiv ist
try:
src_obj, _src_meta = _find_source(doc, eid)
if src_obj is not None:
attrs = src_obj.Attributes.Duplicate()
attrs.SetUserString(_KEY_RAUM_STIL_ID, sid)
doc.Objects.ModifyAttributes(src_obj.Id, attrs, True)
except Exception as ex:
print("[ELEMENTE] write stil_id on {}: {}".format(eid, ex))
n_applied += 1 n_applied += 1
except Exception as ex: except Exception as ex:
print("[ELEMENTE] apply stil {} -> {}: {}".format(sid, eid, ex)) print("[ELEMENTE] apply stil {} -> {}: {}".format(sid, eid, ex))
+1 -1
View File
@@ -908,7 +908,7 @@ function RaumProperties({ raum, geschosse, onUpdate, onDelete, hatchPatterns, fo
fuellung: raum.fuellung || '', fuellung: raum.fuellung || '',
showSia: !!raum.showSia, showSia: !!raum.showSia,
layout: Array.isArray(raum.layout) ? raum.layout : [], layout: Array.isArray(raum.layout) ? raum.layout : [],
}) }, [raum.id]) // direkt aktuellen Raum mit der neuen Stil-ID verknuepfen
return return
} }
if (val === '__delete__') { if (val === '__delete__') {
+3 -2
View File
@@ -244,8 +244,9 @@ export function saveOeffStyle(name, settings) {
} }
export function deleteOeffStyle(id) { send('DELETE_OEFF_STYLE', { id }) } export function deleteOeffStyle(id) { send('DELETE_OEFF_STYLE', { id }) }
// Raumstempel-Stile (Presets pro Doc) // Raumstempel-Stile (Presets pro Doc)
export function saveRaumStil(id, name, settings) { export function saveRaumStil(id, name, settings, applyToIds) {
send('SAVE_RAUM_STIL', { id, name, settings }) send('SAVE_RAUM_STIL', { id, name, settings,
applyToIds: applyToIds || [] })
} }
export function deleteRaumStil(id) { send('DELETE_RAUM_STIL', { id }) } export function deleteRaumStil(id) { send('DELETE_RAUM_STIL', { id }) }
export function applyRaumStil(stilId, ids) { export function applyRaumStil(stilId, ids) {