Update ViewportCanvas to include display mode and active panel state

This commit is contained in:
2026-04-02 22:31:52 +02:00
parent b2cf951269
commit aa7d742277

View File

@@ -10,6 +10,7 @@ import { DEFAULT_BOX_BRUSH_CENTER, DEFAULT_BOX_BRUSH_SIZE } from "../document/br
import type { SceneDocument } from "../document/scene-document"; import type { SceneDocument } from "../document/scene-document";
import type { WorldSettings } from "../document/world-settings"; import type { WorldSettings } from "../document/world-settings";
import { createWorldBackgroundStyle } from "../shared-ui/world-background-style"; import { createWorldBackgroundStyle } from "../shared-ui/world-background-style";
import type { ViewportDisplayMode, ViewportPanelId } from "./viewport-layout";
import { import {
getViewportViewModeControlHint, getViewportViewModeControlHint,
getViewportViewModeGridPlaneLabel, getViewportViewModeGridPlaneLabel,
@@ -20,6 +21,7 @@ import {
import { ViewportHost } from "./viewport-host"; import { ViewportHost } from "./viewport-host";
interface ViewportCanvasProps { interface ViewportCanvasProps {
panelId: ViewportPanelId;
world: WorldSettings; world: WorldSettings;
sceneDocument: SceneDocument; sceneDocument: SceneDocument;
projectAssets: Record<string, ProjectAssetRecord>; projectAssets: Record<string, ProjectAssetRecord>;
@@ -28,6 +30,8 @@ interface ViewportCanvasProps {
selection: EditorSelection; selection: EditorSelection;
toolMode: ToolMode; toolMode: ToolMode;
viewMode: ViewportViewMode; viewMode: ViewportViewMode;
displayMode: ViewportDisplayMode;
isActivePanel: boolean;
focusRequestId: number; focusRequestId: number;
focusSelection: EditorSelection; focusSelection: EditorSelection;
onSelectionChange(selection: EditorSelection): void; onSelectionChange(selection: EditorSelection): void;
@@ -42,15 +46,16 @@ function formatVec3(vector: Vec3 | null): string {
return `${vector.x}, ${vector.y}, ${vector.z}`; return `${vector.x}, ${vector.y}, ${vector.z}`;
} }
function getViewportOverlayText(toolMode: ToolMode, viewMode: ViewportViewMode): string { function getViewportOverlayText(toolMode: ToolMode, viewMode: ViewportViewMode, displayMode: ViewportDisplayMode): string {
if (toolMode === "box-create") { if (toolMode === "box-create") {
return `Box Create is active on the ${getViewportViewModeGridPlaneLabel(viewMode)} grid. Click the ${getViewportViewModeGridPlaneLabel(viewMode)} grid to place a ${DEFAULT_BOX_BRUSH_SIZE.x} x ${DEFAULT_BOX_BRUSH_SIZE.y} x ${DEFAULT_BOX_BRUSH_SIZE.z} box. ${getViewportViewModeControlHint(viewMode)}`; return `${displayMode === "authoring" ? "Authoring view" : "Box Create"} is active on the ${getViewportViewModeGridPlaneLabel(viewMode)} grid. Click the ${getViewportViewModeGridPlaneLabel(viewMode)} grid to place a ${DEFAULT_BOX_BRUSH_SIZE.x} x ${DEFAULT_BOX_BRUSH_SIZE.y} x ${DEFAULT_BOX_BRUSH_SIZE.z} box. ${getViewportViewModeControlHint(viewMode)}`;
} }
return `${getViewportViewModeLabel(viewMode)} view active on the ${getViewportViewModeGridPlaneLabel(viewMode)} grid. ${getViewportViewModeControlHint(viewMode)}`; return `${displayMode === "authoring" ? "Authoring view" : `${getViewportViewModeLabel(viewMode)} view`} active on the ${getViewportViewModeGridPlaneLabel(viewMode)} grid. ${getViewportViewModeControlHint(viewMode)}`;
} }
export function ViewportCanvas({ export function ViewportCanvas({
panelId,
world, world,
sceneDocument, sceneDocument,
projectAssets, projectAssets,
@@ -59,6 +64,8 @@ export function ViewportCanvas({
selection, selection,
toolMode, toolMode,
viewMode, viewMode,
displayMode,
isActivePanel,
focusRequestId, focusRequestId,
focusSelection, focusSelection,
onSelectionChange, onSelectionChange,
@@ -120,6 +127,10 @@ export function ViewportCanvas({
hostRef.current?.setViewMode(viewMode); hostRef.current?.setViewMode(viewMode);
}, [viewMode]); }, [viewMode]);
useEffect(() => {
hostRef.current?.setDisplayMode(displayMode);
}, [displayMode]);
useEffect(() => { useEffect(() => {
hostRef.current?.setBrushSelectionChangeHandler(onSelectionChange); hostRef.current?.setBrushSelectionChangeHandler(onSelectionChange);
}, [onSelectionChange]); }, [onSelectionChange]);
@@ -151,19 +162,29 @@ export function ViewportCanvas({
return ( return (
<div <div
ref={containerRef} ref={containerRef}
className={`viewport-canvas viewport-canvas--${toolMode} viewport-canvas--${viewMode}`} className={`viewport-canvas viewport-canvas--${toolMode} viewport-canvas--${viewMode} viewport-canvas--${displayMode} ${isActivePanel ? "viewport-canvas--active" : ""}`}
data-testid="viewport-shell" data-testid={`viewport-canvas-${panelId}`}
aria-label="Editor viewport" aria-label="Editor viewport"
style={createWorldBackgroundStyle(world.background, world.background.mode === "image" ? loadedImageAssets[world.background.assetId]?.sourceUrl ?? null : null)} style={
displayMode === "authoring"
? {
backgroundColor: "#000000",
backgroundImage: "none"
}
: createWorldBackgroundStyle(world.background, world.background.mode === "image" ? loadedImageAssets[world.background.assetId]?.sourceUrl ?? null : null)
}
> >
<div className="viewport-canvas__overlay" data-testid="viewport-overlay"> <div className="viewport-canvas__overlay" data-testid={`viewport-overlay-${panelId}`}>
<div className="viewport-canvas__overlay-badges"> <div className="viewport-canvas__overlay-badges">
<div className="viewport-canvas__overlay-badge">{toolMode === "box-create" ? "Box Create" : "Select"}</div> <div className="viewport-canvas__overlay-badge">{toolMode === "box-create" ? "Box Create" : "Select"}</div>
<div className="viewport-canvas__overlay-badge viewport-canvas__overlay-badge--view">{getViewportViewModeLabel(viewMode)}</div> <div className="viewport-canvas__overlay-badge viewport-canvas__overlay-badge--view">{getViewportViewModeLabel(viewMode)}</div>
<div className="viewport-canvas__overlay-badge viewport-canvas__overlay-badge--display">
{displayMode === "authoring" ? "Authoring" : "Lit"}
</div>
</div> </div>
<div className="viewport-canvas__overlay-text">{getViewportOverlayText(toolMode, viewMode)}</div> <div className="viewport-canvas__overlay-text">{getViewportOverlayText(toolMode, viewMode, displayMode)}</div>
{toolMode !== "box-create" ? null : ( {toolMode !== "box-create" ? null : (
<div className="viewport-canvas__overlay-preview" data-testid="viewport-snap-preview"> <div className="viewport-canvas__overlay-preview" data-testid={`viewport-snap-preview-${panelId}`}>
Next box center: {formatVec3(boxCreatePreview)} Next box center: {formatVec3(boxCreatePreview)}
</div> </div>
)} )}
@@ -173,8 +194,13 @@ export function ViewportCanvas({
<div className="viewport-canvas__fallback" role="status"> <div className="viewport-canvas__fallback" role="status">
<div className="viewport-canvas__fallback-title">Viewport Unavailable</div> <div className="viewport-canvas__fallback-title">Viewport Unavailable</div>
<div>{viewportMessage}</div> <div>{viewportMessage}</div>
{toolMode !== "box-create" ? null : ( {toolMode !== "box-create" || !isActivePanel ? null : (
<button className="toolbar__button toolbar__button--accent" type="button" data-testid="viewport-fallback-create-box" onClick={() => onCreateBoxBrush(DEFAULT_BOX_BRUSH_CENTER)}> <button
className="toolbar__button toolbar__button--accent"
type="button"
data-testid={`viewport-fallback-create-box-${panelId}`}
onClick={() => onCreateBoxBrush(DEFAULT_BOX_BRUSH_CENTER)}
>
Create Default Box Create Default Box
</button> </button>
)} )}