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>
This commit is contained in:
2026-05-18 01:50:45 +02:00
parent 1180d7bedf
commit 961b3c0396
52 changed files with 10760 additions and 765 deletions
+6 -6
View File
@@ -168,7 +168,7 @@ export default function MassstabApp() {
value={dropdownValue}
onChange={(e) => applyDropdown(e.target.value)}
style={{ ...cellInput, width: 80 }}
title="Massstab waehlen"
title="Massstab wählen"
>
<option value="__none__">1:?</option>
{PRESETS.map(p => (
@@ -201,7 +201,7 @@ export default function MassstabApp() {
style={cellBtn}
title={appliedScale
? `Zoom auf eingestellten Massstab snappen (1:${appliedScale >= 10 ? Math.round(appliedScale) : appliedScale})`
: 'Erst einen Massstab waehlen'}
: 'Erst einen Massstab wählen'}
>100%</button>
<button onClick={zoomExtents} style={cellBtn} title="Auf gesamten Inhalt zoomen">
<Icon name="fit_screen" size={14} />
@@ -224,8 +224,8 @@ export default function MassstabApp() {
borderColor: state.showLineweights ? 'var(--accent)' : 'var(--border)',
}}
title={state.showLineweights
? 'Strichstaerken werden angezeigt (Print-View) — klicken zum Ausschalten'
: 'Strichstaerken als Hairlines (Edit-View) — klicken um Print-View zu zeigen'}
? 'Strichstärken werden angezeigt (Print-View) — klicken zum Ausschalten'
: 'Strichstärken als Hairlines (Edit-View) — klicken um Print-View zu zeigen'}
>
<Icon name="edit" size={14} style={{ display: state.showLineweights ? 'none' : 'inline-block' }} />
<Icon name="print" size={14} style={{ display: state.showLineweights ? 'inline-block' : 'none' }} />
@@ -268,7 +268,7 @@ export default function MassstabApp() {
boxShadow: '0 4px 12px rgba(0,0,0,0.15)', zIndex: 10, minWidth: 220,
}}>
<div style={{ fontSize: 10, color: 'var(--text-muted)' }}>
Bildschirm-Aufloesung fuer Massstab-Berechnung
Bildschirm-Auflösung für Massstab-Berechnung
</div>
<div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
<input
@@ -284,7 +284,7 @@ export default function MassstabApp() {
<button
onClick={() => { detectMassstabDpi(); setDpiOpen(false) }}
style={{ ...cellBtn, fontSize: 10, justifyContent: 'flex-start' }}
title="DPI automatisch ueber EDID des Bildschirms ermitteln"
title="DPI automatisch über EDID des Bildschirms ermitteln"
>
<Icon name="auto_fix_high" size={12} /> Auto-Detect (EDID)
</button>