Skip to main content

Crate day_core

Crate day_core 

Source
Expand description

day-core — the Piece model, realized tree, mounter, layout engine, and event routing (DESIGN.md §5, §7). Build-once: pieces are constructed exactly once; all dynamism flows through reactive bindings (day-reactive) writing to the thread-local tree.

Re-exports§

pub use frame::FrameConsumer;
pub use frame::add_frame_consumer;
pub use frame::frame_consumer_count;
pub use frame::install_frame_requester;
pub use frame::remove_frame_consumer;
pub use lifecycle::dispatch_lifecycle;
pub use lifecycle::lifecycle_supported;
pub use lifecycle::on_lifecycle;
pub use list::BuiltRow;
pub use list::ListDriver;
pub use list::ListReorderDriver;
pub use list::install_list;
pub use list::list_reload;
pub use list::list_scroll_to_end;
pub use list::list_scroll_to_row;
pub use list::list_set_selected;
pub use list::list_try_reorder;
pub use menu::dispatch_menu_action;
pub use menu::register_menu_action;
pub use menu::set_app_menu;
pub use toolbar::dispatch_toolbar_value;
pub use toolbar::patch_toolbar;
pub use toolbar::patch_window_toolbar;
pub use toolbar::register_toolbar_value;
pub use toolbar::set_toolbar;
pub use toolbar::set_window_toolbar;
pub use windows::WindowHandle;
pub use windows::finish_window_open;
pub use windows::focused_window;
pub use windows::open_new_window;
pub use windows::open_preferences;
pub use windows::open_window;
pub use windows::register_new_window;
pub use windows::register_preferences;
pub use windows::register_preferences_with;
pub use windows::window_by_key;

Modules§

frame
Frame clock / continuous-animation driver (§8.4, docs/animation.md).
lifecycle
App-lifecycle callbacks (docs/lifecycle.md). An app registers closures for day_spec::Lifecycle phases with on_lifecycle; each backend, at the matching moment in its native app/activity delegate, emits Event::Lifecycle(phase) (or day-core dispatches the launch phases uniformly), and the event pump routes it here to run the closures inside a reactive batch — the same rails as Event::MenuAction, so a lifecycle handler that writes signals updates the UI like any callback.
list
Recycling-list driver (docs/list.md, §10). The native list host owns scrolling + cell reuse; Day owns row content. day-core injects a day_spec::ListSource into the backend; when the native data-source pulls a cell, bind_row builds it once (per physical cell) and thereafter rebinds it — one slot-write — as the cell recycles.
menu
Menu action dispatch (§ menus). The MODEL (day_spec::MenuItem) is toolkit-neutral and carries only ids for its actions; the real closures live here, keyed by id. A backend fires Event::MenuAction(id) when a native item is chosen; the event pump routes it to dispatch_menu_action, which runs the app’s closure. Ids are process-unique and monotonic.
shield
The system-gesture / interactive-dismiss shield (docs/cover.md): the registries behind the defers_system_gestures and interactive_dismiss_disabled modifiers. Each mounted modifier pushes an entry while its subtree is alive; the union of entries is the app’s current request.
toolbar
Window toolbars (docs/toolbars.md). The MODEL (day_spec::ToolbarItem) is toolkit-neutral and carries only ids for its commands; the real closures live here, keyed by id — the same shape as crate::menu, and deliberately the same id space, so one closure can back both a toolbar button and its menu-bar twin.
windows
Secondary windows (docs/windows.md): the app-facing open_window API, the per-window registry, and the fallback that presents window content as a fullscreen cover where the toolkit cannot open windows (Cap::MultiWindow = Unsupported).

Structs§

