Ribbon 3D-Tab: Kamera-Presets + Darstellungsart; truck-Integration geplant 2026-07-07

This commit is contained in:
2026-07-05 22:43:38 +02:00
parent 1c09b6e7c2
commit 0b56d777bc
3 changed files with 112 additions and 1 deletions
+15 -1
View File
@@ -69,7 +69,7 @@ import type { Pick3dHit } from "./viewport/Wasm3DViewport";
import { ResourceManager } from "./ui/ResourceManager";
import type { ResourceManagerHandlers } from "./ui/ResourceManager";
import { HatchSwatch } from "./ui/hatchPreview";
import { TopBar, ViewRibbonTab } from "./ui/TopBar";
import { TopBar, ViewRibbonTab, Ribbon3dTab } from "./ui/TopBar";
import { RibbonBar } from "./ui/ribbon/RibbonBar";
import type { RibbonTabId } from "./ui/ribbon/ribbonItems";
import { Dropdown } from "./ui/Dropdown";
@@ -3320,6 +3320,20 @@ export default function App() {
textTarget={textTarget}
/>
),
"3d": (
<Ribbon3dTab
viewToggleEnabled={activeLevel.kind === "floor"}
viewType={viewType}
onViewType={setViewType}
view3d={view3d}
onView3d={setView3d}
fov={fov}
onFov={setFov}
renderMode={renderMode}
onRenderMode={setRenderMode}
renderModeEnabled={viewType === "perspektive"}
/>
),
}}
/>
+93
View File
@@ -1262,6 +1262,99 @@ export function ViewRibbonTab({
);
}
export interface Ribbon3dTabProps {
viewToggleEnabled: boolean;
viewType: ViewType;
onViewType: (v: ViewType) => void;
view3d: View3d;
onView3d: (v: View3d) => void;
fov: number;
onFov: (n: number) => void;
renderMode: RenderMode;
onRenderMode: (m: RenderMode) => void;
renderModeEnabled: boolean;
}
/** 3D-Tab des Ribbons — Kamera-Presets + Darstellungsart. Kein Duplikat des
* Ansichten-Tabs: hier nur 3D-relevante Steuerung (Blickwinkel, Rendermodus). */
export function Ribbon3dTab({
viewToggleEnabled,
viewType,
onViewType,
view3d,
onView3d,
fov,
onFov,
renderMode,
onRenderMode,
renderModeEnabled,
}: Ribbon3dTabProps) {
return (
<div className="ribbon-views">
<div className="tb-group" role="group" aria-label={t("topbar.viewGroup")}>
<div className="view-grid view-grid-4">
<button
className={`view-icon${viewToggleEnabled && viewType === "grundriss" ? " active" : ""}`}
onClick={() => onViewType("grundriss")}
disabled={!viewToggleEnabled}
title={viewToggleEnabled ? t("topbar.grundriss") : t("topbar.viewGroup.disabled")}
aria-label={t("topbar.grundriss")}
>
<ViewIcon name="grundriss" />
</button>
{(
[
["top", t("view3d.top")],
["iso", t("view3d.iso")],
["perspective", t("view3d.perspective")],
["front", t("view3d.front")],
["side", t("view3d.side")],
] as [View3d, string][]
).map(([key, label]) => (
<button
key={key}
className={`view-icon${viewToggleEnabled && viewType === "perspektive" && view3d === key ? " active" : ""}`}
onClick={() => {
onView3d(key);
if (viewType !== "perspektive") onViewType("perspektive");
}}
disabled={!viewToggleEnabled}
title={viewToggleEnabled ? `${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 />
<div className="tb-group" role="group" aria-label={t("display.style.group")}>
<label className="tb-field">
<span className="tb-label">{t("display.style")}</span>
<Dropdown
value={renderMode}
disabled={!renderModeEnabled}
onChange={(v) => onRenderMode(v as RenderMode)}
title={t("display.style.hint")}
options={[
{ value: "shaded", label: t("display.style.shaded") },
{ value: "white", label: t("display.style.white") },
{ value: "textured", label: t("display.style.textured") },
{ value: "wireframe", label: t("display.style.wireframe") },
{ value: "hidden", label: t("display.style.hidden") },
]}
/>
</label>
</div>
</div>
);
}
export function TopBar({
project,
ribbonTab,