Panels poliert: Ebenenkombi in Oberleiste, Satelliten-Dialoge, Caps weg, Perf
- Ebenenkombination raus aus Ebenen-Panel, in Oberleiste-Topbar + Editor-Satellite (AusschnittLayerDialog embedded). doc.Strings haelt active_comb_name, auto-clear bei manueller Eye/Lock-Aenderung. - EbenenSettingsDialog jetzt Satellite mit Ebene-Picker-Dropdown (auto-save on switch via SAVE_KEEP). - Per-Ausschnitt Einstellungen-Satellite (Massstab, Display, Overrides, Ebenenkombi). Alte 'Sichtbarkeit bearbeiten'-Option entfernt. - Layouts/Ausschnitte: Top-Header weg, Sticky-Footer mit Anzahl + Aktionen. LayoutDialog ist jetzt Satellite mit Format-Live-Preview. - Panel-Captions + Default-Ebenen-Namen auf Mixed-Case (Ausschnitte, Ebenen, Waende ...). Nur DOSSIER bleibt caps. - DimensionenApp: Card-Optik raus, REF-Wuerfel mit Kreisen statt Quadraten + Hover-Scale. - GeschossManager angeglichen an EbenenManager: Rechtsklick-Menue, Lock-Button, Delete-X, Duplizieren. layer_builder honoriert z.locked. - Active Sublayer folgt jetzt dem Geschoss-Wechsel (gleicher Code unter neuem Parent). Performance Geschoss-Wechsel: - elemente._send_state() ersetzt durch _notify_active_geschoss() (Partial-Push statt 200+ Elements re-enumerieren). - _apply_visibility dedupe via sticky last-applied-signature (STATE_SYNC-Echo loopt nicht mehr durch alle Layer). - _update_clipping nur wenn alt oder neu hasClipping=True. - Redundante doc.Views.Redraw() im CPlane-Pfad entfernt — die folgende apply_visibility-Roundtrip redrawt 30ms spaeter ohnehin. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+151
-2
@@ -334,6 +334,7 @@ class AusschnittBridge(panel_base.BaseBridge):
|
||||
elif t == "UPDATE_LAYERS": self._update_layers(p.get("id"), p.get("layers") or [])
|
||||
elif t == "SAVE_PRESET": self._save_preset(p.get("name"), p.get("layers") or [])
|
||||
elif t == "DELETE_PRESET": self._delete_preset(p.get("name"))
|
||||
elif t == "OPEN_SETTINGS": self._open_settings_window(p.get("id"))
|
||||
|
||||
def _load(self, doc):
|
||||
raw = doc.Strings.GetValue(_STORE_KEY)
|
||||
@@ -537,8 +538,42 @@ class AusschnittBridge(panel_base.BaseBridge):
|
||||
if view is None: return
|
||||
vp = view.ActiveViewport
|
||||
_apply_camera(vp, snap.get("camera"))
|
||||
_apply_layers_global(doc, snap.get("layers", []))
|
||||
# Layer-Sichtbarkeit: bevorzugt die referenzierte Ebenenkombi (live —
|
||||
# zeigt aktuelle Kombi-Definition). Fallback: snap.layers (per-snap
|
||||
# eingefrorener Zustand).
|
||||
kombi = (snap.get("layerCombination") or "").strip()
|
||||
if kombi:
|
||||
try:
|
||||
import rhinopanel
|
||||
rhinopanel.apply_layer_preset_by_name(doc, kombi)
|
||||
except Exception as ex:
|
||||
print("[AUSSCHNITTE] kombi-apply '{}':".format(kombi), ex)
|
||||
_apply_layers_global(doc, snap.get("layers", []))
|
||||
else:
|
||||
_apply_layers_global(doc, snap.get("layers", []))
|
||||
# Eigene Sichtbarkeit → active_comb_name clearen
|
||||
try:
|
||||
import rhinopanel
|
||||
rhinopanel.set_active_comb_name(doc, None)
|
||||
rhinopanel._notify_oberleiste_combs()
|
||||
except Exception: pass
|
||||
_apply_dossier_state(doc, snap.get("dossier") or snap.get("pause") or {})
|
||||
# Overrides: nur anwenden wenn das Snap "applyOverrides" gesetzt hat.
|
||||
# Sonst bleibt der aktuelle User-Override-State unangetastet.
|
||||
if snap.get("applyOverrides"):
|
||||
try:
|
||||
import overrides
|
||||
overrides.set_enabled(doc, bool(snap.get("overridesEnabled")))
|
||||
overrides.set_active_preset(doc, snap.get("overridesPreset") or None)
|
||||
# Oberleiste-Cache invalidieren damit Topbar das neue Preset zeigt
|
||||
try:
|
||||
b = sc.sticky.get("oberleiste_bridge")
|
||||
if b is not None:
|
||||
b._cached_overrides = None
|
||||
b._send_state(force=True)
|
||||
except Exception: pass
|
||||
except Exception as ex:
|
||||
print("[AUSSCHNITTE] overrides-apply:", ex)
|
||||
# Viewport ZUERST umbenennen — der per-Viewport-Massstab in massstab.py
|
||||
# wird unter vp.Name geschluesselt. Erst nach dem Rename schreibt
|
||||
# _apply_scale unter dem neuen Namen, sonst landet der Wert beim alten
|
||||
@@ -703,6 +738,120 @@ class AusschnittBridge(panel_base.BaseBridge):
|
||||
self._store(doc, snaps)
|
||||
self._send_list()
|
||||
|
||||
def _open_settings_window(self, snap_id):
|
||||
"""Oeffnet ein Satelliten-Fenster (Eto.Form + WebView) mit dem
|
||||
Ausschnittseinstellungen-Dialog. Lets User editieren: Massstab,
|
||||
Display-Mode, Overrides, Ebenenkombi."""
|
||||
if not snap_id: return
|
||||
doc = Rhino.RhinoDoc.ActiveDoc
|
||||
snap = next((s for s in self._load(doc) if s.get("id") == snap_id), None)
|
||||
if not snap:
|
||||
print("[AUSSCHNITTE] open_settings: snap nicht gefunden", snap_id)
|
||||
return
|
||||
outer = self
|
||||
bridge_holder = {"form": None, "id": snap_id}
|
||||
|
||||
panel_base.register_and_open("ausschnitte", "AUSSCHNITTE", PANEL_GUID_STR, AusschnittBridge,
|
||||
def _payload():
|
||||
d = Rhino.RhinoDoc.ActiveDoc
|
||||
sn = next((s for s in outer._load(d) if s.get("id") == bridge_holder["id"]), None)
|
||||
if sn is None: sn = {}
|
||||
# Listen fuer Dropdowns
|
||||
display_modes = []
|
||||
try:
|
||||
import oberleiste
|
||||
display_modes = oberleiste._list_display_modes()
|
||||
except Exception as ex:
|
||||
print("[AUSSCHNITTE] display_modes:", ex)
|
||||
overrides_presets = []
|
||||
try:
|
||||
import overrides
|
||||
overrides_presets = [item.get("name") for item in overrides.list_presets() if item.get("name")]
|
||||
except Exception as ex:
|
||||
print("[AUSSCHNITTE] overrides_presets:", ex)
|
||||
layer_kombis = []
|
||||
try:
|
||||
import rhinopanel
|
||||
layer_kombis = rhinopanel.list_layer_preset_names(d)
|
||||
except Exception as ex:
|
||||
print("[AUSSCHNITTE] layer_kombis:", ex)
|
||||
cam = sn.get("camera") or {}
|
||||
return {
|
||||
"snap": {
|
||||
"id": sn.get("id"),
|
||||
"name": sn.get("name"),
|
||||
"scale": sn.get("scale", ""),
|
||||
"displayMode": cam.get("displayMode"),
|
||||
"displayModeName": cam.get("displayModeName"),
|
||||
"applyOverrides": bool(sn.get("applyOverrides", False)),
|
||||
"overridesEnabled": bool(sn.get("overridesEnabled", False)),
|
||||
"overridesPreset": sn.get("overridesPreset") or "",
|
||||
"layerCombination": sn.get("layerCombination") or "",
|
||||
},
|
||||
"displayModes": display_modes,
|
||||
"overridesPresets": overrides_presets,
|
||||
"layerKombis": layer_kombis,
|
||||
}
|
||||
|
||||
def _persist(settings):
|
||||
d = Rhino.RhinoDoc.ActiveDoc
|
||||
snaps = outer._load(d)
|
||||
sid = bridge_holder["id"]
|
||||
target = next((s for s in snaps if s.get("id") == sid), None)
|
||||
if target is None:
|
||||
print("[AUSSCHNITTE] persist settings: snap weg"); return
|
||||
# Massstab
|
||||
sc_val = (settings.get("scale") or "").strip()
|
||||
target["scale"] = sc_val
|
||||
# Display Mode in camera nested
|
||||
cam = target.get("camera") or {}
|
||||
dm_id = settings.get("displayMode")
|
||||
dm_nm = settings.get("displayModeName")
|
||||
if dm_id is not None: cam["displayMode"] = dm_id or None
|
||||
if dm_nm is not None: cam["displayModeName"] = dm_nm or None
|
||||
target["camera"] = cam
|
||||
# Overrides
|
||||
target["applyOverrides"] = bool(settings.get("applyOverrides"))
|
||||
target["overridesEnabled"] = bool(settings.get("overridesEnabled"))
|
||||
target["overridesPreset"] = (settings.get("overridesPreset") or "").strip()
|
||||
# Ebenenkombi
|
||||
target["layerCombination"] = (settings.get("layerCombination") or "").strip()
|
||||
outer._store(d, snaps)
|
||||
outer._send_list()
|
||||
print("[AUSSCHNITTE] Settings fuer '{}' aktualisiert".format(target.get("name")))
|
||||
|
||||
class _AusschnittSettingsBridge(panel_base.BaseBridge):
|
||||
def __init__(self):
|
||||
panel_base.BaseBridge.__init__(self, "ausschnitt_settings")
|
||||
def _on_ready(self):
|
||||
self._send_state()
|
||||
def _send_state(self):
|
||||
self.send("AUSSCHNITT_SETTINGS_STATE", _payload())
|
||||
def handle(self, data):
|
||||
if not isinstance(data, dict): return
|
||||
t = data.get("type", "")
|
||||
p = data.get("payload") or {}
|
||||
if t == "READY":
|
||||
self._on_ready()
|
||||
elif t == "SAVE":
|
||||
_persist(p.get("settings") or {})
|
||||
try:
|
||||
f = bridge_holder.get("form")
|
||||
if f is not None: f.Close()
|
||||
except Exception: pass
|
||||
elif t == "CANCEL":
|
||||
try:
|
||||
f = bridge_holder.get("form")
|
||||
if f is not None: f.Close()
|
||||
except Exception: pass
|
||||
|
||||
b = _AusschnittSettingsBridge()
|
||||
bridge_holder["form"] = panel_base.open_satellite_window(
|
||||
"ausschnitt_settings",
|
||||
params=_payload(),
|
||||
title="Ausschnitt: {}".format(snap.get("name", "")),
|
||||
size=(420, 540),
|
||||
bridge=b)
|
||||
|
||||
|
||||
panel_base.register_and_open("ausschnitte", "Ausschnitte", PANEL_GUID_STR, AusschnittBridge,
|
||||
icon_spec=("crop", "#c87050"))
|
||||
|
||||
Reference in New Issue
Block a user