SwiftUI Native Layouts
Relevant source files
The following files were used as context for generating this wiki page:
- issues/013-apple-native-catchup.md
- issues/014-apple-native-docked-layout.md
- issues/015-apple-layout-skeleton.md
- issues/018-apple-right-panel.md
- issues/019-apple-status-bar.md
- tasks/records/014-basic-swiftui-ui.md
- apple/Dotorixel/Views/TopControlsLeft.swift
- apple/Dotorixel/Views/BottomToolsPanel.swift
SwiftUI Native Layouts represent the evolutionary transition of the Dotorixel Apple native shell from an MVP floating panel system to a structured, docked layout. The primary goal of this system is to achieve feature parity with the web editor while maintaining a platform-native feel on macOS and iPadOS. By leveraging SwiftUI’s declarative syntax, the layout organizes the Metal-based canvas within a responsive framework of toolbars and panels.
The architecture emphasizes a "UI-First" strategy, where modernizing the layout creates the necessary containers for complex features like expanded toolsets, advanced color management, and multi-tab support. This transition replaces the translucent "Pebble UI" aesthetic with an opaque, docked design that mirrors the web's structure while utilizing native SwiftUI controls and size classes for responsiveness.
Layout Evolution: From Floating to Docked
The native shell initially utilized the Pebble UI layout, characterized by a ZStack where floating translucent panels were overlaid on a full-screen Metal canvas. This was replaced by the Docked Layout, which utilizes a VStack and HStack composition to provide dedicated, non-overlapping regions for application controls.
Structural Comparison
The following diagram illustrates the transition from the overlaid ZStack structure to the structured docked regions.
The transition ensures that panels no longer obscure the drawing area and adjoin the canvas directly.
Sources: issues/014-apple-native-docked-layout.md, issues/015-apple-layout-skeleton.md, tasks/records/014-basic-swiftui-ui.md
Core Layout Components
The modern SwiftUI layout is divided into four primary regions surrounding the central drawing area.
Regional Breakdown
| Region | Primary Responsibility | Key Elements |
|---|---|---|
| TopBar | App identity & global controls | Logo, Zoom controls, Grid toggle, Export button |
| LeftToolbar | Tool selection & History | Tool buttons (Pencil/Eraser), Undo/Redo |
| RightPanel | Settings & Color management | Canvas presets, Size inputs, Palette grid, ColorPicker |
| StatusBar | Contextual Information | Canvas dimensions, Active tool name |
| CanvasArea | Interaction | Metal-rendered pixel grid |
Sources: issues/014-apple-native-docked-layout.md, issues/019-apple-status-bar.md
TopBar and StatusBar Logic
The TopBar and StatusBar serve as the header and footer of the application. While the TopBar handles viewport transformations like "fit-to-view" and zoom percentages, the StatusBar is a pure display view that derives its data from the EditorState.
- StatusBar Left: Displays canvas dimensions (e.g., "32 × 32") via the
pixelCanvasstate. - StatusBar Right: Displays the
activeToolname (e.g., "Pencil").
Sources: issues/014-apple-native-docked-layout.md, issues/019-apple-status-bar.md
LeftToolbar and RightPanel
- LeftToolbar: Features a fixed 44pt width to accommodate standard touch targets. It manages tool active states and provides history navigation.
- RightPanel: A 220pt wide panel that supports vertical scrolling. It integrates canvas resizing logic (presets and text input) and color selection (palette grid and native
ColorPicker).
Sources: issues/014-apple-native-docked-layout.md, issues/018-apple-right-panel.md
Data Flow and Component Interaction
The SwiftUI views interact with the underlying Rust core through a UniFFI-generated Swift binding, managed by an @Observable EditorState.
UI updates are driven by the EditorState, which wraps UniFFI objects. For instance, when a user selects a tool in the LeftToolbar, the StatusBar automatically reflects the change by observing the activeTool property.
Sources: tasks/records/014-basic-swiftui-ui.md, issues/019-apple-status-bar.md
Styling and Design Tokens
The layout transition involved a major update to the styling system, moving from PebbleTokens to a new set of DesignTokens that mirror the web's design-tokens.css.
Key Visual Changes
- Opaque Surfaces: Panels moved from translucent overlays to opaque surface colors (
bgSurface). - Solid Borders: Shadow-based panel boundaries were replaced with 1px solid subtle borders (
borderSubtle). - Standardized Sizing: Button sizes were standardized to 44pt to meet Apple's Human Interface Guidelines (HIG) for touch targets.
- Color Tokens: Standardized names such as
bgBase,bgSurface, andaccentare used across platforms.
Button Styles
Two primary ButtonStyle implementations are used within the layout:
- ToolButtonStyle(isActive:): Used for tool selection; displays an accent color when active.
- IconButtonStyle: Used for general actions (Zoom, Grid); features a subtle background on hover/press.
Sources: issues/014-apple-native-docked-layout.md:83-112, issues/015-apple-layout-skeleton.md
Responsive Design Strategy
The SwiftUI layout is designed to handle multiple Apple platforms using size classes:
- Mac and iPad Landscape: These utilize the full docked layout with fixed-width sidebars and flexible canvas areas.
- Adaptive Layout Point: The implementation is structured such that a single point in the code can eventually handle size-class branching for iPad portrait or compact modes without a full architectural restructure.
- Window Resizing: In the Mac target, the
HStackensures theCanvasAreaflexes to fill available space whileLeftToolbarandRightPanelremain fixed at their defined widths.
Sources: issues/013-apple-native-catchup.md, issues/014-apple-native-docked-layout.md, issues/015-apple-layout-skeleton.md
Conclusion
The transition to SwiftUI Native Layouts provides Dotorixel with a scalable foundation for future growth. By moving from floating panels to a docked structure, the project aligns the native Apple shell with the web editor's functional capacity while utilizing platform-specific idioms like native color pickers and size classes to ensure a high-quality user experience.