Settings-Dialoge in echten Rhino-Fenstern (Eto.Form + WebView)
Statt Overlay-im-Panel oeffnet sich der Settings-Dialog jetzt als echtes Rhino-Fenster (verschiebbar, resizable, mehrere parallel). Infrastruktur in panel_base.py: - load_inline akzeptiert jetzt `params` (dict) und injiziert sie als window.PANEL_PARAMS — Satelliten-Apps lesen ihren initialen State daraus. - Neue Funktion open_satellite_window(mode, params, title, size, on_save, on_cancel): erstellt Eto.Forms.Form mit eingebetteter WebView, eigenem Inline-Bridge fuer SAVE/CANCEL-Messages, ruft Callbacks auf und schliesst das Fenster. Backend rhinopanel.py: - Neue Message-Handler OPEN_GESCHOSS_SETTINGS und OPEN_EBENEN_SETTINGS. - _open_geschoss_settings: oeffnet das Satelliten-Fenster mit dem Geschoss als Payload. on_save: replace im doc.Strings z-Liste + _apply(save_z=True). - _open_ebenen_settings: gleich, aber fuer Ebene + hatchPatterns. Neue React-Entries: - GeschossSettingsApp.jsx: wrappt GeschossSettingsDialog, liest window.PANEL_PARAMS, schickt SAVE/CANCEL direkt via document.title- Bridge. - EbenenSettingsApp.jsx: gleich fuer EbenenSettingsDialog. main.jsx-Switch erweitert um 'geschoss_settings' und 'ebenen_settings'. GeschossManager und EbenenManager: - Inline-Dialog-State und -Rendering entfernt. - onSettings ruft jetzt openGeschossSettings(z) / openEbenenSettings(e) in der Bridge auf → Backend oeffnet das Satelliten-Fenster. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -216,9 +216,89 @@ class EbenenBridge(panel_base.BaseBridge):
|
||||
elif t == "DELETE_PRESET":
|
||||
self._delete_preset(p.get("name") or "")
|
||||
self._send_combination()
|
||||
elif t == "OPEN_GESCHOSS_SETTINGS":
|
||||
self._open_geschoss_settings(p.get("geschoss") or {})
|
||||
elif t == "OPEN_EBENEN_SETTINGS":
|
||||
self._open_ebenen_settings(p.get("ebene") or {},
|
||||
p.get("hatchPatterns") or [])
|
||||
|
||||
# ---- Helpers ----
|
||||
|
||||
def _open_geschoss_settings(self, geschoss):
|
||||
"""Oeffnet ein echtes Rhino-Fenster (Eto.Form mit WebView) mit dem
|
||||
GeschossSettingsDialog. Save updated den Eintrag in doc.Strings +
|
||||
triggert Cross-Panel-Sync."""
|
||||
if not isinstance(geschoss, dict) or not geschoss.get("id"):
|
||||
print("[EBENEN] open_geschoss_settings: kein Geschoss-Payload")
|
||||
return
|
||||
gid = geschoss["id"]
|
||||
def on_save(updated):
|
||||
doc = Rhino.RhinoDoc.ActiveDoc
|
||||
if doc is None: return
|
||||
z_raw = doc.Strings.GetValue("dossier_zeichnungsebenen")
|
||||
if not z_raw:
|
||||
print("[EBENEN] save_geschoss: kein z-Store"); return
|
||||
try:
|
||||
z_list = json.loads(z_raw)
|
||||
except Exception as ex:
|
||||
print("[EBENEN] save_geschoss JSON:", ex); return
|
||||
replaced = False
|
||||
for i, z in enumerate(z_list):
|
||||
if isinstance(z, dict) and z.get("id") == gid:
|
||||
z_list[i] = updated
|
||||
replaced = True
|
||||
break
|
||||
if not replaced:
|
||||
print("[EBENEN] save_geschoss: id {} nicht gefunden".format(gid))
|
||||
return
|
||||
# Build_layers + Save via _apply (durchlaeuft ohne save_e)
|
||||
e_raw = doc.Strings.GetValue("dossier_ebenen")
|
||||
try: e_list = json.loads(e_raw) if e_raw else []
|
||||
except Exception: e_list = []
|
||||
self._apply(z_list, e_list, save_z=True, save_e=False)
|
||||
panel_base.open_satellite_window(
|
||||
"geschoss_settings",
|
||||
params=geschoss,
|
||||
title="Zeichnungsebene: {}".format(geschoss.get("name", "")),
|
||||
size=(380, 540),
|
||||
on_save=on_save)
|
||||
|
||||
def _open_ebenen_settings(self, ebene, hatch_patterns):
|
||||
"""Oeffnet ein echtes Rhino-Fenster mit dem EbenenSettingsDialog."""
|
||||
if not isinstance(ebene, dict) or not ebene.get("code"):
|
||||
print("[EBENEN] open_ebenen_settings: kein Ebene-Payload")
|
||||
return
|
||||
old_code = ebene["code"]
|
||||
def on_save(updated):
|
||||
doc = Rhino.RhinoDoc.ActiveDoc
|
||||
if doc is None: return
|
||||
e_raw = doc.Strings.GetValue("dossier_ebenen")
|
||||
if not e_raw:
|
||||
print("[EBENEN] save_ebene: kein e-Store"); return
|
||||
try:
|
||||
e_list = json.loads(e_raw)
|
||||
except Exception as ex:
|
||||
print("[EBENEN] save_ebene JSON:", ex); return
|
||||
replaced = False
|
||||
for i, e in enumerate(e_list):
|
||||
if isinstance(e, dict) and e.get("code") == old_code:
|
||||
e_list[i] = updated
|
||||
replaced = True
|
||||
break
|
||||
if not replaced:
|
||||
print("[EBENEN] save_ebene: code {} nicht gefunden".format(old_code))
|
||||
return
|
||||
z_raw = doc.Strings.GetValue("dossier_zeichnungsebenen")
|
||||
try: z_list = json.loads(z_raw) if z_raw else []
|
||||
except Exception: z_list = []
|
||||
self._apply(z_list, e_list, save_z=False, save_e=True)
|
||||
panel_base.open_satellite_window(
|
||||
"ebenen_settings",
|
||||
params={"ebene": ebene, "hatchPatterns": hatch_patterns},
|
||||
title="Ebene: {}_{}".format(ebene.get("code", ""), ebene.get("name", "")),
|
||||
size=(420, 600),
|
||||
on_save=on_save)
|
||||
|
||||
def _apply(self, zeichnungsebenen, ebenen, save_z=True, save_e=True):
|
||||
print("[EBENEN] _apply START z={} e={} (save_z={} save_e={})".format(
|
||||
len(zeichnungsebenen) if zeichnungsebenen else 0,
|
||||
|
||||
Reference in New Issue
Block a user