# 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. Disable `use_portrait_monitors` to 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 ```json { "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](link_panel.md) and [Environment](environment_panel.md) telemetry demos. The [Console](console_panel.md) 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.