Skip to main content

Ui

Struct Ui 

Source
pub struct Ui<Msg = Callback> { /* private fields */ }
Expand description

The interface of one frame: what the walk over a widget tree produced.

Besides the Scene to paint it holds everything the shell asks of a frame afterwards — what a click, a long press or a dismissal answers, what can take the focus, which areas scroll, which widgets can be dragged or dropped on — so that events are routed against the frame the reader saw. It is made by build_ui and read until the next frame replaces it.

Implementations§

Source§

impl<Msg: Clone> Ui<Msg>

Source

pub fn overflows(&self) -> &[Overflowing]

The scene to hand to the renderer. Boxes in this frame whose children did not fit inside them.

Empty is the normal answer. A non-empty one means content is being drawn outside its parent — invisible where it is clipped, unhittable where it leaves the window, and silent either way until something asks. That silence is what let a task row’s delete button sit off-screen through three milestones.

Source

pub fn scrollbars(&self) -> &[Scrollbar]

The scrollbars this frame drew, and therefore the ones a pointer may drag. Empty where the platform draws none — see crate::Scrollbars.

Source

pub fn scene(&self) -> &Scene

The Scene this frame painted.

Source

pub fn semantics(&self) -> &[(WidgetId, Rect, SemanticsProperties)]

The frame’s accessibility tree: every meaningful node with its bounds on screen and its annotation (frus_core::SemanticsProperties). Paint order (= reading order). The shell pushes it to AccessKit.

Source

pub fn system_ui_style( &self, status_bar: Point, navigation_bar: Point, ) -> SystemUiOverlayStyle

