Files
solvecraft/docs/ui-container-audit.md
T
Lars Jansen 4a0d519727 View: OK and Cancel in the corner of the view while a dialog or sketch is open (#6709) (#6714)
* claim: #6709

* feat(view): OK and Cancel in the corner of the view while a dialog or sketch is open (#6709)
2026-10-26 10:40:36 +00:00

8.2 KiB
Raw Blame History

Layout-aware container audit

Shared container foundation (#4411) and compact composition (#2029), on top of History #3953 and Assistant #3985. Interface preferences save Floating or Compact; view.layout changes the same preference without changing the design.

Ownership

ui_kit::Container is the only production constructor for outer egui hosts in the UI crate and the desktop/web apps. Surface declares purpose, not a second layout setting. The shell publishes LayoutMode before drawing any page. Adaptive panels and shell layout use Container::floating(); frames use the same policy. There is one definition of floating/compact chrome and workspace gaps in ui_kit/container.rs. Compact joins the workspace and ribbon, puts Browser flush beneath it with a square join and content-hugging height, and opens feature/palette sheets at their edge without card gaps or shadows. Tool sheets remain draggable in either layout; compact sheets round all four corners when detached and square only the right corners at their right dock. Contacts declare which edges meet; the container rounds only exposed convex corners and collapses adjoining outlines into one stroke. Stacked headers cover the viewport without reserving a blank column beneath them. Floating keeps its card chrome; both layouts retain tool drag offsets. Menus, system windows, notifications and canvas content retain their existing roles.

The shell still owns ordering, viewport reservations and shared-column geometry. A container does not infer geometry from a title or panel ID. Browser and History share a column width; Assistant remains outermost on either side. Tool sheets may overlap Browser and History, but cannot enter Assistant’s reserved rail or cover the ribbon/workspace selector. Those relationships must survive the compact composition. Existing Panel, Window, Confirm and Menu are content compositions over the universal container, not alternative hosts. The low-level window builder is visible only inside the UI kit: feature and platform windows use the shared composition, including its header and fixed outer frame.

Inventory and migration

Surfaces Owners / composition Container policy
Browser, vertical History and Browser/History shared column browser, timeline_left, lib Adaptive panel; shared shell placement, resizing and fold state remain with owners
Horizontal History timeline Adaptive panel surface; floating strip or bottom dock
Assistant sheet and folded strip agent_chat/panel → Panel Adaptive feature surface; left/right position, resize, drag targets and native pop-out retained
Feature forms, Parameters, material review, Redefine Sketch Plane dialogs, params_dialog, material_card_review, sketch_attachment_ui → Panel Adaptive feature surface; bounded anchors and pinned actions retained
Sketch options sketch_palette → Panel Adaptive palette surface, preserving transparency
Application bar, workspace and ribbon toolbar, shell Chrome hosts; adaptive card geometry comes from the shared policy
Render settings render_workspace Panel host; existing right dock retained
Preferences, managers, About, update/install/recovery/crash/issue prompts Window, Confirm System windows and modal sheets retain modality; these are not workspace sidebars
BOM, Messages, mouse gestures, 3D mouse calibration respective modules → Window::show_body Shared header, tokenised frame and bounded body; native egui title bars/resize highlights and legacy report/width helpers removed
Web stored-files and web recovery windows apps/solidcraft-web → Window::show_body Same shared composition; recovery requires an explicit choice and cannot be dismissed through the header
File/workspace/document/Help/context/overflow menus, radial menu, Select Other and inline rename respective owners → Menu / container popup Anchored transient hosts; never consume workspace dock space
Search, completions, colour and library popovers shortcut_box, kit fields/choice/colour/table Anchored popup containers; editor focus and completion semantics retained
Dimension values, canvas placement values, canvas feedback and History resize seam dim_view, sketch_dims, canvas, timeline_left Model/control-anchored overlays; retain their coordinates rather than becoming docks
Status and loading/progress messages viewport, open_meshing Notification surfaces independent of layout
Navigation bar viewport Shared navigation surface; shell still computes its available canvas bounds
OK and Cancel in the view's corner view_confirm Navigation surface in its own area; the viewport layout reserves its corner and the shell counts it as covered
Home, model viewport, Render canvas and native Assistant window content home, lib, agent_chat/panel Central content hosts, not floating workspace panels
Loading input shield file_load Explicit input shield; must remain interactive while CAD input is blocked

The compass, geometry previews, drag handles, selection outlines, dimension lines, charts and thumbnails are drawn content, not independent card hosts. Giving them workspace docks would be incorrect. egui-managed tooltips and widget internals remain with their owning shared widget. OS file/program/colour pickers and native viewport creation remain host services, not in-app panels.

Enforcement for additions

cargo xtask ui-containers is the mandatory repository gate, implemented once in xtask/src/ui_containers.rs. The fast CI job runs it and its regression tests before approval for heavy UI tests; cargo xtask ci runs it too. Draft PRs retain the repository’s normal CI policy. It recursively parses Rust source and examples under every crate and app, so new packages and nested modules are included automatically. The sole constructor implementation exception is the exact ui_kit/container.rs path.

The gate rejects raw Area, Panel, Window, Modal, CentralPanel, Popup and SubMenu constructors, imported/module/type aliases and re-exports, constructor function references, qualified default constructors, struct literals, macro-hidden hosts and popup shortcuts. Host APIs are default-denied except for explicit popup-state operations, so new egui constructors are rejected automatically. Private raw host/module imports are rejected too, preventing aliases from escaping into another source file. It also rejects raw outer popup/window frames and custom outer shadows. Invalid Rust fails closed. Read-only state queries, content-only frames, and test-only fixtures remain valid; there are no per-feature allowances. This enforces the construction boundary; surface purpose and hand-painted content still need ordinary review.

New workspace panels must declare an adaptive Surface and use this policy for host choice and outer chrome. Do not introduce another layout bool, raw host, shadow or mode-specific frame in the feature module. Body groups, message bubbles, field backgrounds and image frames are content; they may use local zero-shadow frames or existing kit controls. Add new surface policies in the universal module and test both modes and themes. Never add a per-file allowance to bypass the guard.

Retired implementation cleanup

The old report-window builder, window-width enum, heading-band colours and caller-coloured icon API have been removed. Theme palettes and built-in theme files no longer carry procedural command-icon colours; SVG artwork has one palette authority. Only marker/pointer colours remain in the native glyph palette. Older theme exports discard retired colour names at import so active overrides still work; these names do not create renderer tokens or appear in new exports. Unused History height state and superseded click/preview/modifier helpers are also removed. The remaining frame helpers implement dragging and bounded anchors used by current Panel compositions, rather than a second host or style. Buttons and editors use shared kit controls too, including Assistant code-block actions. The control guard scans all UI feature modules, even without a kit import, so adding a new module cannot silently bypass the shared controls.