Overrides als Satelliten-Fenster vom Oberleiste-Gear öffnen
OVERRIDES war als gedocktes Panel zu schmal. Jetzt: kein Panel mehr, sondern ein echtes Rhino-Fenster (Eto.Form + WebView, frei verschieb- und resizable), das vom Oberleiste-Gear-Button geoeffnet wird. panel_base.open_satellite_window: - Akzeptiert jetzt optional einen `bridge`-Parameter. Wenn gegeben, wird die Custom-Bridge (z.B. OverridesBridge) statt der einfachen inline SAVE/CANCEL-Bridge benutzt. So koennen vollwertige Panels (mit bidirektionalem Mess-Verkehr) als Satellite-Fenster laufen. overrides_panel.py: - register_and_open entfaellt — Overrides wird nicht mehr als Panel registriert. - Neue Funktion open_as_window(): erstellt OverridesBridge, registriert sie in sticky["overrides_bridge"] und oeffnet als Satellite-Window. Listener werden lazy beim ersten Aufruf installiert (_ensure_listeners_once). oberleiste.py: - OPEN_OVERRIDES_PANEL ruft jetzt overrides_panel.open_as_window() statt RhinoUI.Panels.OpenPanel(). OberleisteApp.jsx: - Settings-Gear (ToolButton mit icon="settings") nach dem Preset- Dropdown im Overrides-Bereich. Click ruft openOverridesPanel() → oeffnet das Satelliten-Fenster. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+3
-4
@@ -915,11 +915,10 @@ class OberleisteBridge(panel_base.BaseBridge):
|
||||
print("[OBERLEISTE] notify overrides:", ex)
|
||||
elif t == "OPEN_OVERRIDES_PANEL":
|
||||
try:
|
||||
import System
|
||||
import Rhino.UI as RhinoUI
|
||||
RhinoUI.Panels.OpenPanel(System.Guid(OVERRIDES_PANEL_GUID_STR))
|
||||
import overrides_panel
|
||||
overrides_panel.open_as_window()
|
||||
except Exception as ex:
|
||||
print("[OBERLEISTE] OpenPanel Overrides:", ex)
|
||||
print("[OBERLEISTE] open_as_window Overrides:", ex)
|
||||
|
||||
# --- Command-Line Integration -----------------------------------
|
||||
elif t == "RUN_COMMAND":
|
||||
|
||||
@@ -211,16 +211,37 @@ class OverridesBridge(panel_base.BaseBridge):
|
||||
self._send_state()
|
||||
|
||||
|
||||
def _bridge_factory():
|
||||
def _ensure_listeners_once():
|
||||
"""Overrides-Listener nur EINMAL global installieren (statt bei jedem
|
||||
open_as_window)."""
|
||||
if sc.sticky.get("overrides_listeners_installed"):
|
||||
return
|
||||
try:
|
||||
overrides.install_listeners()
|
||||
sc.sticky["overrides_listeners_installed"] = True
|
||||
except Exception as ex:
|
||||
print("[OVERRIDES] install_listeners:", ex)
|
||||
|
||||
|
||||
def open_as_window():
|
||||
"""Oeffnet OVERRIDES als echtes Rhino-Fenster (Eto.Form + WebView).
|
||||
Wird vom Oberleiste-Bridge bei OPEN_OVERRIDES_PANEL gerufen.
|
||||
|
||||
Pro Fenster eine eigene OverridesBridge-Instanz. Die letzte Instanz
|
||||
landet in sticky["overrides_bridge"] — andere Panels (Oberleiste) die
|
||||
Cross-Updates an Overrides senden, treffen das aktive Fenster."""
|
||||
_ensure_listeners_once()
|
||||
b = OverridesBridge()
|
||||
try: overrides.install_listeners()
|
||||
except Exception as ex: print("[OVERRIDES] install_listeners:", ex)
|
||||
# Bridge im sticky ablegen, damit andere Panels (z.B. Oberleiste) sie
|
||||
# bei Cross-Panel-Updates erreichen koennen.
|
||||
sc.sticky["overrides_bridge"] = b
|
||||
return b
|
||||
panel_base.open_satellite_window(
|
||||
"overrides",
|
||||
title="OVERRIDES",
|
||||
size=(760, 580),
|
||||
bridge=b)
|
||||
|
||||
|
||||
panel_base.register_and_open("overrides", "OVERRIDES", PANEL_GUID_STR, _bridge_factory,
|
||||
icon_spec=("tune", "#b5621e"),
|
||||
min_size=(720, 560))
|
||||
# OVERRIDES laeuft jetzt als Satelliten-Fenster (geoeffnet vom Oberleiste-
|
||||
# Gear-Button), nicht mehr als gedocktes Panel. Listener werden lazy beim
|
||||
# ersten open_as_window installiert. Falls jemand das alte Panel via
|
||||
# Workspace-Layout noch geoeffnet hat, wird es nicht mehr registriert →
|
||||
# Rhino zeigt es leer / nicht mehr an.
|
||||
|
||||
+12
-10
@@ -281,16 +281,20 @@ def attach_webview(panel, bridge, mode):
|
||||
# --- Satelliten-Fenster (echtes Rhino-Fenster mit eingebetteter WebView) ----
|
||||
|
||||
def open_satellite_window(mode, params=None, title=None, size=(420, 560),
|
||||
on_save=None, on_cancel=None):
|
||||
on_save=None, on_cancel=None, bridge=None):
|
||||
"""Oeffnet ein echtes Rhino-Fenster (Eto.Form) mit eingebetteter WebView.
|
||||
Die WebView laedt die React-App mit dem gegebenen `mode` und `params`.
|
||||
|
||||
Die React-App sendet via Bridge `SAVE`/`CANCEL`-Messages. Wir rufen
|
||||
dann die jeweilige Callback-Funktion auf (mit dem Save-Payload) und
|
||||
schliessen das Fenster.
|
||||
Zwei Bridge-Modi:
|
||||
- **Default (kein `bridge`-Arg):** inline SAVE/CANCEL-Bridge. React
|
||||
sendet SAVE/CANCEL → on_save/on_cancel-Callback → Fenster zu. Fuer
|
||||
einfache One-Shot-Dialoge (Settings etc.).
|
||||
- **`bridge` uebergeben:** eine vollwertige BaseBridge-Subklasse (z.B.
|
||||
OverridesBridge). Das Fenster nutzt die wie ein normales Panel,
|
||||
mit allen Mess-Typen die der Bridge handlet. Save/Cancel sind dort
|
||||
nicht standard; Fenster bleibt offen bis User es manuell schliesst.
|
||||
|
||||
Returns die Form-Instance (User kann sie speichern um sie spaeter
|
||||
programmatisch zu schliessen)."""
|
||||
Returns die Form-Instance."""
|
||||
|
||||
form = forms.Form()
|
||||
if title is None: title = mode.replace('_', ' ').title()
|
||||
@@ -303,7 +307,8 @@ def open_satellite_window(mode, params=None, title=None, size=(420, 560),
|
||||
|
||||
wv = forms.WebView()
|
||||
|
||||
# Inline-Bridge fuer Satelliten-Fenster: handle SAVE/CANCEL, schliesse
|
||||
if bridge is None:
|
||||
# Inline-Bridge fuer einfache Settings-Dialoge: SAVE/CANCEL, schliesse
|
||||
# bei beiden das Fenster.
|
||||
class _SatelliteBridge(BaseBridge):
|
||||
def __init__(self):
|
||||
@@ -312,8 +317,6 @@ def open_satellite_window(mode, params=None, title=None, size=(420, 560),
|
||||
t = data.get("type", "")
|
||||
p = data.get("payload") or {}
|
||||
if t == "READY":
|
||||
# React liest PANEL_PARAMS direkt vom window-Object — wir
|
||||
# muessen also nichts mehr aktiv senden.
|
||||
pass
|
||||
elif t == "SAVE":
|
||||
if on_save is not None:
|
||||
@@ -328,7 +331,6 @@ def open_satellite_window(mode, params=None, title=None, size=(420, 560),
|
||||
except Exception: pass
|
||||
try: form.Close()
|
||||
except Exception: pass
|
||||
|
||||
bridge = _SatelliteBridge()
|
||||
bridge.set_webview(wv)
|
||||
|
||||
|
||||
@@ -374,6 +374,11 @@ export default function OberleisteApp() {
|
||||
<option disabled>──────────</option>
|
||||
<option value="__configure__">Konfigurieren…</option>
|
||||
</select>
|
||||
<ToolButton
|
||||
onClick={openOverridesPanel}
|
||||
icon="settings"
|
||||
title="Overrides-Regel-Editor öffnen"
|
||||
/>
|
||||
|
||||
{/* Spacer am rechten Rand */}
|
||||
<div style={{ flex: 1 }} />
|
||||
|
||||
Reference in New Issue
Block a user