AnyPiece
Type-erased piece for heterogeneous branches and dynamic construction.
AssetName
The bundled-data name that resource resolves by (the full file name, extension included).
BuildCx
CoverLayout
Fullscreen cover (docs/cover.md): the COVER node occupies no space where it sits in the tree (its native surface is presented over the window, outside the parent’s bounds), and its content is laid out at the size the backend reported via Event::FrameChanged — the same native-owned-frame contract as NavLayout pages.
EngineCx
FillThrough
Paint/clip wrapper (.background, .corner_radius, the animatable layers): like PassThrough for measurement, but the GRANTED rect flows to the child verbatim at place time — these containers exist to paint or clip the area the parent granted, so a grow stretch above them must reach the painted surface (the grid-cell card case) instead of being re-hugged at every wrapper. Under a parent that places at measured size — every stack, grid rigid cell, and overlay — bounds equal the measure and nothing changes.
Flex
Read-only layout facts a parent may consult about a child (§7.2 ChildRef).
FontFamily
The family name of a bundled custom font, feeding Font::custom. Holds a &'static str (so Font stays Copy); generated res::fonts::… constants supply it. The untyped Font::Custom(&'static str, f64) variant remains the escape hatch for a family known another way.
FrameLayout
GridFacts
Per-node grid facts (docs/grid.md), carried on Flex — the shipped form of the §7.2 ChildRef facts surface. Set at build time by grid_row and the .grid_span/.grid_align modifiers; only GridLayout reads them.
GridLayout
SwiftUI-style grid negotiation (docs/grid.md): columns are inferred from grid_row children, a column’s width is the max ideal width of its span-1 cells, a grow_w cell makes its column flexible (leftover width split evenly — the StackLayout share rule), and a non-row child is a full-width cell spanning every column. spacer() is an inert empty cell. The contract: exactly two measure proposals per cell per layout — unconstrained (pass A) and at the final column width (pass B) — and place re-runs the same proposals, so it measures from cache.
GrowLayout
The grow/grow_w/grow_h decorators (§5.2): a single-child wrapper carrying grow Flex so the parent stack OFFERS it the space, and a greedy measure/place so the child actually FILLS it. Non-grown axes hug the child (like frame(maxWidth: .infinity) on one axis).
ImageName
The bundled-image name that image callers resolve by (the file stem).
LeafLayout
Native leaf: measurement delegates to the toolkit.
MaxWidthLayout
The .max_width(w) decorator (docs/layout.md): proposes at most w to the child, so text wraps instead of overflowing, while narrower content still hugs. The vertical axis passes through untouched.
NavController
A mounted host’s control surface. Closures run user code (route builders), so the registry NEVER holds a borrow across a call (§3.3 discipline: clone the Rc out, then call).
NavLayout
Navigation host (docs/navigation.md): page FRAMES are native-owned (splitter panes, nav-controller views), so set_frame on pages is a toolkit no-op; Day lays each page’s CONTENT within the size the toolkit last reported via Event::FrameChanged, falling back to a sidebar/detail split (or the full host) of the host bounds.
NavToken
Opaque handle from register_nav; a nested host calls unregister_nav on dispose.
NodeData
NodeProbe
Cached last-applied props for the dayscript element index (§14.2).
OverlayLayout
Z-layering (§overlay): children share the container bounds, stacked back-to-front in child order (first child = bottom of the z-order), each positioned by a single Alignment. size_to_first reports only the FIRST child’s natural size — the badge/annotation sizing of overlay (the annotation does not grow the frame); otherwise the layout reports the UNION (max) of all children’s natural sizes — the ZStack sizing of zstack. No native work: the container is the same panel as column/row, so backends stack children by attach order.
PaddingLayout
PassThrough
Single-child pass-through (root, wrappers, group fallback): top-leading.
PieceVec
Runtime-heterogeneous children (column_vec-style call sites).
PresentFuture
RNode
Realized-node key. NodeId (the spec-boundary id) is its FFI encoding.
Resource
A handle to a bundled resource’s bytes with efficient random read-only access.
ScrollLayout
Scroll viewport (§7.6): greedy on the proposal; content measured unconstrained on the scroll axis and reported via set_scroll_content. Children are placed in the scroll’s content coordinate space (the scroll node is their native ancestor).
Sleep
Future returned by sleep.
StackLayout
Column/row negotiation (§7.2): rigid children first, remaining main-axis space divided among flexible children; spacer() is maximally flexible; group anchors expand inline.
TaskHandle
A handle to a spawned task. Copy and !Send (the executor is thread-local).
Tree
VectorName
The bundled-vector name that vector callers resolve by (docs/vectors.md): the stem of a resource/vectors/ SVG (or .symbolset bundle). Vectors and images share one per-backend resolution namespace — staging guarantees every vector name resolves as whatever form that backend loads natively (a VectorDrawable, a catalog entry, a rasterized PNG).

