Skip to main content

NavigatorController

Struct NavigatorController 

Source
pub struct NavigatorController<State>
where State: 'static,
{ /* private fields */ }
Expand description

The app-state handle to a navigator: a cloneable op queue an app keeps in its Component::State and drives with push/pop/ replace. Every clone shares one queue (Rc), so the handle the view carries and the handle event handlers call are the same.

Ops are recorded, not applied — the NavigatorWidget drains and applies them at its next rebuild (see the module docs).

Implementations§

Source§

impl<State> NavigatorController<State>
where State: 'static,

Source

pub fn new() -> NavigatorController<State>

A fresh controller with an empty op queue.

Source

pub fn is_mounted(&self) -> bool

Whether a live NavigatorWidget currently renders this controller’s stack — i.e. whether this navigator is in the retained tree right now.

false before the first build and again after the widget’s teardown (a screen with its own nested navigator, popped). Unlike depth/back_interest this is not an advisory snapshot of the stack: it is exact at every point after the widget’s build began, because build/teardown write it directly.

The facade’s back arbitration is the intended consumer: a registered controller that is still mounted is still part of the tree, so it must keep its place in the arbitration list even on a pass in which it did not re-wire; one that is no longer mounted can be released.

Source

pub fn id(&self) -> NavigatorId

This controller’s NavigatorId — stable across clones, distinct per independently constructed controller. See NavigatorId for the liveness caveat.

Source

pub fn depth(&self) -> usize

The current page-stack depth of the navigator this controller drives, as last published by that navigator’s build/rebuild, or 0 if no navigator is attached yet.

Advisory: this reflects the depth at the last rebuild, so a query racing a same-frame stack change sees the previous value (the rebuild-time refresh contract — see can_pop and frust-reactive::back’s timing note).

Source

pub fn can_pop(&self) -> bool

Whether a pop would actually remove a page — true iff the navigator has more than one page (depth > 1).

Advisory, for exactly the Android back contract: the facade’s back handler reads this to decide whether a back press pops or bubbles to the platform, and publishes it as frust-reactive::set_handles_back. The authoritative guard stays the widget’s own len > 1 check in apply_ops — a pop at the root remains a safe no-op even if this raced stale, so a mis-predicted root-level back never removes the last page.

Source

pub fn back_interest(&self) -> bool

Whether the navigator claims the next back press ahead-of-time (predictive-back parity) — true iff the stack is poppable or the top page declares a non-Pop policy (a dismissable/veto overlay). The facade’s back handler reads this (in preference to can_pop) to compute the shell’s handles_back, so a dismissable overlay at the root still consumes back rather than exiting the app.

§Nested navigators: reach follows input routing (R23)

A navigator hosted on a page its own host navigator routes no input to (a covered page, or the page under a transparent overlay) reports false here regardless of its own stack: back arbitration reaches exactly as far as input does, so a press can never pop an off-screen stack while the visible page stays put. Unconditional true for the reach term at the top level, so a single-navigator app is unaffected.

Advisory, published at the last rebuild like depth — a query racing a same-frame stack change sees the previous value; the navigator’s own request_back routing stays authoritative regardless (see frust-reactive::back’s timing note).

Source

pub fn transition(&self) -> TransitionState

The navigator’s current TransitionState — the observation seam chrome outside the navigator subtree (an app bar, a tab bar, a progress indicator) drives its own motion from. TransitionState::default (an at-rest depth-0 snapshot) until a navigator attaches.

Published on the controller, not the widget, deliberately: chrome that wants to match page motion is a sibling of the navigator, not a descendant, so it can never reach the widget — but it can hold a controller clone, exactly as it already does to push.

§The timing contract

The progress driver advances in exactly one place — paint, off PaintCtx::frame_time (the No-Instant::now() rule in docs/REVIEW_FOCUS.md forbids any other clock in frust-widgets). Therefore:

  • A read during your own Widget::paint, from a widget painted after the navigator, is exact for the current frame. In a root Stack(vec![navigator_subtree, chrome]), StackWidget::paint walks its children in order, so chrome paints second and reads the value the navigator wrote microseconds earlier in the same frame. This is the frame-perfect path; it is the one to use for choreography.
  • A read during Component::build (or any View::build/rebuild) is always exactly one frame stale for progress, because build precedes paint. Fine for “is a transition running?”; wrong for choreography.
  • The active edges are the exception. Both start_transition and finalize_transition publish from a BuildCtx pass, so a build-time reader that builds after the navigator sees active flip on the very frame it happens. Only intermediate progress lags.

The navigator already requests a frame for every frame a transition runs, so a paint-time observer needs no wake of its own.

Source

pub fn route_stack(&self) -> RouteStack

The navigator’s currently published route-state snapshot — a clone, authoritative as of the last publish (see route_state‘s module docs’ staleness contract, in particular the interactive-swipe window).

Source

pub fn route_generation(&self) -> u64

The route stack’s current generation — an O(1) change gate equivalent to route_stack().generation() but without cloning the whole snapshot.

Source

