User-Wunsch: das '+' im Zeichnungsebenen-Panel soll standardmaessig
eine NICHT-Geschoss-Zeichnung anlegen (z.B. Bemassung, Plangrafik,
Möblierung). Wer ein Geschoss will:
- Row-Settings-Cog -> isGeschoss umschalten, ODER
- Bearbeiten-Dialog (Pencil) -> Geschoss direkt anlegen
addQuick erstellt jetzt {isGeschoss: false, name: 'Zeichnung N'}.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Symptom: erster +-Klick hat funktioniert, alle weiteren nicht (kein
APPLY im Log). Diagnose: macOS WKWebView in Rhino blockiert
WIEDERHOLTE window.prompt-Aufrufe — der erste zeigt einen Dialog,
nachfolgende returnen direkt null. Mein `if (!name) return`
beendet dann ohne Add → kein APPLY → User sieht nichts.
Plus: das nach Anlegen direkt onActiveChange(code) erzeugte einen
SET_ACTIVE_LAYER race (Layer war noch nicht durch build_layers
erstellt → Warning "Sublayer mit Code X nicht gefunden").
Beide Probleme weg durch:
- EbenenManager.addNew: silent append mit Default-Name "NEU",
Code-Feld bekommt autoEdit-Fokus → User kann direkt tippen,
Tab springt zum Name-Feld. Code = nextFreeAfter(activeCode) bleibt
(eine nach der aktiven).
- GeschossManager.addQuick: silent append mit Default-Name
"NOG" (basiert auf Anzahl Geschosse), kein onActiveChange.
User editiert ueber den Geschoss-Settings-Cog am Row falls
noetig.
Tradeoff: keine Dialog-Bestätigung mehr wie ursprünglich vom User
gewünscht — aber dafür funktioniert's überhaupt. Falls Dialog
wieder gewünscht, müsste ein React-Modal statt window.prompt her.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wahrscheinliche Wurzel von "kann nicht erstellen": neue Ebene
wurde zwar zur Liste hinzugefuegt, aber nicht aktiv markiert
→ keine Pill-Highlight → User sah sie nicht (vor allem wenn sie
am Listen-Ende auftauchte) und dachte es funktioniert nicht.
Fix: nach addNew/addQuick `onActiveChange(code|id)` aufrufen.
Die neue Ebene wird in der Liste als aktiv markiert (Pill-Highlight),
ist sofort auffaellig + neue Geometrie landet direkt darauf.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Feature: neue Ebenen kriegen jetzt einen Code direkt nach dem
aktuell angewaehlten (z.B. active="20" → "21" oder naechste freie
darunter). Vorher war's Max+1 → sprang auf "100", neue Ebene landet
am Listen-Ende und wirkte „unsichtbar" weil weit unten.
Debug-Logs eingebaut um zu diagnostizieren warum Anlegen aus User-
Sicht nicht funktioniert:
- [EBENEN-UI] addNew → bei jedem Click + im Ebenen-Panel
- [ZEICHNUNGSEBENEN-UI] addQuick → bei jedem Click + im Z-Panel
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] structureKey diff → wenn der
Auto-Apply-useEffect feuert
- [EBENEN-UI/ZEICHNUNGSEBENEN-UI] applyAll firing now → wenn der
Debounce-Timer am Ende den Backend-Call macht
- [EBENEN-BE] APPLY from mode=X → Backend-Receiver
- [EBENEN-BE] mode=X: y from doc.Strings n=N → was aus doc.Strings
als Fallback geladen wurde
So sehen wir wo's stockt — UI feuert nicht, Debounce klemmt,
Backend kriegt's nicht, oder build_layers schmeisst still.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
UX-Beschwerde: addNew/addQuick haben still im Hintergrund eine Ebene
am Listenende hinzugefuegt. User sah das Ergebnis nicht weil scroll-
abhaengig oder ueberhaupt — "kann gar nicht erstellen". Bei Ebenen-
Kombinationen geht's via window.prompt, das ist klar.
Beide auf gleiche Prompt-UX umgebaut:
EbenenManager.addNew:
- Prompt "Name für neue Ebene:" mit Default "NEU"
- Bei Cancel/leer: kein Add
- Bei OK: Ebene mit UPPERCASE-Name + auto-generiertem Code, Code-
Feld bekommt sofort den Edit-Mode (User kann ihn schnell anpassen).
GeschossManager.addQuick:
- Prompt "Name für neue Zeichnungsebene (Geschoss):" mit Default
basiert auf Anzahl Geschosse (z.B. "3OG" wenn 2 vorhanden).
- Bei OK: neuer Eintrag als Geschoss (isGeschoss=true) mit hoehe=3.0
und schnitthoehe=1.0 — die Default-Werte. Wegen recalcOkff zeigt
er automatisch das richtige OKFF.
Vorher war addQuick auf `isGeschoss=false` (= Beschriftungs-Eintrag,
kein Geschoss), das war ein Konventions-Mismatch zur User-Erwartung.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Der Section-Header mit dem Panel-Namen ("Ebenen" / "Zeichnungsebenen")
war redundant — der Panel-Tab in Rhino hat den Namen schon. Stattdessen
direkt mit der Sichtbarkeit-Dropdown beginnen.
EbenenManager:
- `<Section>`-Wrapper entfernt, Section-Import raus.
- "+"-Button neben der Sichtbarkeit-Dropdown (flex: 1).
GeschossManager:
- Gleich. "+"- und Edit-Buttons (Bleistift) neben der Sichtbarkeit-
Dropdown.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
App.jsx ruft jetzt `applyVisibility(null, [], activeCode, ebenen, null, eMode)`
— die fremde Slice ist leer/null weil das Panel sie nicht besitzt. Das
crashte mit "Cannot read properties of null (reading 'id')" weil der Code
`a.activeZ.id` blind dereferenzierte. Resultat: "Script error." in
window.onerror → leere Panel-UI.
Fix: Array.isArray-Guard + null-Check fuer activeZ. Backend mergt
fehlende Felder mit doc.Strings.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
UX: Geschoss-Liste und globale Layer-Liste lebten bisher in einem
Panel und mussten beide gescrollt werden. Jetzt zwei getrennte Tabs.
Backend (rhino/rhinopanel.py):
- Selbe EbenenBridge-Klasse, zwei Mode-Instanzen ("ebenen" +
"zeichnungsebenen"). Beide registrieren sich in sticky-Slots
(`ebenen_bridge_ref` / `zeichnungsebenen_bridge_ref`).
- `_broadcast_state(doc)` Helper: liest aktuell Zustand aus doc.Strings
und schickt STATE_SYNC an beide Bridges. Wird nach jeder state-
aendernden Aktion gefeuert (apply, set_active_zeichnungsebene,
toggle_clipping, remove/update ebene, layer-table-event).
- `handle(APPLY)`: wenn nur eine Slice (z oder e) im Payload, fehlende
aus doc.Strings nachladen → Backend baut mit vollem Zustand.
- `_apply_visibility`: zMode/eMode/activeId/activeCode aus Payload
ODER aus doc.Strings (dossier_z_mode/dossier_e_mode/dossier_active_id/
dossier_active_code) faellen lassen — Split-Sends werden korrekt
gemergt.
- Layer-Table-Event broadcastet jetzt statt nur das eine Panel zu
benachrichtigen.
- Zweite `register_and_open("zeichnungsebenen", ...)` Zeile mit eigener
GUID + Icon "levels".
Frontend:
- Neues src/ZeichnungsebenenApp.jsx: enthaelt nur GeschossManager,
haelt Zeichnungsebenen + activeId + zMode lokal, schickt
applyAll([z], []) und applyVisibility mit leerer Ebenen-Slice.
- src/App.jsx geschrumpft: nur noch EbenenManager + AusschnittLayer-
Dialog. Haelt Ebenen + activeCode + eMode + Combinations. Schickt
applyAll([], [e]) und applyVisibility mit leerer Z-Slice.
- src/main.jsx: neuer case fuer mode="zeichnungsebenen" → lädt
ZeichnungsebenenApp.
Existierende User mit altem DOSSIERUI.rhw Workspace muessen das neue
Panel einmal manuell oeffnen (Rechtsklick Panel-Area → Panel hinzu-
fuegen → "Zeichnungsebenen"); Rhino persistiert die Anordnung danach.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Stable working state after a long iteration session. The plugin now supports:
- Multi-Surface-Select für alle Element-Typen (Türen/Fenster/Treppen/Tragwerk)
- Wand-Z-Drag → unbound mode (UK/OK-Override, Wand vom Geschoss entkoppelt)
- Wand-Z-Drag nimmt verknüpfte Öffnungen mit (Brüstung += delta_z via Idle-Pfad)
- Öffnungs-XY-Drag snapt direktional auf Wand-Tangente
- Öffnungs-Z-Drag passt Brüstung an (Fenster sofort sync, Tür deferred)
- Wand-Delete kaskadiert Öffnungen (deferred via Idle, robust gegen _Rotate/_Move)
- Source-Cascade beim Öffnungs-Delete (deferred analog Wand-Kaskade)
- Listener-Cleanup robust gegen _reset_panels.py Reload (Refs in
_dossier_runtime_event_refs gespeichert, vor Re-Install deregistriert)
- _count_same_id_type filtert IsDeleted (verhindert Source-Duplikat-Bug bei Move)
- Frontend: Brüstungs-Slider für Tür ("Schwelle"), Flügel-Block nur bei Fenster
Plus aus früherer Phase dieser Session:
- Dossier-Launcher Auto-Load via Rhinos StartupCommands-XML
- Default-Pfad zeigt auf gebundeltes startup.py (out-of-the-box für neue User)
- Splash-Window beim Plugin-Load mit native macOS rounded corners
- Diverse Launcher-Verbesserungen (Brüstungs-Default, tauri.conf, capabilities)
Known issue: bei Multi-Select-Move mit vielen Sub-Volumen kann sporadisch
"Unable to transform" auftreten (Rhinos Move-Operation kollidiert mit Wand-
Regen). Tür-spezifischer Defer-Pfad mildert das, Fenster läuft sync.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>