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§
Sourcepub fn new() -> NavigatorController<State>
pub fn new() -> NavigatorController<State>
A fresh controller with an empty op queue.
Sourcepub fn is_mounted(&self) -> bool
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.
Sourcepub fn id(&self) -> NavigatorId
pub fn id(&self) -> NavigatorId
This controller’s NavigatorId — stable across clones, distinct per
independently constructed controller. See NavigatorId for the
liveness caveat.
Sourcepub fn depth(&self) -> usize
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).
Sourcepub fn can_pop(&self) -> bool
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.
Sourcepub fn back_interest(&self) -> bool
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).
Sourcepub fn transition(&self) -> TransitionState
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 rootStack(vec![navigator_subtree, chrome]),StackWidget::paintwalks its children in order, sochromepaints 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 anyView::build/rebuild) is always exactly one frame stale forprogress, because build precedes paint. Fine for “is a transition running?”; wrong for choreography. - The
activeedges are the exception. Bothstart_transitionandfinalize_transitionpublish from aBuildCtxpass, so a build-time reader that builds after the navigator seesactiveflip on the very frame it happens. Only intermediateprogresslags.
The navigator already requests a frame for every frame a transition runs, so a paint-time observer needs no wake of its own.
Sourcepub fn route_stack(&self) -> RouteStack
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).
Sourcepub fn route_generation(&self) -> u64
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.
Sourcepub fn push(&self, builder: impl Fn() -> AnyView<State> + 'static)
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).
Sourcepub fn push_with(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
transition: TransitionSpec,
)
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.
Sourcepub fn push_transparent(&self, builder: impl Fn() -> AnyView<State> + 'static)
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).
Sourcepub fn push_for_result(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
on_result: impl Fn(&mut State, PopResult) + 'static,
)
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).
Sourcepub fn push_transparent_for_result(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
transition: TransitionSpec,
on_result: impl Fn(&mut State, PopResult) + 'static,
)
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.
Sourcepub fn push_with_options(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
options: PushOptions<State>,
)
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.
Sourcepub fn pop(&self)
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).
Sourcepub fn pop_with_result(&self, result: PopResult)
pub fn pop_with_result(&self, result: PopResult)
Pop the top page, handing result to its pusher-registered
push_for_result callback.
Sourcepub fn request_back(&self)
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), seeBackPolicy’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.
Sourcepub fn replace(&self, builder: impl Fn() -> AnyView<State> + 'static)
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.
Sourcepub fn replace_with(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
transition: TransitionSpec,
)
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.
Sourcepub fn replace_with_options(
&self,
builder: impl Fn() -> AnyView<State> + 'static,
options: ReplaceOptions,
)
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§fn clone(&self) -> NavigatorController<State>
fn clone(&self) -> NavigatorController<State>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§fn default() -> NavigatorController<State>
fn default() -> NavigatorController<State>
Auto Trait Implementations§
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.