Commit Graph

8 Commits

Author SHA1 Message Date
karim 1ba0bda429 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>
2026-05-19 01:15:12 +02:00
karim fcbc97b608 Ebene-Add Race: SET_VISIBILITY-Roundtrip cancelt APPLY → neuer Eintrag weg
Root-Cause für 'Ebene erscheint kurz und verschwindet wieder, kein
APPLY im PY-Log':

1. User klickt + → addNew. setEbenen(18 Eintraege). state local = 18.
2. visibilityKey aendert sich (ebenen-Aenderung) → applyVisibility
   debounced 30ms.
3. structureKey aendert sich → applyAll debounced 200ms.
4. T=30ms: SET_VISIBILITY landet beim Backend ZUERST.
5. `_apply_visibility` liest e_full (17 alte Eintraege) aus
   doc.Strings, merged Visibility-Flags vom Slim-Payload, schreibt
   die 17 ALTEN zurueck nach doc.Strings (der neue 18. Eintrag ist
   im merged-Loop nicht dabei weil iteriert ueber e_full).
6. broadcast STATE_SYNC mit 17 Eintraegen.
7. React-App empfaengt → setEbenen(17) → neue Ebene weg aus state.
8. structureKey wieder == appliedStructureKey → useEffect's
   clearTimeout cancelt den 200ms-applyAll-Timer.
9. APPLY feuert nie. Backend bleibt auf 17.

Fix in _apply_visibility: detect pending structural change (Payload
hat IDs/Codes die noch nicht in doc.Strings sind) und in dem Fall
das SetString-Save UND den _broadcast_state ueberspringen.
apply_visibility (Rhino-Layer-Visibility-Update) laeuft trotzdem
mit dem merged-state — die noch nicht gespeicherte Ebene hat eh
keinen Rhino-Layer und damit keine Visibility zu setzen.

Sobald der 200ms-applyAll feuert: build_layers + Save bringt alles
in Sync. Daraufhin broadcastet APPLY normal an beide Panels.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 00:49:36 +02:00
karim d63bca1ad8 Ebene-Add: Code = activeCode + nächste freie Nummer + Debug-Logs
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>
2026-05-19 00:29:46 +02:00
karim e96de793a9 Ebenen-Split: FIRST_RUN-Race + Slice-Authoritaet fixen
Symptom: Nach Split funktionierten die Ebenen nicht und Container
erschienen doppelt.

Two bugs:

1. FIRST_RUN-Detection war global statt mode-aware:
   - Beim ersten Plugin-Start war doc.Strings leer.
   - Bridge A (z.B. Zeichnungsebenen) sah leer → sendete FIRST_RUN
     → React schickte APPLY mit `z=INITIAL_Z, e=[]`.
   - Backend speicherte `[]` fuer dossier_ebenen → fortan war
     doc.Strings nicht mehr leer.
   - Bridge B (Ebenen) sah dossier_ebenen vorhanden ("[]") → sendete
     STATE_SYNC mit leerer Liste statt FIRST_RUN → React-App
     ueberschrieb INITIAL_EBENEN mit `[]` → leere UI.
   Fix: `_on_ready` prueft jetzt mode-spezifisch ob SEINE Slice in
   doc.Strings ist. "ebenen"-Mode schaut auf dossier_ebenen,
   "zeichnungsebenen" auf dossier_zeichnungsebenen.

2. APPLY ueberschrieb fremde Slice mit Fallback-`[]`:
   - Wenn nur eine Panel-Slice im Payload kam, las Backend die
     andere aus doc.Strings (= leer beim ersten Mal) und schrieb
     dann *beide* Slices, davon eine als `[]`.
   - Naechstes READY sah die `[]` → STATE_SYNC statt FIRST_RUN →
     Daten weg.
   Fix: `_apply` bekommt `save_z`/`save_e` Flags. Jedes Panel ist
   autoritativ fuer SEINE Slice. APPLY aus dem Ebenen-Panel
   speichert NUR dossier_ebenen (save_z=False), aus Zeichnungs-
   ebenen NUR dossier_zeichnungsebenen.

Effekt: Wenn Ebenen-Panel zuerst lädt → speichert ebenen, lässt z
unangetastet → Zeichnungsebenen-Panel sieht z fehlt → bekommt
FIRST_RUN → schickt INITIAL_Z → speichert z. Symmetrisch wenn
Zeichnungsebenen zuerst lädt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 23:50:21 +02:00
karim a458b4c47d Ebenen-Panel in zwei UI-Panels splitten: Zeichnungsebenen + Ebenen
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>
2026-05-18 23:42:02 +02:00
karim 53fea10cba Clipping: Geschoss-Wechsel loescht Plane nicht mehr
Bug: React's SET_ACTIVE-Message schickt nur Minimal-Payload
`{id, name, isGeschoss, okff}` — ohne hasClipping/schnitthoehe.
`_update_clipping` las `enabled = active_z.get("hasClipping")` aus
diesem Minimal-Payload → False → Plane geloescht. Beim Zurueck-
wechseln auf EG mit aktiviertem Clipping war die Plane weg
obwohl der Toggle im Panel weiter „aktiv" zeigte.

Fix: `_update_clipping` nimmt nur die `id` aus dem uebergebenen
Hint (oder aus `dossier_active_id`) und holt sich den vollen
Geschoss-Record aus `dossier_zeichnungsebenen` doc.String. Damit
sind hasClipping, schnitthoehe, hoehe, visible immer verfuegbar.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 23:26:23 +02:00
karim 961b3c0396 Snapshot: Wand/Öffnung Multi-Surface-Select + Z-Drag + Brüstungs-Mitnahme
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>
2026-05-18 01:50:45 +02:00
karim 9dc191be4f Initial commit — Dossier Rhino 8 Plugin
OpenStudio-Suite Architektur-Plugin fuer Rhino 8 (Mac):
- Smart-Elemente: Wand, Decke, Dach (Pult/Sattel/Walm/Mansarde),
  Oeffnungen (Fenster/Tueren mit Rahmen + Sims + Glas + Fluegel),
  Treppen (gerade · L · Wendel mit Schrittmass-Validierung)
- Live-Previews mit Step-Lines + Soll-Range-Clamping
- Bidirektionale Selection-Sync zwischen Source-Linie und Volume
- Geschoss-/Ebenen-Verwaltung mit OKFF-Persistenz
- Layouts mit PDF-Export
- Ausschnitte / Massstab / Override-Regeln
- Petrol-Gruen Theme (Rapport-konform)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 04:27:41 +02:00