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>
impl<Msg: Clone> Ui<Msg>
Sourcepub fn overflows(&self) -> &[Overflowing]
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.
Sourcepub fn scrollbars(&self) -> &[Scrollbar]
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.
Sourcepub fn semantics(&self) -> &[(WidgetId, Rect, SemanticsProperties)]
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.
Sourcepub fn system_ui_style(
&self,
status_bar: Point,
navigation_bar: Point,
) -> SystemUiOverlayStyle
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.
Sourcepub fn wants_animation(&self) -> bool
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).
Sourcepub fn hit(&self, point: Point) -> Option<WidgetId>
pub fn hit(&self, point: Point) -> Option<WidgetId>
Identity of the topmost clickable widget containing point.
Sourcepub fn msg_for(&self, id: WidgetId) -> Option<Msg>
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.
Sourcepub fn top_dismiss(&self) -> Option<Msg>
pub fn top_dismiss(&self) -> Option<Msg>
Dismissal message of the topmost overlay (for Escape).
Sourcepub fn long_press_at(&self, point: Point) -> Option<Msg>
pub fn long_press_at(&self, point: Point) -> Option<Msg>
Long-press message of the topmost target containing point.
Sourcepub fn refresh_areas(&self) -> &[Refreshable]
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.
Sourcepub fn dismissables(&self) -> &[Dismissable]
pub fn dismissables(&self) -> &[Dismissable]
The frame’s dismissible items, with the configuration each was built with.
Sourcepub fn sheets(&self) -> &[SheetArea]
pub fn sheets(&self) -> &[SheetArea]
The frame’s sheets, with the configuration each was built with and the scroll areas walked inside it.
Sourcepub fn sheet_at(&self, point: Point) -> Option<&SheetArea>
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.
Sourcepub fn sheet_holding(&self, area: WidgetId) -> Option<&SheetArea>
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.
Sourcepub fn dismissable_at(&self, point: Point) -> Option<Dismissable>
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.
Sourcepub fn focus_hit(&self, point: Point) -> Option<(WidgetId, Rect)>
pub fn focus_hit(&self, point: Point) -> Option<(WidgetId, Rect)>
Topmost focusable widget containing point: (id, its bounds).
Sourcepub fn focus_directional(
&self,
current: WidgetId,
direction: FocusDirection,
) -> Option<WidgetId>
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.
Sourcepub fn focus_next(
&self,
current: Option<WidgetId>,
forward: bool,
) -> Option<WidgetId>
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.
Sourcepub fn traversal_order(&self) -> Vec<WidgetId>
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.
Sourcepub fn keystroke(
&self,
stroke: KeyStroke,
focused: Option<WidgetId>,
) -> Vec<Msg>
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:
- Only scopes containing the focused stop are candidates; with nothing
focused, all of them are. Innermost first —
scopesis filled on the way out of the walk, so that order is already the one wanted. - A
crate::KeyboardListenergets the first refusal, and aNonefrom it lets the stroke carry on. - A direct binding (
crate::CallbackShortcuts) sends its message. - Otherwise a
crate::Shortcutsbinding names an intent, and the innermostcrate::Actionsthat 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. - Every
crate::ActionListenerwatching 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.
Sourcepub fn scroll_hit(&self, point: Point) -> Option<Scrollable>
pub fn scroll_hit(&self, point: Point) -> Option<Scrollable>
Topmost scrollable area containing point.
Sourcepub fn scroll_chain(
&self,
point: Point,
) -> impl Iterator<Item = Scrollable> + '_
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.
Sourcepub fn widget_rect(&self, id: WidgetId) -> Option<Rect>
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).
Sourcepub fn ink_box(&self, id: WidgetId) -> Option<Rect>
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.
Sourcepub fn focusable_ids(&self) -> impl Iterator<Item = WidgetId> + '_
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.
Sourcepub fn form_of(&self, id: WidgetId) -> Vec<(WidgetId, Rect)>
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.
Sourcepub fn form_group(&self, id: WidgetId) -> Option<WidgetId>
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.
Sourcepub fn group_stops(&self, group: WidgetId) -> Vec<(WidgetId, Rect)>
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.
Sourcepub fn scrollable_viewport(&self, id: WidgetId) -> Option<Rect>
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).
Sourcepub fn reveal(
&self,
id: WidgetId,
runtime: &Runtime,
) -> Vec<(WidgetId, (f32, f32))>
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.
Sourcepub fn scroll_regions(&self) -> &[Scrollable]
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.
Sourcepub fn scroll_region(&self, id: WidgetId) -> Option<Scrollable>
pub fn scroll_region(&self, id: WidgetId) -> Option<Scrollable>
The area id, when it is present this frame.
Sourcepub fn scrollable_maxes(&self) -> Vec<(WidgetId, f32, f32)>
pub fn scrollable_maxes(&self) -> Vec<(WidgetId, f32, f32)>
SingleChildScrollView bounds (id, max_x, max_y) of every scrollable area.
Sourcepub fn scrollbar_at(&self, point: Point) -> Option<Scrollbar>
pub fn scrollbar_at(&self, point: Point) -> Option<Scrollbar>
Scrollbar thumb under point (to start a drag).
Sourcepub fn scrollbar_near(&self, point: Point) -> Option<Scrollbar>
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.
Sourcepub fn draggable_at(&self, point: Point) -> Option<(WidgetId, Rect)>
pub fn draggable_at(&self, point: Point) -> Option<(WidgetId, Rect)>
Topmost draggable widget under point: (id, its bounds).
Sourcepub fn drag_source_at(&self, point: Point) -> Option<DragSource>
pub fn drag_source_at(&self, point: Point) -> Option<DragSource>
Topmost drag source under point, with what it carries.
Sourcepub fn drop_zone_at(&self, point: Point) -> Option<DropZone>
pub fn drop_zone_at(&self, point: Point) -> Option<DropZone>
Topmost drop target under point.
Sourcepub fn reorderable_at(&self, point: Point) -> Option<WidgetId>
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.
Sourcepub fn reorderables_at(
&self,
point: Point,
) -> impl Iterator<Item = WidgetId> + '_
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.
Sourcepub fn reorderables(&self) -> &[(WidgetId, Rect)]
pub fn reorderables(&self) -> &[(WidgetId, Rect)]
Every reorderable of the frame, with its box, in paint order.
Sourcepub fn interactive_at(&self, point: Point) -> Option<(WidgetId, Rect)>
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.
Sourcepub fn interactive_bounds(&self) -> Vec<(WidgetId, Rect)>
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.