Arranging and windows
The code decides what exists; you decide where it's shown. None of this changes paths or values, and it's saved per page (separately from values).
- Pin any row or folder from its menu (right-click, or long-press on touch): it shows at the top of the panel. It's the same control as the one in its folder: same value, history and modified dot.
- Groups: New group with this… from a row's menu, then Add to “…” from other rows. Groups can be renamed, reordered, collapsed and floated.
- Arrange rows…, from the panel's or a window's own menu (right-click its title, or hold a finger on it), shows a grip on every row in that window: drag to reorder within a folder, drop onto a group to add it there, drag a folder or group out to open it in a window. Hold it near the top or bottom of a list and the list scrolls. ↑/↓ on a focused grip moves it. Done (or Esc) ends it.
- Folders move by their header too, without arranging: drag one and a line shows where it would go, in its folder, inside another folder or onto a group, and it goes there when you let go.
- Windows: drag a folder header out of the panel, or choose Open in window. See below.
- If a control disappears (HMR, a code edit), its pins, groups and position are kept for when it comes back. Clean up layout removes entries for paths that no longer exist.
From code: gui.layout.pin(path), createGroup(title, paths), addToGroup(id, path), moveChild(folder, node, index), openWindow({ folder }), clean(exists).
Windows
The panel, folder and group windows, and texture inspectors are all windows:
- Snapping: drag one by its title (the panel by its header) near an edge or a corner of the browser window and it snaps there. Let go and it stays held to that edge as the browser window resizes.
- It glides into a snap rather than jumping, and out of one as you pull it free: the window keeps to the pointer, and a spring takes up the difference. A held edge lights up as it snaps.
- Drag it away to free it.
- Hold ⌘/Ctrl to drag without snapping.
- Resizing an edge snaps it the same way.
- Docking at a side: drag a window so the pointer meets a side of the browser window, as you would on a desktop, and an outline shows where it'll go. Let go to dock it there: full height at the left or right, or across the top or the bottom at its height. Move away (or Esc) and it doesn't. ⌘/Ctrl turns this off too.
- The panel:
- By default it's a side panel growing down, as it always was.
- Shrink its bottom edge to give it a set height. Drag the edge back to the bottom and it holds there; double-click it to follow the content again.
- Dock left / right / bottom, Float panel and Reset panel position are in the menu and the palette.
- On a phone it starts as a bottom sheet.
- Composing: windows snap to each other too, side by side or lined up. A window held to another moves with it: stack an inspector under the panel, or put side panels left and right with a window spanning between them along the bottom.
- The gap between held windows resizes both.
- Held windows stack as one: bring one to the front and the rest come with it. A window in front of them is in front of the gap between them too.
- Closing a window passes its place on to the ones held to it.
- Reset window layout puts everything back.
- A window's own menu (right-click its title bar, or hold a finger on it; the panel's header too): arrange its rows, dock it to a side, close it (a folder's goes back into the panel). The panel's also docks, floats, minimises, hides or pops it out.
- Folders: drag a folder's header out of the panel (or a window), and it becomes its own window under the pointer as you drag. It leaves the list it was in while it's in its window; closing the window brings it back.
- Drag that window by its title back over a panel, and a line shows where it would land: back in its place, elsewhere in its folder, or inside another folder. The list it would go into lights up.
- Hold it near the top or bottom edge of that list, where the list scrolls, and it scrolls (faster nearer the edge), to reach places out of view. Move away from the edge and it stops.
- Only where it's taken: over a window that doesn't take it, a tool's like the frame capture, it just moves (and snaps). A tool's own folders (the capture's inputs) go back only into it.
- Inside another folder, it's only shown there. Its path, values and code are unchanged, and its menu has Move back.
- Tools (the frame capture, its Vertices window, texture inspectors) don't go into lists: dragged over the panel or another window, their own folder's included, they just move, snap and dock at a side like any window. Close one to put it back.
- Keyboard: with a title focused, the arrows move it, ⌘/Ctrl+arrows snap it to that edge, and Shift+arrows resize it. F6 moves between windows.
From code:
gui.openWindow('Scene/render', { dock: 'bottom' }); // or 'left', 'right', 'top'
gui.openWindow('Material', { beside: 'panel' });
gui.openWindow('Performance', { corner: 'top-left', size: { w: 260, h: 280 } }); // any corner
gui.openWindow('Scene/albedo'); // a texture row: its inspector (a group: by its id)
// what windows docked full length along each edge cover, to keep your subject clear of them
gui.on('insets', ({ bottom }) => (canvas.style.height = `calc(100% - ${bottom}px)`));
What a folder's window can be dropped into is the folder's to say, with its drops hint: what it is (kind), and the kinds it takes (accepts). Unset, a folder is what its folder is and takes what its folder takes; at the top, a 'folder' that takes folders. Its own folders of its kind go back in.
// a tool: its window goes into no list (its own folder's neither: closing it puts it back), and
// nothing goes into it; the folders in it, its parts, go back only into it
gui.folder('Tools', { drops: { kind: 'tool', accepts: [] } });
// a shelf for tools as well as folders
gui.folder('Shelf', { drops: { accepts: ['folder', 'tool'] } });
A folder's window is a list: as tall as its rows, the height you give it at most. One whose rows are a tool that changes as you work in it (the frame capture, stepped through draw by draw) keeps the size you give it instead, its rows scrolling inside, with the window hint:
gui.folder('Inspector', { window: 'tool' });