Enums§

Alignment
Two-axis placement of a child within a container’s bounds (SwiftUI’s Alignment). Used by the z-layering primitives (OverlayLayout): zstack, overlay/overlay_aligned.
Axis
Boundary
Measure-invalidation boundary (§7.4): Yes stops upward needs-measure propagation (scroll viewports, nav pages). Named enum instead of a bare bool at call sites (docs/api-style.md).
CrossAlign
ScrollTarget
A programmatic scroll destination (§7.6, docs/scroll.md). Edges are axis extremes (Top/Bottom vertical, Leading/Trailing horizontal — start/end in layout direction); Offset pins the viewport origin to a content-space point (clamped by the platform); Id reveals the element with that dayscript id inside its nearest enclosing scroll.
WindowRootReply
TreeOps::open_window_root’s answer — the tree-level face of day_spec::WindowOpenReply, carrying the adopted (or parked) root node.

Constants§

NAV_SIDEBAR_WIDTH

Traits§

Layout
Open layout protocol (§7.2). children are the node’s direct children; group nodes (when/each anchors) are layout-transparent — stacks expand them inline.
LayoutOps
The engine surface visible to Layout implementations.
NavStore
A key/value sink a nav surface’s .restore persists its state through, so navigation survives a relaunch or an Android process death (docs/navigation.md). The framework never installs one — an app opts in by installing a store (e.g. day_part_prefs::install_nav_store) and marking the surfaces it wants remembered with .restore(key). With no store installed, .restore is a silent no-op, so a surface’s .restore call never fails to build.
Piece
A UI description consumed once (§5.2). Returns the root realized node it created.
PieceSeq
Children of a container: a tuple of pieces (the floem ViewTuple pattern — implemented ONLY for tuples, (), and PieceVec, never via a blanket, to stay coherent).
TreeOps

Functions§

