4.1 KiB
Display layouts
Run either scene with F6:
scenes/layout_landscape.tscn: 1920×1080, 32×18 grid.scenes/layout_dual_portrait.tscn: two independent 1080×1920 windows, each 18×32. With two portrait monitors detected, each window is maximized on its own screen; otherwise, smaller windows open side by side. Disableuse_portrait_monitorsto force the windowed preview.
The reference cell size is 60px. Window scaling is uniform and independent of the project's stretch scale. Physical monitor placement still needs checking on the target hardware.
Editing
Hover briefly in the top-left corner to enter overview. The trigger uses a 20-pixel window area, including letterboxing, independently of UI scale. In dual portrait, only the left window owns the hot corner; both windows enter overview together.
Add element opens a scrollable library. Select an entry and click Add element (or double-click it). Panels use the first free space, falling back to their minimum size if needed. Multiple instances are supported; a full grid leaves the library open with a no-space message.
Select and drag a panel to move it. Selected panels show three buttons:
- ↘: drag to resize from the bottom-right edge.
- ×: remove the panel from this layout.
- ⚙: settings, currently disabled.
Moves and sizes snap to cells. Occupied space, minimum sizes, and window boundaries block invalid placements; invalid drops return to their starting position. Escape or leaving overview cancels an unfinished drag. Panels stay within their own window.
Changes save automatically as JSON under user://layouts/: landscape.json, portrait_left.json, and portrait_right.json. Godot resolves user:// to the application's user-data directory (the XDG data location on Linux), available from OS.get_user_data_dir(). To store files beside a writable application instead, set each canvas's config_path to an absolute path in that folder. Existing .cfg layouts migrate on first load when no JSON file exists; the originals are retained. Reset layout restores default positions, sizes, and deleted panels. Exit with Escape, Return to dashboard, or a click outside the preview.
JSON format
{
"version": 1,
"grid": [32, 18],
"elements": [
{"id": "camera", "type": "camera", "rect": [0, 0, 16, 10]}
]
}
The elements array is the complete active layout; omitted default panels stay deleted. IDs distinguish repeated instances. Writes use a temporary file followed by rename. Invalid types, duplicate IDs, overlaps, and out-of-bounds rectangles are rejected before changing the displayed layout.
Scene structure
layout_overview.tscn owns the shader grid and toolbar. Each layout_canvas.tscn places its panel children using layout_item.gd; set their IDs, cell rectangles, and minimum sizes in the Inspector. Existing UI scenes remain under each item's Content node. Each allocation has a full-size panel background with a shared panel_gap (16 logical pixels by default). Instruments scale uniformly inside that frame; reserved slots fill it. Embedded component backgrounds are transparent so their scaling does not change the visible gutters. The camera retains its 16:9 picture inside the camera/header allocation.
The initial layouts deliberately leave free cells for rearranging. VR/video and operator tools are placeholders. The Link and Environment panels have separate Link and Environment telemetry demos. The Console is available in the library with four tabs and direct focus shortcuts. Camera and telemetry feeds are not connected.
The library registry is scripts/layout_catalog.gd. Each entry supplies a scene, display text, preferred/minimum cells and sizing behavior. JSON stores registered type IDs rather than resource paths. components/layout_library.tscn owns the drawer; selection button order is unchanged.
LayoutItemBackground supplies the shared outer frame. Components with a separate background node can specify background_path on their item (or background in the catalog entry); root PanelContainers are embedded automatically. Standalone component scenes retain their own styling.