Files
karim 95031ee2c0 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>
2026-05-19 03:58:28 +02:00

59 lines
1.8 KiB
Python

#! python 3
# -*- coding: utf-8 -*-
"""
werkzeuge.py
WERKZEUGE-Panel: Architektur-orientierte Toolbar als React-WebView.
Feuert Rhino-Befehle via RunScript bei Button-Klick.
"""
import os
import sys
import Rhino
import scriptcontext as sc
_HERE = os.path.dirname(os.path.abspath(__file__))
if _HERE not in sys.path:
sys.path.insert(0, _HERE)
import panel_base
PANEL_GUID_STR = "6d9f5040-7e1f-4f2b-c4d5-f6071829304a"
class WerkzeugeBridge(panel_base.BaseBridge):
def __init__(self):
panel_base.BaseBridge.__init__(self, "werkzeuge")
def _on_ready(self):
# Keine initialen Daten noetig — Toolbar ist statisch
pass
def handle(self, data):
if not isinstance(data, dict): return
t = data.get("type", "")
p = data.get("payload") or {}
if not isinstance(p, dict): p = {}
if t == "READY":
self._on_ready()
elif t == "RUN":
cmd = p.get("cmd")
if cmd and isinstance(cmd, str):
# Whitelist: alles muss mit "_" beginnen (Rhino-Befehl) und
# darf keine Zeilenumbrueche oder Semikolons enthalten.
cmd = cmd.strip()
if cmd.startswith("_") and "\n" not in cmd and ";" not in cmd:
try:
Rhino.RhinoApp.RunScript(cmd, False)
print("[WERKZEUGE] {}".format(cmd))
except Exception as ex:
print("[WERKZEUGE] RunScript-Fehler:", ex)
else:
print("[WERKZEUGE] Befehl ignoriert (kein '_' Praefix oder unsicher):", cmd)
def _bridge_factory():
return WerkzeugeBridge()
panel_base.register_and_open("werkzeuge", "Werkzeuge", PANEL_GUID_STR, _bridge_factory,
icon_spec=("build", "#3a6fa8"))