Skip to main content

BuildContext

Struct BuildContext 

Source
pub struct BuildContext<'a> { /* private fields */ }
Expand description

Context available during Widget::build().

Implementations§

Source§

impl<'a> BuildContext<'a>

Source

pub fn self_id(&self) -> WidgetId

The WidgetId of the widget being built.

Source

pub fn add(&mut self, widget: impl Widget + 'static) -> WidgetId

Add a widget to the tree.

Source

pub fn add_boxed(&mut self, widget: Box<dyn Widget>) -> WidgetId

Add a pre-boxed widget to the tree.

Source

pub fn add_detached(&mut self, widget: impl Widget + 'static) -> WidgetId

Add a parentless widget this one owns: pre-built overlay content (a dropdown menu, a date picker’s calendar, a tooltip’s nested cascade children) that must not be reached by the child walk.

Use this — never a bare add — for anything built ahead of time and parked with set_dormant to be shown later through an overlay. The two differ only in bookkeeping: add hands back a node nothing owns, so the builder’s own teardown cannot reach it and every rebuild strands another copy in the arena; this records the ownership edge, so the node dies with its owner and the previous generation dies with each rebuild.

Content that can be a child should be returned from build() as one instead. This exists for content that cannot: activation and the paint walk both descend through children, so a dormant popup parked there wakes with its host and paints inline at zero size.

Source

pub fn add_deferred( &mut self, reveal: Signal<bool>, widget: impl Widget + 'static, ) -> WidgetId

Insert a child whose subtree is not built until reveal first turns true, and is retained from then on. Returns the host’s id immediately.

The shape this replaces is ctx.add(panel) followed by ctx.set_dormant(id) — correct, but it builds content the user may never open, on every rebuild of the owner. In a virtualized collection the owner is a per-row delegate, so that cost is multiplied by the row count: on a 40-row table whose cells each carried a four-item menu, the eager form cost 325–552 ms per rebuild against 42–46 ms without the column at all, and ~85% of it was the add rather than constructing the widget value. See DeferredSubtree for the full contract.

Pass the same signal the content’s visible_when gate uses. Everything downstream of the returned id — set_dormant / activate, visible_when, OverlayRequest::content_id, descendant checks, dismissal — is unchanged; only when the subtree below it exists moves.

Source

pub fn add_deferred_boxed( &mut self, reveal: Signal<bool>, widget: Box<dyn Widget>, ) -> WidgetId

add_deferred for an already-boxed widget.

Source

pub fn add_deferred_on_demand( &mut self, widget: impl Widget + 'static, ) -> WidgetId

add_deferred for content the framework materializes, kept as a child of the builder.

The parented twin of add_detached_deferred_on_demand, for the two rich-tooltip attach paths: they have always parented their body on the anchor’s owner, and reparenting them to detached would move which teardown reaps them. Only when the body is built changes.

Worth the separate entry point because a rich tooltip is not one widget: RichTooltipWidget::build eagerly pre-creates a nested tooltip for every :key link in its body, recursively, so one attached tip expands into a cascade. Built eagerly on a data view’s row delegate, 29 rows of Skribisto’s Overview carried 1,305 tooltip widgets inside a 22,737-node subtree, and tearing that down cost 5.3 s per arrow-key press — the destroy, not the build.

Source

pub fn add_detached_deferred_on_demand( &mut self, widget: impl Widget + 'static, ) -> WidgetId

add_deferred for content the framework materializes rather than a widget’s own open signal.

The tooltip case: a tooltip body has no open signal a widget could hand over — the tree decides, when a dwell matures. WidgetTree forces such a host just before it consults Widget::tooltip_has_content, so the body exists by the time anything asks it a question.

Source

pub fn add_detached_deferred_boxed( &mut self, reveal: Signal<bool>, widget: Box<dyn Widget>, ) -> WidgetId

add_deferred, inserted detached — the shape overlay content wants, so it is owned by the builder and dies with it rather than outliving every menu the user ever opened.

Source

pub fn add_detached_deferred( &mut self, reveal: Signal<bool>, widget: impl Widget + 'static, ) -> WidgetId

add_detached_deferred_boxed for an unboxed widget.

Source

pub fn add_detached_boxed(&mut self, widget: Box<dyn Widget>) -> WidgetId

add_detached for an already-boxed widget.

Source

pub fn add_child( &mut self, parent: WidgetId, widget: impl Widget + 'static, ) -> WidgetId

Add a Level 2 widget as a child of another widget.

Source

pub fn signal<T: 'static>(&mut self, value: T) -> Signal<T>

Create a new mutable signal.

Source

pub fn animated_signal(&mut self, value: f32) -> Signal<f32>

Create a new Signal<f32> that supports animate_to(). Registered with the animation scheduler automatically. The owning widget (self_id()) is recorded so that the scheduler can pause the animation when the widget is offscreen, dormant, or rebuilt.

Source

pub fn register_animated_signal(&mut self, signal: &Signal<f32>)

Register a pre-existing Signal<f32> for animation support. Use this when the signal was created outside of build() (e.g. in the widget constructor) and needs to be registered with the animation scheduler.

Source

pub fn prefers_reduced_motion(&self) -> bool

Read the OS-level prefers-reduced-motion preference. Widgets that use looping or decorative animations (spinners, sprite icons, marquee text, etc.) should skip starting them when this returns true so the UI respects accessibility settings and — as a bonus — draws no CPU/GPU.

Source

pub fn animate(&self) -> AnimationSpec

Build an AnimationSpec — the fluent ergonomic façade over Signal<f32>::animate_to. Captures the theme’s MotionTokens and the platform reduced-motion preference at build time, returns a clonable spec that event-handler closures can drive without re-threading durations and easing.

let knob_anim = ctx.animate().fast().standard();
handlers = handlers.on_tap(move |_, _| {
    knob_anim.to_or_snap(&knob_position, target);
});
Source

pub fn animated_quad(&mut self, kind: AnimatedQuadKind) -> AnimatedQuadHandle

Opt into the shader-driven animated-quad pipeline. The widget paint() emits ONE canvas.draw_animated_quad(bounds, handle.slot(), class) call; the renderer samples per-slot state from its uniform buffer each frame and the widget’s paint() does not re-run for animation ticks — only on layout changes. The returned handle is stable for the widget-mount lifetime and should be stashed on self to thread to paint().

For decorative motion that isn’t a quad (scroll-offset tweens, sidebar slide, toggle knob), keep using ctx.animated_signal + signal.animate_looping — both paths coexist.

Source

pub fn frame_tick(&self) -> Signal<f32>

The per-frame delta-seconds signal. Observe it via ctx.effect(&ctx.frame_tick(), |delta| ...) to run code once per frame the tree was explicitly asked to pump. Merely observing this signal does not keep the event loop awake — widgets must call request_frame (typically from an event handler or from inside the tick closure itself) to schedule the next wake-up. This preserves Teksilo’s draw-when-needed model.

Source

pub fn request_frame(&self)

Ask the tree to pump exactly one more frame. See frame_tick for the observer side.

Source

pub fn request_accessibility_update(&self)

Request that the AccessKit tree be re-walked after this build pass. Use when build() restructured its subtree in a way that changes the accessibility tree (relayout alone no longer re-walks AT). SceneView calls this each build, since it may have materialised or destroyed scene widgets or applied a11y-only scene mutations.

Source

pub fn frame_request_handle(&self) -> Rc<Cell<bool>>

Clone the shared “frame requested” flag. Stash it on widget state and call .set(true) from inside a frame-tick effect closure to chain-request another frame without needing mutable access to the tree. Used by widgets with continuous frame needs (caret blink, drag auto-scroll, smooth animations driven from a tick closure).

Prefer subscribe_frame_tick for visual-only continuous animations (Pulse, Cycle, …): the scheduler-backed path automatically pauses the chain when the owner widget is hidden, while this raw handle keeps the event loop pumping at full frame rate regardless of visibility.

Source

pub fn subscribe_frame_tick(&self) -> FrameTickSubscription

Subscribe the widget being built to the per-frame-effect scheduler. The returned RAII guard removes the subscription on drop — store it on self so its lifetime tracks the widget’s.

While at least one subscriber’s owner is visible, the framework auto-arms frame_tick_requested after every render. When all subscribers are hidden (e.g. parked inside a non-selected Switcher branch), no re-arm happens and the chain dies, so the event loop sleeps. On a hidden→visible transition the visible_when binding’s relayout dirty triggers a repaint that paints the subscriber, which the post-render arm then detects and resumes the chain.

Replaces the widget-managed frame_request.set(true) re-arm pattern for visual-only continuous animations. The widget’s frame_tick effect closure no longer needs to call frame_request.set(true) itself — the scheduler handles it.

Source

pub fn subscribe_frame_tick_throttled( &self, interval: Duration, ) -> FrameTickSubscription

Like subscribe_frame_tick, but the widget only needs to wake at most once per interval while visible. Same visibility gate and RAII guard; between wakes the event loop sleeps to the interval deadline rather than rendering identical 60 fps frames. Use when the widget’s visible output changes far less often than 60 Hz — e.g. Cycle’s once-per-period index advance, or a seconds-granular clock.

Source

pub fn wake_at_handle(&self) -> Rc<Cell<Option<Instant>>>

Clone the shared wake-at deadline cell. Stash it on widget state and set Some(instant) from a frame-tick effect to schedule a one-shot deadline wake-up without keeping the event loop in Poll mode. See WidgetTree::wake_at_handle for the underlying mechanism.

Source

pub fn effect<T: Clone + 'static>( &mut self, signal: &Signal<T>, f: impl Fn(&T) + 'static, )

Register a scoped effect tied to this build cycle. The effect fires whenever the signal changes. It is automatically cleaned up on rebuild or widget destruction.

Source

pub fn own_handle(&mut self, handle: ObserverHandle)

Register a pre-existing observer handle for lifecycle management. The handle will be dropped (and the observer removed) on rebuild or widget destruction.

Source

pub fn binding_registry(&self) -> &BindingRegistry

Get the binding registry.

Source

pub fn theme(&self) -> &Theme

Get the current theme.

Source

pub fn theme_signal(&self) -> Signal<Theme>

Reactive handle on the current theme. Fires observers when tree.set_theme(...) is called. Build implementations that want theme-driven values to update without a rebuild should use this instead of cloning tokens from self.theme() — for example, ctx.theme_signal().map(|t| t.colors.primary) or combining with interaction state via zip(...).

Source

pub fn text_scale(&self) -> f32

Current combined text-scale factor (user × OS, 1.0 = 100 %). One-shot read for build-time sizing; for a value that updates without a rebuild, bind text_scale_signal instead.

Source

pub fn text_scale_signal(&self) -> Signal<f32>

Reactive handle on the combined text-scale factor. Fires when the user scale, theme, or OS text-scale preference changes. Build implementations that derive a build-time dimension from the scale (e.g. Calendar’s fixed cell sizes) bind this — typically at Rebuild level so the change recomputes the constants — since a scale change relayouts but does not rebuild on its own.

Source

pub fn window_active(&self) -> bool

Whether the host window is currently active (focused AND not occluded). One-shot read for build-time use; for a value that reacts to focus changes, bind window_active_signal.

Source

pub fn window_active_signal(&self) -> Signal<bool>

Reactive handle on window-active state. Fires when the host window gains or loses active status (focused AND not occluded). Build implementations that show/hide appearance with window focus — caret effects, the selection-colour swap in text fields, DimWhenInactive — bind this, typically at RepaintOnly level (an active-state flip never affects geometry). Starts true.

Source

pub fn locale_signal(&self) -> Signal<Option<String>>

Reactive handle on the current locale. Fires observers when tree.set_locale(...) is called.

Source

pub fn window(&self) -> Option<&WindowState>

The WindowState for the window hosting this tree. None only for trees built outside of an app (tests, headless scenarios). Use this to bind widgets to window-level signals like placement, size, focused.

Source

pub fn app_state<T: 'static>(&self) -> Option<&T>

Retrieve an application-scoped value of type T registered via TeksiloAppBuilder::app_state. Returns None if no value of that type was registered. The returned reference borrows from the framework for the duration of the build pass.

Source

pub fn poster(&self) -> Option<&Arc<dyn AppEventPoster>>

Borrow the AppEventPoster installed by the framework, if any. Mirrors EventContext::poster. Used by integrations that wire a platform callback (e.g. a native menu item) to post a typed payload back to the UI loop. Returns None for trees built outside an app (tests / headless).

Source

pub fn visible_when(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s visibility to a boolean prop or compatibility state binding.

Source

pub fn run_after_mount( &mut self, f: impl FnOnce(&mut EventContext<'_>) + 'static, )

Enqueue a one-shot action to run shortly after this build, with a real EventContext — the only place a widget can read the OS parent window handle (ctx.parent_window_handle()), app_state, and poster together, after it is mounted under its window. The action runs at most once per enqueue (the app loop drains the queue each iteration); a widget that rebuilds must guard against enqueuing twice. Built for widgets owning a native OS resource that needs a window handle to initialise (a WebView’s engine subview); ordinary widgets never need it.

Source

pub fn activation_signal(&mut self, id: WidgetId) -> Signal<bool>

Observe a node’s framework activation as a Signal<bool>true while active, false while parked dormant by a Switcher / visible_when gate. Initialised to the node’s current state and updated only on an actual Active↔Dormant transition.

Ordinary widgets never need this: dormant subtrees are simply not painted, so they vanish for free. It exists for the one case where “not painted” ≠ “hidden” — a widget owning a native OS resource that renders outside the wgpu pass (a WebView’s engine subview). Such a widget does ctx.effect(&ctx.activation_signal(id), move |a| handle.set_visible(*a)) to hide/show the native surface in lockstep.

Source

pub fn view_focus_active(&mut self) -> Signal<bool>

Reactive Signal<bool> that is true while the focus scope containing the widget being built — its nearest focusable ancestor, e.g. the enclosing ListView / TreeView — holds keyboard focus. Items outside any focusable scope read a constant true.

Drives focus-aware selection: a selected row renders with the active Selected chrome while its view has focus and the muted SelectedInactive chrome when focus moves elsewhere — the standard desktop affordance (Qt SH_ItemView_..., macOS inactive selection) that shows where the keyboard is. The scope is resolved at build time but the signal stays live across focus changes.

Source

pub fn begin_view_focus(&mut self) -> Signal<bool>

Mark the widget being built as a focus scope for the rows/items it builds next: any descendant’s view_focus_active (and StandardItem’s focus-aware selection / focus ring) reads this widget’s keyboard focus. A data view calls this around its row loop, then end_view_focus. Deterministic — unaffected by arena parenting, which may not be wired while docked/virtualized rows build.

Source

pub fn begin_view_focus_for(&mut self, node_id: WidgetId) -> Signal<bool>

Like begin_view_focus but keys the scope on an explicit node_id rather than the widget being built. A view whose rows are built by a separate body-pane widget (TableView / TreeTableView / GridView) passes its own focusable root id so descendant items resolve the root’s keyboard focus — not the pane’s, which is a child of the root and so never holds focus itself.

Source

pub fn end_view_focus(&mut self)

End the focus scope opened by begin_view_focus.

Source

pub fn focus_visible(&self) -> Signal<bool>

Input-modality “focus-visible” signal — true after keyboard input, false after pointer input (the standard :focus-visible rule). Pair with view_focus_active to draw a focus ring only during keyboard navigation, not on mouse clicks.

Source

pub fn set_opacity(&mut self, id: WidgetId, opacity: impl Into<Prop<f32>>)

Bind an opacity multiplier (0..1) to a widget. The render walker emits SetOpacity(value) before painting the widget’s subtree and RestoreOpacity afterwards, so the multiplier composes correctly with ancestor opacity scopes. Bound at RepaintOnly: opacity changes never trigger relayout. Used by the Fade wrapper to animate a child between hidden and fully visible.

Source

pub fn set_transform( &mut self, id: WidgetId, transform: impl Into<Prop<Transform2D>>, )

Bind a 2D affine transform to a widget. The render walker emits PushTransform(value) before painting the widget’s subtree and PopTransform afterwards, so the transform composes onto the renderer’s stack with any ancestor transform scopes and with the widget’s own canvas-level transforms. Bound at RepaintOnly: visual-only transforms never trigger relayout. Used by Scale and Rotate; reflow-driving wrappers (e.g. Scale::reflow(true)) must additionally bind their driver signal to themselves at Relayout to make layout track the value.

Source

pub fn set_content_transform( &mut self, id: WidgetId, transform: impl Into<Prop<Transform2D>>, )

Bind a 2D affine content transform to a widget — the transform positions the widget’s content within its fixed parent-space viewport (its bounds) rather than transforming the widget itself. Renders the same PushTransform / PopTransform scope as set_transform, but hit-testing treats the bounds as a fixed viewport so the whole visible area stays interactive at any pan / zoom. Used by SceneView for its pan/zoom view transform.

Source

pub fn set_blur(&mut self, id: WidgetId, radius: impl Into<Prop<f32>>)

Bind a Gaussian-equivalent blur radius to a widget. The render walker emits BeginBlurredSubtree { bounds, radius } before painting the widget’s subtree and EndBlurredSubtree afterwards; the renderer redirects drawing into an intermediate texture, runs a dual-Kawase blur chain at the requested radius, and composites the blurred result back into the parent pass at the widget’s bounds. Bound at RepaintOnly: blur radius changes never trigger relayout. Sub-perceptual radii (< 0.5) skip the Begin/End pair entirely so animated enable/disable patterns have zero per-frame cost when fully off. Used by the Blur wrapper.

Source

pub fn enabled_when(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s enabled state to a boolean prop or compatibility state binding.

Source

pub fn effective_enabled_signal(&mut self, id: WidgetId) -> Signal<bool>

Reactive view of “is this widget effectively enabled?” — the AND of the widget’s own enabled_state and every ancestor’s. The arena’s crate::arena::WidgetArena::is_enabled is the non-reactive equivalent; this method gives composite widgets a Signal<bool> they can .map(...) / .zip(...) against to derive other reactive UI state (cursor, custom paint, helper signals).

Leaves like IconWidget / TextWidget / RectWidget do NOT need this — they get the bool directly via crate::widget::PaintContext::effective_enabled at paint time. This method is for composites that need the value at build time or want to chain signals.

The signal is node-resident and framework-refreshed (install-or-reuse, like Self::activation_signal), so it tracks ancestors correctly even though a widget’s parent is not yet wired while its own build() runs. It is a mutable signal, so — unlike the old derived implementation — it can be passed to Self::effect.

Returns a signal reading true for any node whose entire ancestor chain (including itself) has no enabled_state bound.

Source

pub fn set_tab_stop(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s Tab-key participation to a boolean prop or compatibility state binding. When false, the widget is removed from Tab / Shift+Tab traversal but remains reachable via request_focus and arrow-key navigation. Implements the ARIA roving-tabindex pattern (HTML tabindex="-1" semantics).

Source

pub fn set_traversal_scope(&mut self, policy: TraversalScopePolicy)

Declare the widget being built as a traversal-scope boundary for Tab / Shift+Tab navigation. Descendants’ tab_index values become scoped to this node — they never collide with sibling scopes — and the policy controls what happens at the scope’s ends:

  • TraversalScopePolicy::Continue — Tab flows out into the enclosing scope’s next member (groups numbering only).
  • TraversalScopePolicy::Cycle — Tab wraps within the scope, never exits. For modal dialogs only: a popover or menu is non-modal, and the framework closes one the keyboard walks out of rather than containing focus in it. Trapping such an overlay stops that dismissal from ever firing.

This node is automatically excluded from being a Tab stop itself. Prefer the FocusScope wrapper widget in teksilo-widgets over calling this directly.

Source

pub fn attach_tooltip( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, )

Attach a tooltip to a widget.

Source

pub fn attach_tooltip_with_placement( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, placement: TooltipPlacement, )

Attach a tooltip with an explicit TooltipPlacement — use Side for anchors stacked vertically (menu items, a vertical tab strip, list/tree rows) so the tooltip opens beside the anchor instead of covering the next sibling.

Source

pub fn attach_tooltip_with_sticky( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, )

Attach a tooltip that auto-promotes to sticky after a dwell timer. Non-None sticky_after enables the sticky-on-dwell UX: once the tooltip has been shown for sticky_after, the tree flags the entry sticky and swaps the overlay’s dismiss behavior to EscapeOrClickOutside.

Source

pub fn attach_tooltip_with_sticky_sink( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, shown_at_sink: Rc<Cell<Option<Instant>>>, )

Variant of attach_tooltip_with_sticky that takes a shared Rc<Cell<Option<Instant>>> “sink” the tree updates whenever the tooltip is shown / dismissed. The tooltip widget reads from this sink to compute its own dwell progress reliably, without needing a paint-gap heuristic.

Source

pub fn attach_tooltip_with_sticky_sink_placement( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, shown_at_sink: Rc<Cell<Option<Instant>>>, placement: TooltipPlacement, )

Variant of attach_tooltip_with_sticky_sink that also carries a TooltipPlacement. The full-featured path used by rich + composite tooltips that want Side placement in a vertical context (menu items, list/tree rows).

Source

pub fn promote_tooltip_to_sticky(&mut self, content_id: WidgetId)

Promote a shown tooltip to “sticky”: removes its auto-dismiss on pointer-leave and swaps the overlay’s dismiss behavior to EscapeOrClickOutside. Used by rich tooltips that implement a dwell timer.

Source

pub fn set_dormant(&mut self, id: WidgetId)

Set a widget as dormant (inactive). Used to pre-create overlay content that will be activated later via EventContext::activate().

Source

pub fn destroy_subtree(&mut self, id: WidgetId)

Destroy a widget and its entire subtree, removing them from the arena and dropping any per-widget subscription / effect handles.

Use this to clean up dormant subtrees that the current widget created during a prior build and that live outside its regular arena children — e.g., a pre-built popup panel inserted via ctx.add(..) + ctx.set_dormant(..) that becomes stale after a rebuild. Regular arena children of the composite (i.e. widgets whose ids are returned from build) are destroyed automatically by the framework’s rebuild path and do not need this call.

If an overlay currently references id as its content, the overlay is dismissed first so the manager does not retain a stale content reference.

Source

pub fn apply_self_handlers(&mut self, handler_set: HandlerSet)

Apply a HandlerSet to the composite widget being built (self). This transfers attached event handlers, focusable flag, cursor, etc. to the widget’s arena node, replacing event() and is_focusable() overrides.

Source

pub fn focus(&mut self, id: WidgetId)

Move keyboard focus to id. Mirrors EventContext::request_focus for use during build() — e.g. when a composing widget pre-builds an editor and needs focus to land on it as soon as the subtree is wired in.

Source

pub fn first_focusable_descendant(&self, root: WidgetId) -> Option<WidgetId>

Find the first focusable widget within the subtree rooted at root in depth-first order. Returns None when the subtree has no focusable descendant or root is not in the arena.

Source

pub fn focus_into(&mut self, id: WidgetId) -> bool

Move keyboard focus into the subtree rooted at id: its first focusable descendant in tab order, or id itself when it is the only focusable thing there. Returns whether focus ended up inside id.

The build-time twin of EventContext::request_focus_into, and safe here for the same reason focus is: add builds a child’s whole subtree synchronously, so by the time a composing widget holds a child’s id the focusable descendants of that child already exist.

Idempotent, and that is the point. build runs again on every rebuild, so a bare focus here would drag focus back into this subtree every time the owner rebuilt for an unrelated reason — a table body pane rebuilds on selection, on filtering and on scroll. This is a no-op while focus already sits inside id, so it expresses “focus belongs in here” rather than “focus here now”.

A subtree with nothing focusable leaves focus exactly where it was: an empty region never traps it.

Ancestor-chain side effects do not run, and that is a property of focusing from build at all, not of this method — focus has it too. A node added during build is not parented until the build that produced it returns, so at this moment id’s chain stops at whatever the caller has already inserted: focus_within signals on enclosing nodes never flip, and scroll_focused_into_view finds no scroll container to reveal the target in. Everything below id is linked (children are parented as each is inserted), so the walk that picks the focusable descendant, and every later key dispatch — which happens after the pass, on a whole tree — are unaffected.

Reach for EventContext::request_focus_into where the difference matters: it is queued and drained after dispatch, against a complete tree.

Source

pub fn register_action(&mut self, action: Action)

Attach an Action to the widget being built. Actions are consulted during intent dispatch as the framework walks source-widget → root; the first matching, enabled action wins (subject to the IntentResponse returned by its handler).

Actions are cleared on rebuild, mirroring event handlers.

Source

pub fn register_text_surface(&mut self, surface: Rc<dyn TextSurface>)

Declare that the widget being built edits text.

Every text widget should call this. It is what lets an application take a text chord — Ctrl+Z, Ctrl+C — for itself without silently breaking the widget it took it from: the host asks focused_text_surface and either drives this surface or steps aside so the widget keeps its own keys. See crate::text_surface for the whole argument.

Owned by the registering widget and torn down on its rebuild or destroy, like register_action_global. Calling it twice from one widget re-points rather than duplicating, so a rebuild that hands over a fresh handle is correct.

Source

pub fn text_surfaces(&self) -> TextSurfaces

A cloneable view of this tree’s registered text surfaces.

Take it once, during build, and hold it: a view-model refreshed from a frame tick has no &WidgetTree to consult, and that is exactly when it needs to know whether the caret is in a text widget.

Source

pub fn register_action_global(&mut self, action: Action)

Register a window-global Action, owned by the widget being built. Unlike register_action — which only fires when this widget is on the intent’s source→root walk — a global action is consulted as a dispatch fallback, so it is reachable no matter where the intent originated: a menu-bar dropdown (which renders in an overlay, not under the registering widget), deep content, or a global shortcut anchored at the root when nothing is focused.

This is the action-side counterpart to register_shortcut_global: use it for app-wide commands (app.save, view.toggle_sidebar) whose handler lives at the app root but whose triggers (menu, toolbar, shortcut) are scattered across the tree and chrome. Ownership applies: the action is torn down when this widget rebuilds or is destroyed.

Source

pub fn register_shortcut(&mut self, shortcut: Shortcut)

Register a Shortcut in the tree’s registry, owned by the widget being built.

If the shortcut builder left scope at the default (ShortcutScope::Global), this method rewrites it to Scoped(self_id) so the shortcut only fires when focus is inside the registering widget’s subtree — the ergonomic default for widget-declared shortcuts. Callers that want an explicit global shortcut should use BuildContext::register_shortcut_global instead; callers that want to scope to a specific child should set .scope_to(child_id) on the builder themselves.

Ownership: the shortcut is removed from the registry when the widget is destroyed or rebuilt. User overrides survive across rebuilds (graveyard semantics).

Source

pub fn register_shortcut_global(&mut self, shortcut: Shortcut)

Register a Shortcut with explicit global scope, owned by the widget being built. Unlike BuildContext::register_shortcut, this does not rewrite the scope — the shortcut fires regardless of focus position.

Ownership still applies: the shortcut is torn down when this widget goes away.

Source

pub fn register_pending_shortcuts( &mut self, shortcuts: impl IntoIterator<Item = Shortcut>, )

Pre-declare shortcuts on behalf of a not-yet-mounted child (e.g. a Switcher walking its Pending slots’ static declarations before they’re inserted). Each shortcut is owned by the calling widget and its declared scope is preserved as-is — unlike register_shortcut, no rewrite from Global to Scoped(self) happens, because the child intended its own scope.

When the child is eventually mounted, the framework’s insert-time walk of Widget::declare_shortcuts re-registers the same ids owned by the child; the registry’s idempotent upsert moves ownership cleanly. If the child never mounts, the pre-declared entries stay alive (owned by the parent) so settings UIs still see them, and they get torn down when the parent goes away.

Source

pub fn shortcut_registry(&self) -> &ShortcutRegistry

Read-through access to the tree’s shortcut registry. Consumers (menus, tooltips) look up the effective keystroke for a given id here, and observe ShortcutRegistry::version to refresh when the user rebinds.

Source

pub fn effective_shortcut<'b>( &'b self, id: &str, ) -> Option<EffectiveShortcut<'b>>

Effective view of a shortcut by id, merged with any user override. Returns None when no default has been registered for id. Typical caller pattern: call from paint() so late-registered shortcuts are still picked up without a dedicated build-phase query.

Source

pub fn shortcut_version(&self) -> &Signal<u64>

Convenience accessor for the reactive version signal. Widgets that render shortcut-derived state (menu labels, tooltips) observe this so the UI refreshes when the user rebinds or a new shortcut is registered.

Source

pub fn effective_shortcut_signal( &mut self, id: &'static str, ) -> Signal<Option<KeyStroke>>

A reactive, per-id handle to a shortcut’s effective primary keystroke — the granular alternative to Self::shortcut_version. Bind this to render one shortcut’s accelerator as a leaf value (a menu item’s trailing label, a tooltip) that refreshes in place when the user rebinds that id, without observing — and rebuilding on — every unrelated registry mutation. The signal is created on first request, seeded with the current value, and kept live by the registry across register / unregister / rebind of that id.

Source

pub fn apply_handlers(&mut self, id: WidgetId, handler_set: HandlerSet)

Apply a HandlerSet to a child widget created during this build. Use this to attach event handlers to children without wrapping them in WidgetWithHandlers.

Source

pub fn access_labelled_by(&mut self, id: WidgetId, label_id: WidgetId)

Wire an accessibility labelled_by relation from an already-mounted child (id) to its label (label_id), so assistive tech announces the field by its visible label (WCAG 3.3.2 / EN 301 549 11.5.2.7). Unlike the .access_labelled_by(..) builder method, this operates after the child is mounted (so a container like FormLayout can pair a label and a boxed field once both ids are resolved) and preserves any accessibility overrides the child already carries.

Source

pub fn access_described_by(&mut self, id: WidgetId, target_id: WidgetId)

Wire an accessibility described_by relation from an already-mounted child (id) to a description/error node (target_id) — the post-mount, override-preserving counterpart of the .access_described_by(..) builder method (WCAG 3.3.1).

Source

pub fn subscribe_event<O, E, F>(&mut self, origin: O, callback: F)
where O: 'static, E: 'static, F: Fn(&E) + 'static,

Source

pub fn subscribe_event_with_ctx<O, E, F>(&mut self, origin: O, callback: F)
where O: 'static, E: 'static, F: Fn(&E, &mut EventContext<'_>) + 'static,

Like subscribe_event, but the UI-side callback additionally receives a fresh EventContext bound to this widget’s window. That lets it react to a backend event imperatively — update / replace / dismiss a toast, present a modal, send_intent, navigate — none of which a plain (context-free) subscribe_event callback can do (it can only poke Signals).

This is the supported bridge for long-operation progress: a Qleany Origin::LongOperation(Progress | Completed | Cancelled | Failed) event crosses from the operation’s background thread to the UI thread and the callback drives an evolving progress toast (percentage in the body, a Cancel action, a success/error replacement on completion) — see the toast_demo example.

The event is delivered on the UI thread through the same AppEvent::SubscriptionEvent path as subscribe_event; teksilo-app mints the EventContext from this widget’s window tree just before the call (mirroring teksilo-async’s spawn_local_with completion path). The subscription is torn down with the widget, exactly like subscribe_event.

The <O, E> type match against the registered event source is a debug_assert (as in subscribe_event); a mismatched call site in a release build is not caught here but panics later at the payload downcast.

Registering from a windowless tree (headless / tests) is allowed but records None for the window — the app-side router then has no tree to mint an EventContext from and cannot deliver it, so such a subscription never fires in a running app. Ordinary application widgets always have a window; headless code that wants to observe events should use subscribe_event and drive Signals instead.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for BuildContext<'a>

§

impl<'a> !Send for BuildContext<'a>

§

impl<'a> !Sync for BuildContext<'a>

§

impl<'a> !UnwindSafe for BuildContext<'a>

§

impl<'a> Freeze for BuildContext<'a>

§

impl<'a> Unpin for BuildContext<'a>

§

impl<'a> UnsafeUnpin for BuildContext<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.