TopBar/Footer: Referenzlinien in die Statusleiste, Ansichten bleiben sichtbar

Der Referenzlinien-Schalter wandert aus der TopBar in die Statusleiste
(neben Fang) — dort passt er besser zu den übrigen Anzeige-/Fang-Kontrollen.
Die doppelt gezeigten Werte Massstab und Zoom fallen aus der Statusleiste
weg; sie stehen weiterhin im TopBar-Cluster. Die Ansichts-Icons blenden sich
auf Nicht-Geschoss-Ebenen (Schnitt/Ansicht/2D) nicht mehr komplett aus,
sondern bleiben sichtbar und werden nur deaktiviert.
This commit is contained in:
2026-07-03 23:52:26 +02:00
parent b6c1a9a3c6
commit 56bbcec2a8
6 changed files with 126 additions and 100 deletions
+3 -5
View File
@@ -2747,9 +2747,6 @@ export default function App() {
renderModeEnabled={viewType === "perspektive"} renderModeEnabled={viewType === "perspektive"}
planColorMode={planColorMode} planColorMode={planColorMode}
onPlanColorMode={setPlanColorMode} onPlanColorMode={setPlanColorMode}
referenceLines={referenceLines}
onReferenceLines={setReferenceLines}
referenceLinesEnabled={planActive}
combos={{ combos={{
// Ebenen-Kombinationen: Speichern = Snapshot des Layer-Baums → // Ebenen-Kombinationen: Speichern = Snapshot des Layer-Baums →
// localStorage; Laden = Map lesen → Sichtbarkeits-Flags anwenden. // localStorage; Laden = Map lesen → Sichtbarkeits-Flags anwenden.
@@ -2985,8 +2982,9 @@ export default function App() {
hint={toolHint} hint={toolHint}
cursor={planActive ? cursor : null} cursor={planActive ? cursor : null}
unit="m" unit="m"
scaleDenominator={planActive ? liveScale : null} referenceLines={referenceLines}
zoomPercent={planActive ? zoomPercent : null} onReferenceLines={setReferenceLines}
referenceLinesEnabled={planActive}
activeFloor={activeLevel.name} activeFloor={activeLevel.name}
activeLayer={activeLayerName} activeLayer={activeLayerName}
rendererMode={rendererMode} rendererMode={rendererMode}
+4
View File
@@ -10,6 +10,7 @@ export const de = {
"brand.tag": "Dokumentmodell", "brand.tag": "Dokumentmodell",
"topbar.viewGroup": "Ansicht", "topbar.viewGroup": "Ansicht",
"topbar.viewGroup.disabled": "Ansichten nur für Geschosse",
"topbar.grundriss": "Grundriss", "topbar.grundriss": "Grundriss",
"topbar.perspektive": "Perspektive", "topbar.perspektive": "Perspektive",
@@ -183,6 +184,9 @@ export const de = {
"status.unit": "Einheit", "status.unit": "Einheit",
"status.scale": "Massstab", "status.scale": "Massstab",
"status.zoom": "Zoom", "status.zoom": "Zoom",
"status.referenceLines": "Achsen",
"status.referenceLines.hint": "Referenzlinien (Wandachsen) ein-/ausblenden",
"status.referenceLines.hintDisabled": "Referenzlinien wirken im Grundriss",
"status.floor": "Geschoss", "status.floor": "Geschoss",
"status.layer": "Ebene", "status.layer": "Ebene",
"status.none": "—", "status.none": "—",
+4
View File
@@ -9,6 +9,7 @@ export const en: Record<TranslationKey, string> = {
"brand.tag": "Document model", "brand.tag": "Document model",
"topbar.viewGroup": "View", "topbar.viewGroup": "View",
"topbar.viewGroup.disabled": "Views available for floors only",
"topbar.grundriss": "Plan", "topbar.grundriss": "Plan",
"topbar.perspektive": "Perspective", "topbar.perspektive": "Perspective",
@@ -182,6 +183,9 @@ export const en: Record<TranslationKey, string> = {
"status.unit": "Unit", "status.unit": "Unit",
"status.scale": "Scale", "status.scale": "Scale",
"status.zoom": "Zoom", "status.zoom": "Zoom",
"status.referenceLines": "Axes",
"status.referenceLines.hint": "Show/hide reference lines (wall axes)",
"status.referenceLines.hintDisabled": "Reference lines apply in the plan",
"status.floor": "Floor", "status.floor": "Floor",
"status.layer": "Layer", "status.layer": "Layer",
"status.none": "—", "status.none": "—",
+31
View File
@@ -803,6 +803,37 @@ body {
cursor: default; cursor: default;
} }
/* Einzelner Umschalt-Button in der Statusleiste (z. B. Referenzlinien). */
.sb-toggle {
display: inline-flex;
align-items: center;
border: 1px solid var(--border);
border-radius: 5px;
background: transparent;
color: var(--muted);
font-family: inherit;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.02em;
padding: 2px 8px;
cursor: pointer;
transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.sb-toggle:hover:not(:disabled) {
background: var(--accent-dim);
color: var(--accent);
border-color: var(--accent);
}
.sb-toggle.active {
background: var(--accent);
border-color: var(--accent);
color: #fff;
}
.sb-toggle:disabled {
opacity: 0.4;
cursor: default;
}
/* Generische Segment-Pille für die Statusleiste (Linien-Darstellung, Fang) — /* Generische Segment-Pille für die Statusleiste (Linien-Darstellung, Fang) —
gleiche Masse/Optik wie .sb-renderer-toggle, aber nicht renderer-spezifisch. */ gleiche Masse/Optik wie .sb-renderer-toggle, aber nicht renderer-spezifisch. */
.sb-seg { .sb-seg {
+25 -19
View File
@@ -23,13 +23,12 @@ export interface StatusBarProps {
cursor: Vec2 | null; cursor: Vec2 | null;
/** Einheit aus dem Projekt (vorerst fix „m"). */ /** Einheit aus dem Projekt (vorerst fix „m"). */
unit: string; unit: string;
/** /** Referenzlinien (Wandachsen) an/aus — sitzt jetzt in der Statusleiste. */
* LIVE Papier-Massstab-Nenner (1:N) aus der View-Transform oder `null` referenceLines: boolean;
* (keine Plan-Ansicht aktiv → „—"). /** Referenzlinien umschalten. */
*/ onReferenceLines: (on: boolean) => void;
scaleDenominator: number | null; /** Nur im Grundriss sinnvoll — deaktiviert den Schalter wenn `false`. */
/** Live-Zoom in Prozent oder `null` (keine zoombare Ansicht aktiv). */ referenceLinesEnabled: boolean;
zoomPercent: number | null;
/** Name des aktiven Geschosses / der aktiven Zeichnungsebene. */ /** Name des aktiven Geschosses / der aktiven Zeichnungsebene. */
activeFloor: string; activeFloor: string;
/** Name der aktiven Ebene (Kategorie) oder „—". */ /** Name der aktiven Ebene (Kategorie) oder „—". */
@@ -260,8 +259,9 @@ export function StatusBar({
hint, hint,
cursor, cursor,
unit, unit,
scaleDenominator, referenceLines,
zoomPercent, onReferenceLines,
referenceLinesEnabled,
activeFloor, activeFloor,
activeLayer, activeLayer,
rendererMode, rendererMode,
@@ -293,6 +293,22 @@ export function StatusBar({
<Sep /> <Sep />
<SnapControl snap={snap} onSnapChange={onSnapChange} /> <SnapControl snap={snap} onSnapChange={onSnapChange} />
<Sep /> <Sep />
{/* Referenzlinien-Schalter (aus der TopBar hierher gewandert). */}
<button
type="button"
className={`sb-toggle${referenceLines ? " active" : ""}`}
aria-pressed={referenceLines}
disabled={!referenceLinesEnabled}
onClick={() => onReferenceLines(!referenceLines)}
title={
referenceLinesEnabled
? t("status.referenceLines.hint")
: t("status.referenceLines.hintDisabled")
}
>
{t("status.referenceLines")}
</button>
<Sep />
<span className="sb-field"> <span className="sb-field">
<span className="sb-key">{t("status.renderer")}</span> <span className="sb-key">{t("status.renderer")}</span>
<span className="sb-renderer-toggle" role="group" aria-label={t("status.renderer")}> <span className="sb-renderer-toggle" role="group" aria-label={t("status.renderer")}>
@@ -321,16 +337,6 @@ export function StatusBar({
<Sep /> <Sep />
<Field label={t("status.unit")} value={unit} /> <Field label={t("status.unit")} value={unit} />
<Sep /> <Sep />
<Field
label={t("status.scale")}
value={scaleDenominator == null ? "—" : `1:${Math.round(scaleDenominator)}`}
/>
<Sep />
<Field
label={t("status.zoom")}
value={zoomPercent == null ? "—" : `${Math.round(zoomPercent)}%`}
/>
<Sep />
<Field label={t("status.floor")} value={activeFloor} /> <Field label={t("status.floor")} value={activeFloor} />
<Sep /> <Sep />
<Field label={t("status.layer")} value={activeLayer} /> <Field label={t("status.layer")} value={activeLayer} />
+59 -76
View File
@@ -135,12 +135,6 @@ export interface TopBarProps {
planColorMode: PlanColorMode; planColorMode: PlanColorMode;
onPlanColorMode: (m: PlanColorMode) => void; onPlanColorMode: (m: PlanColorMode) => void;
// Referenzlinien (Wandachsen).
referenceLines: boolean;
onReferenceLines: (on: boolean) => void;
/** Referenzlinien nur im Grundriss sinnvoll (sonst deaktiviert). */
referenceLinesEnabled: boolean;
// Sichtbarkeits-Kombinationen (Ebenen-/Zeichnungskombinationen). // Sichtbarkeits-Kombinationen (Ebenen-/Zeichnungskombinationen).
/** Handler-Satz für die beiden Kombinations-Dropdowns. */ /** Handler-Satz für die beiden Kombinations-Dropdowns. */
combos: ComboMenuHandlers; combos: ComboMenuHandlers;
@@ -846,9 +840,6 @@ export function TopBar({
renderModeEnabled, renderModeEnabled,
planColorMode, planColorMode,
onPlanColorMode, onPlanColorMode,
referenceLines,
onReferenceLines,
referenceLinesEnabled,
combos, combos,
resourcesOpen, resourcesOpen,
onToggleResources, onToggleResources,
@@ -921,52 +912,65 @@ export function TopBar({
„Grundriss" schaltet auf den 2D-Plan, die übrigen auf die jeweilige „Grundriss" schaltet auf den 2D-Plan, die übrigen auf die jeweilige
3D-Ansicht (Perspektive wird dabei automatisch aktiviert). 4 oben / 3D-Ansicht (Perspektive wird dabei automatisch aktiviert). 4 oben /
3 unten. Tooltip nennt jede Ansicht im Klartext. */} 3 unten. Tooltip nennt jede Ansicht im Klartext. */}
{viewToggleEnabled && ( {/* Ansichts-Icons bleiben immer sichtbar; auf Nicht-Geschoss-Ebenen
<> (Schnitt/Ansicht/2D-Zeichnung) sind sie deaktiviert, weil dort keine
<div className="tb-group" role="group" aria-label={t("topbar.viewGroup")}> 2D/3D-Umschaltung greift — die Serie verschwindet nicht mehr ganz. */}
<div className="view-grid view-grid-4"> <div className="tb-group" role="group" aria-label={t("topbar.viewGroup")}>
<button <div className="view-grid view-grid-4">
className={`view-icon${viewType === "grundriss" ? " active" : ""}`} <button
onClick={() => onViewType("grundriss")} className={`view-icon${
title={t("topbar.grundriss")} viewToggleEnabled && viewType === "grundriss" ? " active" : ""
aria-label={t("topbar.grundriss")} }`}
> onClick={() => onViewType("grundriss")}
<ViewIcon name="grundriss" /> disabled={!viewToggleEnabled}
</button> title={
{( viewToggleEnabled
[ ? t("topbar.grundriss")
["top", t("view3d.top")], : t("topbar.viewGroup.disabled")
["iso", t("view3d.iso")], }
["perspective", t("view3d.perspective")], aria-label={t("topbar.grundriss")}
["front", t("view3d.front")], >
["side", t("view3d.side")], <ViewIcon name="grundriss" />
] as [View3d, string][] </button>
).map(([key, label]) => ( {(
<button [
key={key} ["top", t("view3d.top")],
className={`view-icon${ ["iso", t("view3d.iso")],
viewType === "perspektive" && view3d === key ? " active" : "" ["perspective", t("view3d.perspective")],
}`} ["front", t("view3d.front")],
onClick={() => { ["side", t("view3d.side")],
onView3d(key); ] as [View3d, string][]
if (viewType !== "perspektive") onViewType("perspektive"); ).map(([key, label]) => (
}} <button
title={`${label}${t(`view3d.${key}.hint`)}`} key={key}
aria-label={label} className={`view-icon${
> viewToggleEnabled && viewType === "perspektive" && view3d === key
<ViewIcon name={key} /> ? " active"
</button> : ""
))} }`}
<CameraMenu onClick={() => {
fov={fov} onView3d(key);
onFov={onFov} if (viewType !== "perspektive") onViewType("perspektive");
disabled={viewType !== "perspektive"} }}
/> disabled={!viewToggleEnabled}
</div> title={
</div> viewToggleEnabled
<Sep /> ? `${label}${t(`view3d.${key}.hint`)}`
</> : t("topbar.viewGroup.disabled")
)} }
aria-label={label}
>
<ViewIcon name={key} />
</button>
))}
<CameraMenu
fov={fov}
onFov={onFov}
disabled={!viewToggleEnabled || viewType !== "perspektive"}
/>
</div>
</div>
<Sep />
{/* Sichtbarkeits-Kombinationen (Vectorworks: Ebenen-/Zeichnungs- {/* Sichtbarkeits-Kombinationen (Vectorworks: Ebenen-/Zeichnungs-
kombinationen). Sitzt direkt nach dem Ansichts-Umschalter, weil beides kombinationen). Sitzt direkt nach dem Ansichts-Umschalter, weil beides
@@ -1172,27 +1176,6 @@ export function TopBar({
<Sep /> <Sep />
{/* Referenzlinien (Wandachsen) — zeigt/versteckt die gestrichelten
Achslinien im Grundriss. Nur im Grundriss sinnvoll → sonst deaktiviert. */}
<div className="tb-group" role="group" aria-label={t("topbar.referenceLinesGroup")}>
<button
className={`view-icon${referenceLines ? " active" : ""}`}
onClick={() => onReferenceLines(!referenceLines)}
disabled={!referenceLinesEnabled}
aria-pressed={referenceLines}
aria-label={t("topbar.referenceLines")}
title={
referenceLinesEnabled
? `${t("topbar.referenceLines")}${t("topbar.referenceLines.hint")}`
: t("topbar.referenceLines.hintDisabled")
}
>
<TbIcon name="straighten" />
</button>
</div>
<Sep />
{/* Rechte Gruppe: Layout-Menü · Ressourcen · Projektname. */} {/* Rechte Gruppe: Layout-Menü · Ressourcen · Projektname. */}
<div className="topbar-right"> <div className="topbar-right">
{layoutMenu} {layoutMenu}