The assets and scene objects panels in the left column are split by a draggable splitter that keeps its ratio when the window is resized

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-18 07:29:58 +02:00
1 parent 33a7b1b63e
commit 55bfa7521a
4 files changed
+54 -4

No files matched your search

+20 -3
View File
@@ -115,6 +115,8 @@ const MAX_RIGHT_WIDTH = 600;
// The floor is the console's own header: dragged all the way shut it stays visible to drag open.
const MIN_CONSOLE_HEIGHT = Panel.HEADER_HEIGHT;
const MAX_CONSOLE_HEIGHT = 600;
// Either panel of the left column keeps at least its header, for the same reason as the console.
const MIN_PANEL_HEIGHT = Panel.HEADER_HEIGHT;
/**
* Composes toolbar, panels, viewports and graph editor into the one application that edits and
@@ -151,6 +153,8 @@ export class Editor implements PlayHost {
readonly leftSplitter = new Splitter('x');
readonly rightSplitter = new Splitter('x');
readonly consoleSplitter = new Splitter('y');
/** Between the asset panel and the scene objects below it. */
readonly columnSplitter = new Splitter('y');
private readonly workspace: HStack;
private readonly centre: VStack;
private readonly tabs: TabStrip<TabId>;
@@ -165,6 +169,8 @@ export class Editor implements PlayHost {
private leftWidth = 250;
private rightWidth = 350;
private consoleHeight = 300;
/** The asset panel's part of the left column's height; the scene objects get the rest. */
private assetsShare = 0.5;
constructor(
app: Application,
@@ -219,11 +225,22 @@ export class Editor implements PlayHost {
root.add(this.toolbar);
this.workspace = new HStack();
this.leftColumn = new VStack({ gap: 1 });
this.leftColumn = new VStack();
this.assets = new AssetPanel(state, textures, fonts, sounds);
this.leftColumn.add(this.assets, 1);
this.leftColumn.add(this.assets, this.assetsShare);
installFileImport(app.canvas, { state, textures, fonts, sounds });
this.leftColumn.add(this.hierarchy, 1);
this.leftColumn.add(this.columnSplitter);
this.leftColumn.add(this.hierarchy, 1 - this.assetsShare);
// A share rather than a height, so a taller or shorter window keeps the split the user chose.
this.columnSplitter.onDrag = (delta) => {
const room = this.leftColumn.h - Splitter.THICKNESS;
if (room <= 0) return;
const floor = Math.min(0.5, MIN_PANEL_HEIGHT / room);
this.assetsShare = clamp(this.assetsShare + delta / room, floor, 1 - floor);
this.assets.flex = this.assetsShare;
this.hierarchy.flex = 1 - this.assetsShare;
this.leftColumn.relayout();
};
this.centre = new VStack();
this.tabs = new TabStrip<TabId>(
+6
View File
@@ -264,6 +264,12 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
tabRow: () => editor.tabRow(),
/** The dividers left and right of the centre column – dragging them narrows the tab row. */
panelSplitters: () => ({ left: centreOf(editor.leftSplitter), right: centreOf(editor.rightSplitter) }),
/** The left column: asset panel on top, scene objects below, and the divider between them. */
leftColumn: () => ({
assets: rectOf(editor.assets),
objects: rectOf(editor.hierarchy),
splitter: centreOf(editor.columnSplitter),
}),
viewportCenter: () => centreOf(viewport),
/** Pans the Scene tab to a world point – a step's own lane, away from what earlier steps left. */
lookAt: (x: number, y: number) => viewport.lookAt(x, y),