3.1 KiB
3.1 KiB
Iced Architecture Patterns (bDS Rust Rewrite)
Iced 0.13, wgpu renderer, muda for native menus, rfd for file dialogs.
Message Design
- Root
Messageenum inapp.rs:MenuEvent(MenuId),Noop, plus child view variants. - Child view messages wrapped in parent enum variants:
Message::Editor(editor::Message). - Keep messages flat where possible -- avoid deep nesting beyond two levels.
- Use
Task<Message>for async operations (file I/O, dialogs, database queries). - Noop absorbs events that need no action (e.g., unhandled menu IDs).
Subscription Model
- Menu events:
iced::event::listen_withpollingMenuEvent::receiver().try_recv()each tick. - Future: filesystem watcher subscription for external db/file changes.
- Subscriptions are declarative --
subscription()returns the full set every frame; Iced diffs internally. - Each subscription keyed by a unique ID to avoid duplicates.
Custom Widget Pattern (CodeEditor)
- Implements
iced::advanced::Widget<Message, Theme, Renderer>. - Persistent state via
widget::tree::StateholdingEditorState(cursor pos, selection, scroll offset). tag()returnsTypeId::of::<EditorState>()for widget tree identity.state()returnsState::new(EditorState::default())for initialization.on_event()handles keyboard/mouse input, returnsStatus::CapturedorStatus::Ignored.draw()usesrenderer.fill_quad()for backgrounds/cursors/gutters,renderer.fill_text()for content.- Takes
&mut EditorBufferreference for direct mutation on input -- buffer is not owned by the widget. - Focus management:
is_focusedflag inEditorState, set on mouse press inside bounds, cleared on press outside.
Platform Integration
- muda menus built once at startup; call
init_for_nsapp()on macOS before event loop. - Menu IDs stored in a map (
HashMap<MenuId, Message>) for routingMenuEventto appMessage. - macOS lifecycle hooks (
application:openFile:,openURLs:) via objc2 -- deferred to M2. - rfd dialogs:
rfd::AsyncFileDialogspawned behindTask::perform, result mapped to aMessagevariant.
Rendering
- Iced uses cosmic-text internally for text shaping and layout.
- Custom widgets call
renderer.fill_text()with aTextstruct: font, size, bounds, horizontal/vertical alignment. - Use
Font::MONOSPACEfor the editor, default system font for UI chrome. renderer.fill_quad()for solid-color rectangles: backgrounds, cursor bar, gutter column, selections.- Clipping: call
renderer.with_layer()to restrict drawing to widget bounds.
State Management
- Top-level app state lives in
BdsAppstruct (db connection, open buffers, UI flags). - Child widget state in
widget::tree::State-- survives acrossview()calls as long as widget identity matches. EditorBuffer(rope-based text buffer via ropey) owned byBdsApp, passed as&mutto widget onview()andon_event().- Database connection (
bds_core::db::Database) opened once at startup, held inBdsApp, not cloned. - No global mutable state -- everything flows through the
Message->update()->view()cycle.