app_temp_dir
An app-writable scratch directory (docs/files.md) — re-exported from day_spec::present so day_core::app_temp_dir() keeps working for the pieces layer’s file-save staging. An app-writable scratch directory: the backend-supplied one, else std::env::temp_dir(). Used by the file-save flow (docs/files.md) to stage bytes before the native save picker.
backend_name
The compile-time target key of the running backend ("macos-appkit", "ios-uikit", …, the Platform::TARGET string), recorded by launch_with. None before launch.
capability
Query the active toolkit’s support for a capability (docs). Lets app/piece code adapt its own content to the backend — e.g. a page can skip a title the native nav already shows in a header (Cap::NavHeader), or pick a presentation from Cap::NavSplit.
clear_controllers
Drop every controller — a fresh mount / test boot (called from tree install/uninstall).
current_anim
The ambient animation set by the innermost enclosing with_animation, if any.
current_route
The FULL current route: every mounted surface’s contribution, outermost to innermost, /-joined (docs/navigation.md). None = no surface mounted; Some("") = everything at its root. Round-trips through navigate, so persisting navigation state is save(current_route()) on the way out and navigate(&saved) on the way back in.
dark_mode
Whether the platform is rendering in dark appearance (see Toolkit::dark_mode): the branch apps take when painting custom OPAQUE surfaces so fills track the theme that the default text colors already follow.
debug_title_tag
The development tag every window title carries in a DEBUG build: (<version>/<toolkit>[/<script>])(1.1.0/appkit), or (1.1.0/gtk/walkthrough.yaml) while a dayscript is driving. With several apps, toolkits and scripted runs open at once, the title bar is the only place that says which window is which.
direction_of_locale
The writing direction a locale implies (language subtag match).
encode_route
Assemble a route string from segments and params — the inverse of parse_route. Reserved characters (/, ?, &, =, %) in segments and params are percent-encoded.
enqueue_event
The enqueue-only event sink installed into every backend (§8.3). May be invoked re-entrantly from inside any Toolkit method; dispatch happens at the next safe point.
enqueue_events
Enqueue several events into ONE drain before dispatching. Backends that observe a focus move at a single point (Qt’s focusChanged(old, new), an AppKit first-responder change) deliver the loss+gain pair through this so the pump can dispatch the gain first and a shared group signal never passes through None (docs/focus.md).
has_launch_deeplink
Whether a launch deep link is pending (DAY_DEEPLINK or a platform hint). A nav surface’s .restore reads this so a deep link wins over restored state (docs/navigation.md).
has_tree
id_of
Resolve a dispatched NodeId back to the app-authored .id() string that named its node (find_by_id’s inverse, §5.5), or None for an id-less node or one no longer in the tree. The recorder (day::record, §14.6) calls this from inside its event observer to label a tap/input with the id an app would target in a dayscript step. Borrow-safe: returns None rather than panicking if the tree is momentarily borrowed by a re-entrant backend call.
id_to_rnode
install_tree
invalidate_size
Tell layout that a node’s intrinsic size may have changed. For tweaks (docs/tweaks.md): after a native call that alters a widget’s preferred size (fonts, tick marks, bezel styles), the measure cache along the node’s path must be invalidated — Day can’t see native mutations it didn’t make. Relayout runs at the next turn boundary as usual. No-op on a disposed node.
is_rtl
Whether the app is being rendered right-to-left (docs/localization) — a convenience over layout_direction. The layout engine already mirrors widget placement under an RTL locale, but a canvas draws in its own coordinate space, so a custom drawing that has a reading direction (a battery that drains one way, an arrow, a progress sweep) can call this to mirror itself. Fixed for the life of the process, like layout_direction.
label_of
A human-readable label for a node, for annotating a recorded script (§14.6): the accessibility label if one is set (.a11y(label = …), the localized string the screen reader speaks), otherwise the control’s own visible text. None when the node carries neither.
launch_with
Launch a Day app on the given platform backend: sets up the reactive scheduler and the cross-thread poster, mounts the root piece into the window’s content container, runs the initial layout, and installs the turn-end layout callback (§3.3). The backend then owns the native main loop.
layout_direction
The app-wide layout direction (docs/localization): mirrors every horizontal placement in the place pass when [day_geometry::LayoutDirection::Rtl]. Resolved lazily from the DAY_LOCALE launch environment (so toolkits can read it before any UI exists); set_layout_direction (called by install_locales for the resolved locale) overrides. Fixed for the life of the process — switching locale at runtime does not re-mirror.
nav_back
Pop one level, day-initiated (the toolkit presents the pop). Native-initiated pops arrive as Event::NavBack and go through the owning host’s pop directly.
nav_store_load
Read a .restore key through the installed NavStore (None if none is installed or the key was never saved).
nav_store_save
Write a .restore key through the installed NavStore (a no-op if none is installed).
navigate
Navigate to a route (docs/navigation.md).
note_appearance_changed
Re-read the toolkit’s appearance into the reactive dark_mode signal. Backends call this when the SYSTEM appearance changes under a running app (macOS theme switch, GTK style-manager change), and set_appearance calls it after applying an override — so closures reading dark_mode() recolor live instead of going stale until a rebuild.
note_navigation
Announce a navigation to route from its SOURCE — a nav host (the sidebar selector) calls this the instant it changes the bound selection, so the observer sees it synchronously instead of waiting for the route to settle into NAV_STACK a frame later (which maybe_notify_route_change reads). Deduped like the pump-boundary path. route is the host’s local key, which replays as a relative navigate (innermost-first) — correct for both a top-level sidebar and a nested one.
open_url
Open url in the platform’s default handler (system browser for http(s), mail client for mailto:, …). The seam behind the link piece; call it directly from a tap handler for a custom affordance. Fire and forget — no result, unopenable URLs are ignored by the backend.
parse_route
Split a route string into its path segments and query params. Segments and param names/values are percent-decoded (%2F/, …); everything else is taken literally.
pending_presentation
The most recently opened still-pending presentation, for dayscript inspection/response.
piece_fn
A piece from a closure.
present
Present a native modal and await its answer (docs/dialogs.md). The pieces layer wraps this in Alert/confirm/prompt; call it directly for a custom PresentSpec.
pump_events
Dispatch queued native events (see [pump_events_inner]), CONTAINING any panic. Native event callbacks reach Day through extern "C" signal trampolines (GTK’s value_changed_trampoline, Qt’s event filters, …) that ABORT the process on unwind (panic_cannot_unwind). A panic in a Day event handler or its reactive drain — e.g. the reactive-cycle assertion firing during a slider drag — would therefore SIGABRT the whole app instead of surfacing. Catch it at this single backend-agnostic boundary, log it (the message carries the offending effect’s source location), and reset the runtime so the app keeps running (degraded) rather than crashing.
pump_generation
The current pump generation (see PUMP_GEN). Read by the recorder’s nav coalescing.
rc_layout
Helper for constructing shared layout Rcs.
register_nav
Install a controller (innermost = last). Returns its token. The root nav() registers once and never unregisters; nested hosts (tabs() in a route) unregister when their scope disposes.
request_route
Ask the app to navigate, from anywhere, at any time.
resolve_presentation
Deliver a native answer (the modal already dismissed itself). Called from pump_events on Event::PresentResult.
resource
Open a bundled resource by name for efficient random read-only access.
respond_presentation
Answer a still-open modal programmatically (dayscript). Resolves with the given result FIRST (removing the pending request), then dismisses the native control — so the native dismissal’s own completion event finds nothing pending and is a no-op. False = no such pending request.
rnode_to_id
route_param
The value of one query param of the most recent navigate (None = not present).
route_params
The query params carried by the most recent navigate call (?name=value&…). Read them inside a destination builder: route_param("id"). They describe the navigation in flight — a push you perform by writing a path signal directly carries its data in your own state instead (docs/navigation.md).
safe_area
The window’s safe-area insets, in points. Zero on every backend that clamps Day’s root to the safe area natively (the default everywhere); nonzero only where a backend runs the root edge-to-edge — today day-android’s opt-in immersive mode (docs/layout.md, the android platform page). Compose it yourself where a background should run under the system bars: paint the background unpadded, pad the content by these insets. The read is tracked, but layout attributes like .padding capture the value at build time — a mid-run inset change (rotation) does not re-pad already-built pages.
scroll_to
Imperatively scroll a scroll piece (docs/scroll.md): node is the SCROLL node for edge and offset targets (ScrollTarget::Id ignores it and reveals the named element in its own nearest scroll). Animated on-screen; dayscript uses the unanimated variant for determinism. Call with no tree borrow held.
set_appearance
Override the app’s appearance: Some(true) dark, Some(false) light, None follow the system again. On backends reporting Cap::Appearance the native widgets restyle in place and dark_mode answers the override; app-painted surfaces pick it up on their next rebuild. Other backends ignore the call — probe before offering a theme picker.
set_contained_panic_observer
Register the contained-panic observer. First registration wins; later calls are no-ops (there is one crash reporter per process).
set_event_observer
Install (or clear, with None) an observer that sees every event day-core dispatches, in queue order, at the one point EVERY backend funnels native events through (enqueue_events, §8.3) — BEFORE the event reaches the app, so it observes exactly what the app receives. This is the recording/telemetry seam behind day::record (§14.6): a higher layer captures user actions into a replayable dayscript without touching any of the backends. Main-thread only; a None observer adds no cost to the event path. The boxed closure is adopted into an Rc internally so enqueue_events can call it with no borrow held.
set_launch_deeplink
Record the host’s launch deep link before launch_with runs (docs/navigation.md). Platform glue only — apps navigate with navigate. DAY_DEEPLINK, where a process environment exists, takes precedence.
set_layout_direction
Override the layout direction (normally from install_locales). Must be called before the first layout pass to take effect everywhere.
set_nav_observer
Install (or clear, with None) the navigation observer. Resets the dedup baseline so the next change fires regardless of where recording started.
set_nav_store
Install the app’s navigation persistence store (docs/navigation.md). Call once at startup, before the UI mounts, so a .restore surface reads it on first build. A later call replaces the store.
set_resource_opener
Register the active backend’s resource opener (Android AAssetManager, GTK GResource, Qt QResource, ArkUI rawfile, …). Called once during backend init. A second call is ignored, so a backend that shares the default file opener need not call this at all.
set_safe_area
Backend-facing: report the window’s safe-area insets (points). Call from the native inset pass whenever the value changes; apps observe it through safe_area.
sleep
Resolve after (at least) ms milliseconds, on the UI thread — the portable delay for day::task flows (docs/async.md). Rides Platform::post_delayed, so it works on single-threaded hosts (web) where std::thread::sleep + Setter cannot.
synthesize_text
Deliver synthetic TYPING to a text control (the dayscript input step and the autodrive string commands both route here): paint the widget via the ordinary app-write patch, then enqueue the TextChanged event. Both halves are needed — when a real user types, the text is already in the native field by the time its change event fires, so the two-way binding’s echo guard deliberately suppresses the write-back (§4.4); a synthesized event alone would drive the app’s signal while the widget kept showing its old text.
task
Spawn an async flow onto Day’s main-loop executor. This is the opt-in seam for actions that open modals or pickers: button.action(|| day::task(async move { … .await … })). The future is polled once before this returns; the returned handle can TaskHandle::abort it and is freely discardable.
toolkit_key
The toolkit key of the running backend ("appkit", "gtk", … — the Platform::TOOLKIT string), recorded by launch_with. None before launch.
try_with_tree
Like with_tree, but returns None instead of panicking when the tree can’t be entered: already borrowed, or not installed yet. A snapshot (TreeOps::snapshot) holds the borrow while the backend draws the window synchronously, and that draw can re-enter Day through a native callback — e.g. a lazy list’s viewForRow/connect_bind/cellForRow firing during cacheDisplayInRect. And platform style callbacks can fire before install_tree — e.g. GTK’s StyleManager emits a dark notify while startup applies a forced DAY_THEME scheme, before activate mounts the tree; a panic there unwinds into a C signal trampoline and aborts the process. Such callbacks use this and simply skip their work; the next real layout (or the signal’s first post-mount read) catches up.
uninstall_tree
Reset the thread-local tree + queues (tests).
unregister_nav
Remove a controller whose host was disposed. No-op if already gone.
with_animation
Explicitly animate every state change made in f — Day’s equivalent of SwiftUI’s withAnimation. The mutation runs inside a day_reactive::batch; that batch’s synchronous fixpoint drain (bindings → patch, plus the turn-end layout → set_frame) executes while spec is ambient, so the resulting native updates carry the animation intent and the toolkit animates them on its own compositor. Nesting overrides; the previous ambient restores after.
with_tree
Access the installed tree. Tree methods never run user code, so nesting cannot occur while a borrow is held; if events were queued during the call, they are pumped after the borrow is released (the “safe point” of §3.3).

Type Aliases§

EventHandler
An event handler registered on a realized node.
EventObserver
The recording/telemetry observer installed via set_event_observer (§14.6): called with every dispatched (NodeId, Event), in queue order, before the app receives it.
NavObserver
A navigation observer (§14.6): called with the new FULL route each time it changes, from any source — imperative navigate/nav_back, a nav_link or sidebar row (which navigate from an event handler, bypassing the event observer), a stack push, or a native back gesture. "" is the root. Installed by the recorder in day-script; day-core only fires it.
ResourceOpener
A backend’s resource opener: maps a declared name (e.g. "stations.json") to its bytes, or None if there is no such resource.
Day API ↩ Guides· daybrite.dev