What the system bars should look like over this frame (#46): the regions under status_bar answer for the status bar and those under navigation_bar for the other, the one drawn last first and field by field. What none states is left None, for crate::SystemUiOverlayStyle::resolve to take from the theme.

The shell picks the two points: the first row of the screen’s content under the status bar, and the last one above the navigation bar.

Source

pub fn wants_animation(&self) -> bool

true when a widget animates continuously (the framework must redraw). Whether this tree’s widgets want the next frame: a spinner turning, an ink ripple spreading, a pull being held.

It answers for the widgets and nothing else. A fetch still in flight also owes the screen a frame — see frus_core::images_in_flight — and that is the process’s business, asked by whoever drives the loop. It used to be folded in here, which made this method’s answer depend on what an unrelated part of the program happened to be doing: in the test suite, where everything shares one process, a refresh area with nothing pulled asked for frames whenever another test was loading an image (milestone 411).

Source

pub fn hit(&self, point: Point) -> Option<WidgetId>

Identity of the topmost clickable widget containing point.

Source

pub fn msg_for(&self, id: WidgetId) -> Option<Msg>

The message tied to a given clickable widget. None for a target that swallows input without emitting anything.

It is always paired with hit, so the two have to agree on which target an identity means: every registered target therefore has one of its own, the dismissal barrier below an overlay included.

Source

pub fn top_dismiss(&self) -> Option<Msg>

Dismissal message of the topmost overlay (for Escape).

Source

pub fn long_press_at(&self, point: Point) -> Option<Msg>

Long-press message of the topmost target containing point.

Source

pub fn refresh_areas(&self) -> &[Refreshable]

The frame’s pull-to-refresh areas, with the configuration each was built with. The shell steps them and reads their refreshing flag from here.

Source

pub fn dismissables(&self) -> &[Dismissable]

The frame’s dismissible items, with the configuration each was built with.

Source

pub fn sheets(&self) -> &[SheetArea]

The frame’s sheets, with the configuration each was built with and the scroll areas walked inside it.

Source

pub fn sheet_at(&self, point: Point) -> Option<&SheetArea>

The sheet whose panel is under point, the last one walked winning — which is the one painted on top.

Source

pub fn sheet(&self, id: WidgetId) -> Option<&SheetArea>

The sheet id, when it is in the frame.

Source

pub fn sheet_holding(&self, area: WidgetId) -> Option<&SheetArea>

The sheet the scroll area area was walked inside, when there is one — the innermost, should sheets nest, since an outer one counts the inner one’s areas too.

Source

pub fn dismissable_at(&self, point: Point) -> Option<Dismissable>

The topmost dismissible item containing point — the candidate a press has to weigh against the scrollable underneath it.

Source

pub fn focus_hit(&self, point: Point) -> Option<(WidgetId, Rect)>

Topmost focusable widget containing point: (id, its bounds).

Source

pub fn focus_directional( &self, current: WidgetId, direction: FocusDirection, ) -> Option<WidgetId>

Nearest focusable in the given direction (arrow navigation, a geometric policy): among the focusables whose centre lies on the right side, it minimises the distance along the main axis with a penalty on the cross-axis offset. None when there is nothing in that direction.

Source

pub fn focus_next( &self, current: Option<WidgetId>, forward: bool, ) -> Option<WidgetId>

Next/previous focus stop for Tab, wrapping. With no current focus, the first (or the last).

Tree order, unless something said otherwise. Stops carrying an explicit order are sorted ahead of those that do not, smallest first, and the sort is applied within a traversal group rather than across the whole frame — so a reordered dialog does not reshuffle the page behind it. Stops marked skip are passed over here while remaining reachable by a click: the keyboard’s order and the pointer’s reach are two different questions.

Source

pub fn traversal_order(&self) -> Vec<WidgetId>

The Tab order: the participating stops, minus those that asked to be skipped, with each traversal group’s members sorted among themselves.

A stable sort on the order key, so everything without one keeps tree order and ties do too — the property that makes an explicit order a local statement rather than a rearrangement of the whole frame.

Source

pub fn keystroke( &self, stroke: KeyStroke, focused: Option<WidgetId>, ) -> Vec<Msg>

What a keystroke means here: the messages it sends, in the order they should be applied.

The resolution, in one place because it is the whole feature:

  1. Only scopes containing the focused stop are candidates; with nothing focused, all of them are. Innermost first — scopes is filled on the way out of the walk, so that order is already the one wanted.
  2. A crate::KeyboardListener gets the first refusal, and a None from it lets the stroke carry on.
  3. A direct binding (crate::CallbackShortcuts) sends its message.
  4. Otherwise a crate::Shortcuts binding names an intent, and the innermost crate::Actions that answers it supplies the message. An intent nobody answers does nothing — deliberately: a key bound to a meaning the current screen has no answer for should be inert, not an error.
  5. Every crate::ActionListener watching that intent adds its message too.

Empty means nobody wanted it, and the caller should carry on to whatever it would have done with the key.

Source

pub fn scroll_hit(&self, point: Point) -> Option<Scrollable>

Topmost scrollable area containing point.

Source

pub fn scroll_chain( &self, point: Point, ) -> impl Iterator<Item = Scrollable> + '_

Every scrollable area containing point, innermost first — the whole stack a finger has under it.

Self::scroll_hit answers which one is on top, which is the right question for a wheel or a scrollbar. A finger asks a different one: a strip that only slides across, sitting in a page that only scrolls down, cannot take a drag downwards, and the page behind it can. Deciding that needs the ones behind as well.

Source

pub fn widget_rect(&self, id: WidgetId) -> Option<Rect>

Frame of a focusable widget id, when it is present this frame — so the shell can find the focused field’s geometry (vertical caret movement).

Source

pub fn ink_box(&self, id: WidgetId) -> Option<Rect>

The box of the inked surface id, when the frame has one — what the shell needs to start a splash: where inside it the finger landed, and how big it is.

The topmost match wins, as the hit-test does: two inked surfaces can overlap, and the one that took the tap is the one drawn last.

Source

pub fn focusable_ids(&self) -> impl Iterator<Item = WidgetId> + '_

The identities of every focusable widget of the frame (the scope included) — so the shell can detect the focus disappearing (an overlay closed) and restore it.

Source

pub fn form_of(&self, id: WidgetId) -> Vec<(WidgetId, Rect)>

The focus stops of the form id is part of, in tree order, each with its box this frame (unclipped: a field scrolled out of sight is still a field of the form). A stop in no crate::AutofillGroup is a form of one. Empty when id is not a focus stop this frame.

Stops, not fields: which of them take part in autofill is a question for the widgets (crate::Widget::autofill_hints), which the shell has and this does not.

Source

pub fn form_group(&self, id: WidgetId) -> Option<WidgetId>

The crate::AutofillGroup focus stop id sits in, if it is a stop this frame and sits in one.

Source

pub fn group_stops(&self, group: WidgetId) -> Vec<(WidgetId, Rect)>

Every focus stop inside the crate::AutofillGroup group, in tree order, with its unclipped box. Empty once the group has left the screen — which is the moment a form is finished with, and the platform may offer to save what was typed in it.

Source

pub fn scrollable_viewport(&self, id: WidgetId) -> Option<Rect>

Frame (viewport) of the scrollable area id, when there is one — so the shell can find a multi-line field’s width/height (caret following).

Source

pub fn reveal( &self, id: WidgetId, runtime: &Runtime, ) -> Vec<(WidgetId, (f32, f32))>

The scroll offsets that would bring id into view, nearest region first.

Empty when it is already in view, when the frame does not contain it, or when nothing around it scrolls. Nobody has to check first: an empty answer is the answer that nothing needs to move.

Nested regions are walked from the inside out, and each is told where the target ended up rather than where it started. A sideways strip inside a page that scrolls down moves the target across, and the page then decides how far down it still is; asking both about the original box would have them fight over the same pixels and land somewhere neither wanted.

Source

pub fn scroll_regions(&self) -> &[Scrollable]

Every scrollable area of the frame — geometry, bounds and physics — which is what the runtime needs to drive momentum and edges.

Source

pub fn scroll_region(&self, id: WidgetId) -> Option<Scrollable>

The area id, when it is present this frame.

Source

pub fn scrollable_maxes(&self) -> Vec<(WidgetId, f32, f32)>

SingleChildScrollView bounds (id, max_x, max_y) of every scrollable area.

Source

pub fn scrollbar_at(&self, point: Point) -> Option<Scrollbar>

Scrollbar thumb under point (to start a drag).

Source

pub fn scrollbar_near(&self, point: Point) -> Option<Scrollbar>

The scrollbar a pointer is near enough to wake: inside its track, or within a tap target’s reach of its thumb.

Wider than Ui::scrollbar_at, and — unlike it — it answers for a bar that has faded out entirely, which is the whole point. A bar nobody can see is a bar nobody can grab, so the reference lets a mouse coming near one bring it back first (scrollbar.dart:766); only then is it something to take hold of.

Source

pub fn draggable_at(&self, point: Point) -> Option<(WidgetId, Rect)>

Topmost draggable widget under point: (id, its bounds).

Source

pub fn drag_source_at(&self, point: Point) -> Option<DragSource>

Topmost drag source under point, with what it carries.

Source

pub fn drop_zone_at(&self, point: Point) -> Option<DropZone>

Topmost drop target under point.

Source

pub fn reorderable_at(&self, point: Point) -> Option<WidgetId>

Topmost reorderable widget under point: its id. The basis of reordering drag-and-drop (the source on press, the target on drop) — independent of clickability.

Source

pub fn reorderables_at( &self, point: Point, ) -> impl Iterator<Item = WidgetId> + '_

Every reorderable under point, topmost first.

Self::reorderable_at answers which one is on top, which is the right question for a press: whatever is nearest the finger is what the finger grabbed. A drop asks a different one, because the thing on top may be a grip that nothing can be dropped on — see Widget::reorder_droppable — and the row it belongs to, which can, is the one behind it.

Source

pub fn reorderables(&self) -> &[(WidgetId, Rect)]

Every reorderable of the frame, with its box, in paint order.

Source

pub fn interactive_at(&self, point: Point) -> Option<(WidgetId, Rect)>

Topmost interactive viewport (InteractiveViewer) under point: (id, its screen viewport). The shell routes panning and zooming to it.

Source

pub fn interactive_bounds(&self) -> Vec<(WidgetId, Rect)>

Interactive viewports (id, screen viewport), to drive the inertia (fling) and the clamping of the pan on the framework’s side.

Auto Trait Implementations§

§

impl<Msg = Callback> !RefUnwindSafe for Ui<Msg>

§

impl<Msg = Callback> !Send for Ui<Msg>

§

impl<Msg = Callback> !Sync for Ui<Msg>

§

impl<Msg = Callback> !UnwindSafe for Ui<Msg>

§

impl<Msg> Freeze for Ui<Msg>
where Vec<Hit<Msg>>: Freeze, Vec<Msg>: Freeze, Vec<Scope<Msg>>: Freeze, Vec<(Range<usize>, Rc<dyn Fn(KeyStroke) -> Option<Msg>>)>: Freeze,

§

impl<Msg> Unpin for Ui<Msg>
where Vec<Hit<Msg>>: Unpin, Vec<Msg>: Unpin, Vec<Scope<Msg>>: Unpin, Vec<(Range<usize>, Rc<dyn Fn(KeyStroke) -> Option<Msg>>)>: Unpin,

§

impl<Msg> UnsafeUnpin for Ui<Msg>
where Vec<Hit<Msg>>: UnsafeUnpin, Vec<Msg>: UnsafeUnpin, Vec<Scope<Msg>>: UnsafeUnpin, Vec<(Range<usize>, Rc<dyn Fn(KeyStroke) -> Option<Msg>>)>: 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<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<Msg> IntoMsg<Msg> for Msg

Source§

fn defer(work: impl Fn() -> Msg + 'static) -> Msg

The message that stands for work’s result.
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.