pub fn push(&self, builder: impl Fn() -> AnyView<State> + 'static)

Push an opaque page built by builder on top of the stack, using the navigator’s default transition (instant unless the navigator sets one).

Source

pub fn push_with( &self, builder: impl Fn() -> AnyView<State> + 'static, transition: TransitionSpec, )

Push an opaque page with an explicit TransitionSpec, overriding the navigator’s default for this push only. The spec is stored on the pushed page and reversed when it is later popped.

Source

pub fn push_transparent(&self, builder: impl Fn() -> AnyView<State> + 'static)

Push a transparent page (e.g. a dialog/overlay) — the page below it stays visible and painted (see module docs’s paint culling).

Source

pub fn push_for_result( &self, builder: impl Fn() -> AnyView<State> + 'static, on_result: impl Fn(&mut State, PopResult) + 'static, )

Push an opaque page and register on_result, invoked with &mut State when this page is later popped (carrying the pop’s PopResult).

The callback is delivered at the start of the NavigatorWidget::event pass after the pop’s rebuild — the first point after the pop where the erased app state is in scope (a rebuild carries only a BuildCtx).

Source

pub fn push_transparent_for_result( &self, builder: impl Fn() -> AnyView<State> + 'static, transition: TransitionSpec, on_result: impl Fn(&mut State, PopResult) + 'static, )

Push a transparent page (e.g. a dialog/bottom sheet) with an explicit TransitionSpec (e.g. PageTransition::M3FadeThrough for a dialog, PageTransition::SlideUp for a bottom sheet — a design system’s own dialog/sheet helpers are the shipped callers), and register on_result, invoked with &mut State when this page is later popped (carrying the pop’s PopResult) — the modal-with-a-result combination push_transparent and push_for_result each cover only half of.

ⓘ
// A confirm dialog that reports whether the user confirmed:
controller.push_transparent_for_result(
    || dialog_view(),
    TransitionSpec::duration(PageTransition::M3FadeThrough),
    |state: &mut State, result: PopResult| {
        state.confirmed = result.take::<bool>().unwrap_or(false);
    },
);

The callback is delivered the same way push_for_result’s is: at the start of the NavigatorWidget::event pass after the pop’s rebuild.

Source

pub fn push_with_options( &self, builder: impl Fn() -> AnyView<State> + 'static, options: PushOptions<State>, )

Push a page with an explicit PushOptions — the full-control variant carrying a back-press BackPolicy (and, for a DismissAnimated overlay, its dismiss signal) alongside opacity/transition/result. The dismissable-overlay helpers push through this; every other push* method pushes with BackPolicy::Pop.

Source

pub fn pop(&self)

Pop the top page with no result payload (a plain back-navigation). A pop of the last/root page is ignored (a navigator always keeps one page).

Source

pub fn pop_with_result(&self, result: PopResult)

Pop the top page, handing result to its pusher-registered push_for_result callback.

Source

pub fn request_back(&self)

Route a back press through the top page’s BackPolicy (the entry the facade’s back handler drives instead of a bare pop):

  • Pop → a normal pop (transitions preserved; a safe no-op at the root);
  • DismissAnimated → fires the top page’s dismiss signal (stack unchanged; the overlay animates its own exit and pops itself), see BackPolicy’s observation seam;
  • Veto → the press is consumed but nothing happens.

Recorded like every other op and applied at the next rebuild (never self-mutating mid-event). Whether this call would claim the press is back_interest.

Source

pub fn replace(&self, builder: impl Fn() -> AnyView<State> + 'static)

Replace the top page in place with an opaque page built by builder, using the navigator’s default transition.

Source

pub fn replace_with( &self, builder: impl Fn() -> AnyView<State> + 'static, transition: TransitionSpec, )

Replace the top page with an explicit TransitionSpec, overriding the navigator’s default for this replace only.

Source

pub fn replace_with_options( &self, builder: impl Fn() -> AnyView<State> + 'static, options: ReplaceOptions, )

Replace the top page with an explicit ReplaceOptions — the full-control variant carrying a route identity alongside opacity and transition. Router::go/ Router::replace push through this.

Trait Implementations§

Source§

impl<State> Clone for NavigatorController<State>
where State: 'static,

Source§

fn clone(&self) -> NavigatorController<State>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<State> Default for NavigatorController<State>
where State: 'static,

Source§

fn default() -> NavigatorController<State>

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<State> !RefUnwindSafe for NavigatorController<State>

§

impl<State> !Send for NavigatorController<State>

§

impl<State> !Sync for NavigatorController<State>

§

impl<State> !UnwindSafe for NavigatorController<State>

§

impl<State> Freeze for NavigatorController<State>
where Rc<RefCell<Vec<NavOp<State>>>>: Freeze,

§

impl<State> Unpin for NavigatorController<State>
where Rc<RefCell<Vec<NavOp<State>>>>: Unpin,

§

impl<State> UnsafeUnpin for NavigatorController<State>
where Rc<RefCell<Vec<NavOp<State>>>>: UnsafeUnpin,

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> NoneValue for T
where T: Default,

Source§

type NoneType = T

Source§

fn null_value() -> T

The none-equivalent value.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> StorageAccess<T> for T

Source§

fn as_borrowed(&self) -> &T

Borrows the value.
Source§

fn into_taken(self) -> T

Takes the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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, !>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more