From 8c96a5dfb94ed6da327e45fa65aaa03184d58374 Mon Sep 17 00:00:00 2001 From: Karim Date: Sat, 4 Jul 2026 13:47:27 +0200 Subject: [PATCH] Renderer-Umschalter in die Settings; Nordstern als Default Der WebGL2<->Nordstern-Umschalter wandert aus der Statusleiste in den Settings-Dialog. Default ist jetzt Nordstern (WASM), sofern WebGPU verfuegbar ist; WebGL2 nur noch als expliziter Fallback. So sieht man nicht mehr versehentlich die Darstellungsfehler des WebGL2-Viewers. styles.css: .sb-renderer-toggle align-self:flex-start, damit das Pill im Settings-Dialog nicht auf volle Breite zieht. --- src/App.tsx | 17 ++++++++++------- src/styles.css | 8 +++++--- src/ui/SettingsDialog.tsx | 40 +++++++++++++++++++++++++++++++++++++++ src/ui/StatusBar.tsx | 36 ----------------------------------- 4 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 282cd19..f70077c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2534,15 +2534,18 @@ export default function App() { // Persistiert in localStorage, damit die Wahl einen Neustart ohne URL-Param // übersteht (z.B. die Electron-App startet immer auf der Basis-URL). const RENDERER_STORAGE_KEY = "cad.rendererMode"; + const webGpuAvailable = typeof navigator !== "undefined" && "gpu" in navigator; const rendererMode: RendererMode = (() => { const fromUrl = new URLSearchParams(window.location.search).get("engine"); if (fromUrl === "wasm") return "wasm"; if (fromUrl === "webgl2") return "webgl2"; - return window.localStorage.getItem(RENDERER_STORAGE_KEY) === "wasm" - ? "wasm" - : "webgl2"; + const fromStorage = window.localStorage.getItem(RENDERER_STORAGE_KEY); + if (fromStorage === "webgl2") return "webgl2"; + if (fromStorage === "wasm") return "wasm"; + // Keine explizite Wahl (weder URL noch localStorage) — Nordstern (WASM) + // ist Standard, sofern WebGPU verfügbar ist; sonst WebGL2 als Fallback. + return webGpuAvailable ? "wasm" : "webgl2"; })(); - const webGpuAvailable = typeof navigator !== "undefined" && "gpu" in navigator; const setRendererMode = (mode: RendererMode) => { window.localStorage.setItem(RENDERER_STORAGE_KEY, mode); const url = new URL(window.location.href); @@ -3343,9 +3346,6 @@ export default function App() { referenceLinesEnabled={planActive} activeFloor={activeLevel.name} activeLayer={activeLayerName} - rendererMode={rendererMode} - webGpuAvailable={webGpuAvailable} - onRendererModeChange={setRendererMode} lineMode={lineMode} onLineModeChange={setLineMode} lineModeEnabled={planActive} @@ -3411,6 +3411,9 @@ export default function App() { onSnapColorChange={setSnapColor} project={project} setProject={setProject} + rendererMode={rendererMode} + webGpuAvailable={webGpuAvailable} + onRendererModeChange={setRendererMode} onClose={() => setSettingsOpen(false)} /> )} diff --git a/src/styles.css b/src/styles.css index ccc3dcb..18010d7 100644 --- a/src/styles.css +++ b/src/styles.css @@ -816,12 +816,14 @@ body { background: var(--border); } -/* Renderer-Umschalter (WebGL2 / Engine) in der Statusleiste — kleine - Segmentpille, an die 22px-Leiste angepasst (siehe .tb-seg für das größere - Vorbild in der Oberleiste). */ +/* Renderer-Umschalter (WebGL2 / Nordstern) — kleine Segmentpille; ursprünglich + in der Statusleiste (22px-Leiste), jetzt im Einstellungs-Fenster. In einer + flex-column (.imp-section) würde sie sonst auf volle Breite gestreckt + werden (Standard-`align-items: stretch`) — bleibt daher inhaltsbreit. */ .sb-renderer-toggle { display: inline-flex; align-items: stretch; + align-self: flex-start; height: 16px; border: 1px solid var(--border); border-radius: 999px; diff --git a/src/ui/SettingsDialog.tsx b/src/ui/SettingsDialog.tsx index d9ff785..fdc92cf 100644 --- a/src/ui/SettingsDialog.tsx +++ b/src/ui/SettingsDialog.tsx @@ -14,6 +14,7 @@ import { t } from "../i18n"; import { ACCENT_SWATCHES } from "../theme/accents"; import type { Project } from "../model/types"; import { ColorHexField } from "./ColorHexField"; +import type { RendererMode } from "./StatusBar"; export interface SettingsDialogProps { marqueeColor: string; @@ -22,6 +23,15 @@ export interface SettingsDialogProps { onSnapColorChange: (hex: string) => void; project: Project; setProject: (next: Project | ((p: Project) => Project)) => void; + /** Aktuell gewählter Plan-Renderer (aus dem `?engine`-URL-Param abgeleitet). */ + rendererMode: RendererMode; + /** Ist `navigator.gpu` vorhanden? Steuert, ob „Nordstern" wählbar ist. */ + webGpuAvailable: boolean; + /** + * Renderer wechseln (setzt/entfernt den `engine`-URL-Param und lädt neu — kein + * Live-Remount der Renderer-Hooks). + */ + onRendererModeChange: (mode: RendererMode) => void; onClose: () => void; } @@ -32,6 +42,9 @@ export function SettingsDialog({ onSnapColorChange, project, setProject, + rendererMode, + webGpuAvailable, + onRendererModeChange, onClose, }: SettingsDialogProps) { useEffect(() => { @@ -85,6 +98,33 @@ export function SettingsDialog({
+
+
{t("status.renderer")}
+ + + + + {!webGpuAvailable && ( +
{t("status.rendererWasmUnavailable")}
+ )} +
+
{t("settings.section.display")}
void; /** Linien-Darstellung: „display" (Haarlinien) oder „print" (echte mm-Stärken). */ lineMode: "display" | "print"; /** Linien-Darstellung wechseln. */ @@ -264,9 +255,6 @@ export function StatusBar({ referenceLinesEnabled, activeFloor, activeLayer, - rendererMode, - webGpuAvailable, - onRendererModeChange, lineMode, onLineModeChange, lineModeEnabled, @@ -309,30 +297,6 @@ export function StatusBar({ {t("status.referenceLines")} - - {t("status.renderer")} - - - - - -