Add support for viewport quad split in editor store and ViewportPanel component

This commit is contained in:
2026-04-03 01:25:25 +02:00
parent 9d233de06a
commit 37e70a6b0b
2 changed files with 26 additions and 3 deletions

View File

@@ -26,7 +26,8 @@ import {
type ViewportDisplayMode,
type ViewportLayoutMode,
type ViewportPanelId,
type ViewportPanelState
type ViewportPanelState,
type ViewportQuadSplit
} from "../viewport-three/viewport-layout";
export interface EditorStoreState {
@@ -36,6 +37,7 @@ export interface EditorStoreState {
viewportLayoutMode: ViewportLayoutMode;
activeViewportPanelId: ViewportPanelId;
viewportPanels: Record<ViewportPanelId, ViewportPanelState>;
viewportQuadSplit: ViewportQuadSplit;
viewportTransientState: ViewportTransientState;
canUndo: boolean;
canRedo: boolean;
@@ -61,6 +63,7 @@ export class EditorStore {
private viewportLayoutMode: ViewportLayoutMode = "single";
private activeViewportPanelId: ViewportPanelId = "topLeft";
private viewportPanels = createDefaultViewportLayoutState().panels;
private viewportQuadSplit = createDefaultViewportLayoutState().viewportQuadSplit;
private viewportTransientState = createDefaultViewportTransientState();
private previousEditingToolMode: Exclude<ToolMode, "play"> = "select";
private readonly history = new CommandHistory();
@@ -168,6 +171,18 @@ export class EditorStore {
this.emit();
}
setViewportQuadSplit(viewportQuadSplit: ViewportQuadSplit) {
if (this.viewportQuadSplit.x === viewportQuadSplit.x && this.viewportQuadSplit.y === viewportQuadSplit.y) {
return;
}
this.viewportQuadSplit = {
x: viewportQuadSplit.x,
y: viewportQuadSplit.y
};
this.emit();
}
setViewportToolPreview(toolPreview: ViewportToolPreview) {
const nextToolPreview = cloneViewportToolPreview(toolPreview);
@@ -330,6 +345,7 @@ export class EditorStore {
viewportLayoutMode: this.viewportLayoutMode,
activeViewportPanelId: this.activeViewportPanelId,
viewportPanels: this.viewportPanels,
viewportQuadSplit: this.viewportQuadSplit,
viewportTransientState: this.viewportTransientState,
canUndo: this.history.canUndo(),
canRedo: this.history.canRedo(),

View File

@@ -1,3 +1,5 @@
import type { CSSProperties } from "react";
import { ViewportCanvas } from "./ViewportCanvas";
import {
getViewportDisplayModeLabel,
@@ -22,6 +24,8 @@ interface ViewportPanelProps {
panelState: ViewportPanelState;
layoutMode: ViewportLayoutMode;
isActive: boolean;
className?: string;
style?: CSSProperties;
world: WorldSettings;
sceneDocument: SceneDocument;
projectAssets: Record<string, ProjectAssetRecord>;
@@ -45,6 +49,8 @@ export function ViewportPanel({
panelState,
layoutMode,
isActive,
className,
style,
world,
sceneDocument,
projectAssets,
@@ -63,15 +69,16 @@ export function ViewportPanel({
onSelectionChange
}: ViewportPanelProps) {
const shouldShow = layoutMode === "quad" || isActive;
const panelStyle = shouldShow ? style : { ...(style ?? {}), display: "none" };
return (
<section
className={`viewport-panel ${layoutMode === "single" ? "viewport-panel--single" : "viewport-panel--quad"}`}
className={`viewport-panel ${layoutMode === "single" ? "viewport-panel--single" : "viewport-panel--quad"} ${className ?? ""}`.trim()}
data-testid={`viewport-panel-${panelId}`}
data-active={isActive ? "true" : "false"}
aria-hidden={shouldShow ? undefined : true}
aria-label={`${getViewportPanelLabel(panelId)} viewport panel`}
style={shouldShow ? undefined : { display: "none" }}
style={panelStyle}
onPointerDownCapture={() => onActivatePanel(panelId)}
onFocusCapture={() => onActivatePanel(panelId)}
>