Enhance editor store with viewport layout state management
This commit is contained in:
@@ -22,11 +22,16 @@ import {
|
|||||||
type ViewportTransientState
|
type ViewportTransientState
|
||||||
} from "../viewport-three/viewport-transient-state";
|
} from "../viewport-three/viewport-transient-state";
|
||||||
import {
|
import {
|
||||||
|
areViewportPanelCameraStatesEqual,
|
||||||
|
cloneViewportLayoutState,
|
||||||
|
cloneViewportPanelCameraState,
|
||||||
createDefaultViewportLayoutState,
|
createDefaultViewportLayoutState,
|
||||||
type ViewportDisplayMode,
|
type ViewportDisplayMode,
|
||||||
|
type ViewportLayoutState,
|
||||||
type ViewportLayoutMode,
|
type ViewportLayoutMode,
|
||||||
type ViewportPanelId,
|
type ViewportPanelId,
|
||||||
type ViewportPanelState,
|
type ViewportPanelState,
|
||||||
|
type ViewportPanelCameraState,
|
||||||
type ViewportQuadSplit
|
type ViewportQuadSplit
|
||||||
} from "../viewport-three/viewport-layout";
|
} from "../viewport-three/viewport-layout";
|
||||||
|
|
||||||
@@ -47,6 +52,7 @@ export interface EditorStoreState {
|
|||||||
|
|
||||||
interface EditorStoreOptions {
|
interface EditorStoreOptions {
|
||||||
initialDocument?: SceneDocument;
|
initialDocument?: SceneDocument;
|
||||||
|
initialViewportLayoutState?: ViewportLayoutState;
|
||||||
storage?: KeyValueStorage | null;
|
storage?: KeyValueStorage | null;
|
||||||
storageKey?: string;
|
storageKey?: string;
|
||||||
}
|
}
|
||||||
@@ -60,10 +66,10 @@ export class EditorStore {
|
|||||||
private document: SceneDocument;
|
private document: SceneDocument;
|
||||||
private selection: EditorSelection = { kind: "none" };
|
private selection: EditorSelection = { kind: "none" };
|
||||||
private toolMode: ToolMode = "select";
|
private toolMode: ToolMode = "select";
|
||||||
private viewportLayoutMode: ViewportLayoutMode = "single";
|
private viewportLayoutMode: ViewportLayoutMode;
|
||||||
private activeViewportPanelId: ViewportPanelId = "topLeft";
|
private activeViewportPanelId: ViewportPanelId;
|
||||||
private viewportPanels = createDefaultViewportLayoutState().panels;
|
private viewportPanels: Record<ViewportPanelId, ViewportPanelState>;
|
||||||
private viewportQuadSplit = createDefaultViewportLayoutState().viewportQuadSplit;
|
private viewportQuadSplit: ViewportQuadSplit;
|
||||||
private viewportTransientState = createDefaultViewportTransientState();
|
private viewportTransientState = createDefaultViewportTransientState();
|
||||||
private previousEditingToolMode: Exclude<ToolMode, "play"> = "select";
|
private previousEditingToolMode: Exclude<ToolMode, "play"> = "select";
|
||||||
private readonly history = new CommandHistory();
|
private readonly history = new CommandHistory();
|
||||||
@@ -89,7 +95,13 @@ export class EditorStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor(options: EditorStoreOptions = {}) {
|
constructor(options: EditorStoreOptions = {}) {
|
||||||
|
const initialViewportLayoutState = cloneViewportLayoutState(options.initialViewportLayoutState ?? createDefaultViewportLayoutState());
|
||||||
|
|
||||||
this.document = options.initialDocument ?? createEmptySceneDocument();
|
this.document = options.initialDocument ?? createEmptySceneDocument();
|
||||||
|
this.viewportLayoutMode = initialViewportLayoutState.layoutMode;
|
||||||
|
this.activeViewportPanelId = initialViewportLayoutState.activePanelId;
|
||||||
|
this.viewportPanels = initialViewportLayoutState.panels;
|
||||||
|
this.viewportQuadSplit = initialViewportLayoutState.viewportQuadSplit;
|
||||||
this.storage = options.storage ?? null;
|
this.storage = options.storage ?? null;
|
||||||
this.storageKey = options.storageKey ?? DEFAULT_SCENE_DRAFT_STORAGE_KEY;
|
this.storageKey = options.storageKey ?? DEFAULT_SCENE_DRAFT_STORAGE_KEY;
|
||||||
this.snapshot = this.createSnapshot();
|
this.snapshot = this.createSnapshot();
|
||||||
@@ -171,6 +183,21 @@ export class EditorStore {
|
|||||||
this.emit();
|
this.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setViewportPanelCameraState(panelId: ViewportPanelId, cameraState: ViewportPanelCameraState) {
|
||||||
|
if (areViewportPanelCameraStatesEqual(this.viewportPanels[panelId].cameraState, cameraState)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.viewportPanels = {
|
||||||
|
...this.viewportPanels,
|
||||||
|
[panelId]: {
|
||||||
|
...this.viewportPanels[panelId],
|
||||||
|
cameraState: cloneViewportPanelCameraState(cameraState)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.emit();
|
||||||
|
}
|
||||||
|
|
||||||
setViewportQuadSplit(viewportQuadSplit: ViewportQuadSplit) {
|
setViewportQuadSplit(viewportQuadSplit: ViewportQuadSplit) {
|
||||||
if (this.viewportQuadSplit.x === viewportQuadSplit.x && this.viewportQuadSplit.y === viewportQuadSplit.y) {
|
if (this.viewportQuadSplit.x === viewportQuadSplit.x && this.viewportQuadSplit.y === viewportQuadSplit.y) {
|
||||||
return;
|
return;
|
||||||
@@ -298,7 +325,7 @@ export class EditorStore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return saveSceneDocumentDraft(this.storage, this.document, this.storageKey);
|
return saveSceneDocumentDraft(this.storage, this.document, this.createViewportLayoutState(), this.storageKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDraft(): EditorDraftLoadResult {
|
loadDraft(): EditorDraftLoadResult {
|
||||||
@@ -316,6 +343,11 @@ export class EditorStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.replaceDocument(draftResult.document);
|
this.replaceDocument(draftResult.document);
|
||||||
|
|
||||||
|
if (draftResult.viewportLayoutState !== null) {
|
||||||
|
this.applyViewportLayoutState(draftResult.viewportLayoutState);
|
||||||
|
}
|
||||||
|
|
||||||
return draftResult;
|
return draftResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +369,24 @@ export class EditorStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createViewportLayoutState(): ViewportLayoutState {
|
||||||
|
return cloneViewportLayoutState({
|
||||||
|
layoutMode: this.viewportLayoutMode,
|
||||||
|
activePanelId: this.activeViewportPanelId,
|
||||||
|
panels: this.viewportPanels,
|
||||||
|
viewportQuadSplit: this.viewportQuadSplit
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private applyViewportLayoutState(viewportLayoutState: ViewportLayoutState) {
|
||||||
|
const nextViewportLayoutState = cloneViewportLayoutState(viewportLayoutState);
|
||||||
|
|
||||||
|
this.viewportLayoutMode = nextViewportLayoutState.layoutMode;
|
||||||
|
this.activeViewportPanelId = nextViewportLayoutState.activePanelId;
|
||||||
|
this.viewportPanels = nextViewportLayoutState.panels;
|
||||||
|
this.viewportQuadSplit = nextViewportLayoutState.viewportQuadSplit;
|
||||||
|
}
|
||||||
|
|
||||||
private createSnapshot(): EditorStoreState {
|
private createSnapshot(): EditorStoreState {
|
||||||
return {
|
return {
|
||||||
document: this.document,
|
document: this.document,
|
||||||
|
|||||||
Reference in New Issue
Block a user