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
+48
View File
@@ -0,0 +1,48 @@
// Shared helpers fuer den Tauri-Updater. Verwendet vom Auto-Check Modal
// (UpdateNotifier) und dem manuellen Check in den Einstellungen.
export const SKIP_KEY = "dossier_update_skipped_version";
export const LAST_CHECK_KEY = "dossier_update_last_check";
export function isTauri() {
return typeof window !== "undefined" && !!window.__TAURI_INTERNALS__;
}
export async function checkForAppUpdate({ respectSkip = true } = {}) {
if (!isTauri()) return { available: false, isTauri: false };
const { check } = await import("@tauri-apps/plugin-updater");
const result = await check();
localStorage.setItem(LAST_CHECK_KEY, new Date().toISOString());
if (!result?.available) return { available: false, update: null, isTauri: true };
if (respectSkip && localStorage.getItem(SKIP_KEY) === result.version) {
return { available: false, update: result, isTauri: true, skipped: true };
}
return { available: true, update: result, isTauri: true };
}
export async function installAppUpdate(update, onProgress) {
await update.downloadAndInstall(onProgress);
const { relaunch } = await import("@tauri-apps/plugin-process");
await relaunch();
}
export function skipUpdateVersion(version) {
if (version) localStorage.setItem(SKIP_KEY, version);
}
export function getLastUpdateCheck() {
return localStorage.getItem(LAST_CHECK_KEY);
}
export function formatLastCheck(iso) {
if (!iso) return "noch nie";
try {
const d = new Date(iso);
return d.toLocaleString("de-CH", {
day: "2-digit", month: "long", year: "numeric",
hour: "2-digit", minute: "2-digit",
});
} catch {
return "—";
}
}