frus_widgets/widget.rs
1//! The [`Widget`] trait, generic over the message type emitted on interaction.
2
3use frus_core::{Rect, Scene, SemanticsProperties, Size};
4use frus_layout::Style;
5
6use crate::interaction::{Cursor, Key, Status};
7use crate::portal::Placement;
8use crate::runtime::Edit;
9use crate::scroll::Axis;
10use crate::theme::Theme;
11
12/// A slot built on demand: the closure a `Table` header, a `Table` row or a `Kanban`
13/// column takes for a cell that holds a **widget** rather than a string. It is called
14/// again on every rebuild, so it hands back a fresh widget each time.
15pub type CellFn<Msg = crate::callback::Callback> = Box<dyn Fn() -> Box<dyn Widget<Msg>>>;
16
17/// Axis along which a **reorderable** widget moves while dragging: `Table` columns slide
18/// **horizontally** (the default), `Kanban` cards **vertically**. The shell adapts the drag
19/// preview (ghost direction, insertion indicator) to this axis.
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
21pub enum ReorderAxis {
22 /// Horizontal reordering (columns) — the default.
23 #[default]
24 Horizontal,
25 /// Vertical reordering (stacked cards).
26 Vertical,
27}
28
29/// The **sizing** half of a style: the fields that decide how big a box is, and none
30/// of the ones that decide what happens inside it.
31///
32/// For a wrapper that nests its child ([`crate::Draggable`], [`crate::Hero`]) and wants
33/// the box its child would have had. Copying the *whole* style would inset that child
34/// twice — once by the wrapper's padding, then again by the child's, which is the same
35/// number.
36pub(crate) fn sizing_of(style: Style) -> Style {
37 Style {
38 width: style.width,
39 height: style.height,
40 min_width: style.min_width,
41 min_height: style.min_height,
42 max_width: style.max_width,
43 max_height: style.max_height,
44 flex_grow: style.flex_grow,
45 flex_shrink: style.flex_shrink,
46 flex_basis: style.flex_basis,
47 aspect_ratio: style.aspect_ratio,
48 ..Default::default()
49 }
50}
51
52/// A widget: a composable interface element.
53///
54/// `Msg` is the application message type emitted on interaction (a message-passing
55/// model, in the Elm/iced style).
56/// What the paint walk knows and a widget does not, at the moment its layer filter is
57/// asked for.
58///
59/// Both fields are there for the same reason: they are properties of *where the widget
60/// turned out to be*, not of what it was built with. A mask is written in fractions of
61/// a box, and the box is only a place on screen once layout has run; a shared backdrop
62/// belongs to the nearest enclosing group, and a widget cannot see its own ancestors.
63#[derive(Clone, Copy, Debug)]
64pub struct FilterContext {
65 /// The widget's own box, on screen.
66 pub box_rect: frus_core::Rect,
67 /// The identity of the nearest enclosing [`crate::BackdropGroup`], if any — the
68 /// key a backdrop asking to be shared should use.
69 pub backdrop_group: Option<u64>,
70}
71
72/// The axes a widget asks to **fill**: on each, it takes the room its parent leaves it
73/// rather than shrink-wrapping its children.
74///
75/// # Why this is asked and not declared
76///
77/// `width: 100%` looks like the same thing and is not. A percentage resolves against the
78/// parent's **resolved** width, which a parent that shrink-wraps has not got yet — it is
79/// waiting on this very child to find out how wide it should be. Both are "full width" in
80/// English, and only one can be computed in time:
81///
82/// | | what it needs | known |
83/// |---|---|---|
84/// | `width: 100%` | the parent's own width | on the way back **up** |
85/// | a fill request | the room being offered | on the way **down** |
86///
87/// Fifteen widgets in this crate said it the first way and every one of them collapsed
88/// under a plain column (milestone 404). Asking is the only phrasing the layout can answer.
89#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
90pub struct FillAxes {
91 /// Take the width the parent offers.
92 pub horizontal: bool,
93 /// Take the height the parent offers.
94 pub vertical: bool,
95}
96
97/// Where a drag lands along a widget that takes one: see [`Widget::drag_track`].
98#[derive(Clone, Copy, Debug, PartialEq)]
99pub struct DragTrack {
100 /// How far in from each end the travel starts, in logical pixels.
101 pub inset: f32,
102 /// Whether the travel runs from the right in a right-to-left reading direction.
103 pub mirrored: bool,
104 /// How a press and a slide move the value (milestone 650).
105 pub mode: DragMode,
106}
107
108/// **How a press and a slide move a dragged value** (milestone 650) — the reference's
109/// `SliderInteraction`, in the terms the shell needs to apply it.
110#[derive(Clone, Copy, Debug, Default, PartialEq)]
111pub enum DragMode {
112 /// The value goes where the pointer is, from the press on: a tap jumps it, a slide
113 /// carries it. The default.
114 #[default]
115 Follow,
116 /// The press sets the value; the slide that follows changes nothing.
117 TapOnly,
118 /// The press leaves the value where it is; the slide moves it by its own length, from
119 /// `origin`, the value's place along the travel when the press landed.
120 Slide {
121 /// Where the value was, `0..=1` along the travel.
122 origin: f32,
123 },
124 /// As [`Slide`](Self::Slide), and only for a press within `radius` logical pixels of
125 /// the thumb at `origin`: a press anywhere else starts nothing at all.
126 SlideThumb {
127 /// Where the value, and so the thumb, was, `0..=1` along the travel.
128 origin: f32,
129 /// How far from the thumb's centre a press still takes it.
130 radius: f32,
131 },
132 /// **Two thumbs on one travel** (milestone 651), the reference's range slider: the
133 /// press picks one ([`DragTrack::pick_thumb`]) and the drag moves it with the pointer;
134 /// the widget hears it through [`Widget::on_thumb_drag`].
135 Thumbs {
136 /// The two thumbs' places, `0..=1` along the travel, the start first.
137 values: [f32; 2],
138 /// How far from a thumb's centre a press is on it.
139 radius: f32,
140 },
141}
142
143/// A moment of a drag on one of a widget's thumbs: see [`Widget::on_thumb_drag`].
144#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
145pub enum ThumbDrag {
146 /// The thumb was picked: the gesture starts.
147 Start,
148 /// It moved.
149 Move,
150 /// It was let go.
151 End,
152}
153
154impl DragTrack {
155 /// The whole width, left to right, following the pointer: what a widget with no
156 /// opinion answers.
157 pub const WHOLE: Self = Self {
158 inset: 0.0,
159 mirrored: false,
160 mode: DragMode::Follow,
161 };
162
163 /// Where `x` falls along `rect`'s travel, as a fraction `0..=1`, for a reading
164 /// direction that is right to left when `rtl`.
165 ///
166 /// One function, used by a drag's start, every move and its end alike: three copies
167 /// of this arithmetic would agree on every slider until one of them did not.
168 pub fn fraction(self, rect: crate::Rect, x: f32, rtl: bool) -> f32 {
169 self.along(rect, x, rtl).clamp(0.0, 1.0)
170 }
171
172 /// [`fraction`](Self::fraction) before it is held to the travel, so that a slide that
173 /// runs past an end still measures its whole length.
174 fn along(self, rect: crate::Rect, x: f32, rtl: bool) -> f32 {
175 let width = rect.width - 2.0 * self.inset;
176 let t = if width > 0.0 {
177 (x - rect.x - self.inset) / width
178 } else {
179 0.0
180 };
181 if self.mirrored && rtl {
182 1.0 - t
183 } else {
184 t
185 }
186 }
187
188 /// Whether a press at `x` starts anything at all: always, but for
189 /// [`DragMode::SlideThumb`], which wants the press on its thumb.
190 pub fn engages(self, rect: crate::Rect, x: f32, rtl: bool) -> bool {
191 match self.mode {
192 DragMode::SlideThumb { origin, radius } => {
193 let width = (rect.width - 2.0 * self.inset).max(0.0);
194 let t = if self.mirrored && rtl {
195 1.0 - origin
196 } else {
197 origin
198 };
199 let thumb = rect.x + self.inset + t * width;
200 (x - thumb).abs() <= radius
201 }
202 _ => true,
203 }
204 }
205
206 /// The value a drag pressed at `press_x` and now at `x` stands for, as a fraction of
207 /// the travel; `None` when this moment changes nothing. `moved` is `false` for the
208 /// press itself and `true` for every movement after it — and for the release, which
209 /// is where the slide ended.
210 ///
211 /// A slide that started from the value moves it by the pointer's movement, as the
212 /// reference's does, so a thumb grabbed off its centre does not jump to the pointer.
213 pub fn value_at(
214 self,
215 rect: crate::Rect,
216 press_x: f32,
217 x: f32,
218 moved: bool,
219 rtl: bool,
220 ) -> Option<f32> {
221 match self.mode {
222 DragMode::Follow | DragMode::Thumbs { .. } => Some(self.fraction(rect, x, rtl)),
223 DragMode::TapOnly => (!moved).then(|| self.fraction(rect, press_x, rtl)),
224 DragMode::Slide { origin } | DragMode::SlideThumb { origin, .. } => moved.then(|| {
225 (origin + self.along(rect, x, rtl) - self.along(rect, press_x, rtl)).clamp(0.0, 1.0)
226 }),
227 }
228 }
229
230 /// **Which thumb a press at `press_x` takes** on a [`DragMode::Thumbs`] track, `0` for
231 /// the start and `1` for the end, the movement since the press being `dx` — the
232 /// reference's `_defaultRangeThumbSelector`. The nearer thumb, unless the press is on
233 /// both, when the first movement decides: towards the start takes the start. `None`
234 /// while that is undecided, or on a track without thumbs.
235 pub fn pick_thumb(self, rect: crate::Rect, press_x: f32, dx: f32, rtl: bool) -> Option<usize> {
236 let DragMode::Thumbs { values, radius } = self.mode else {
237 return None;
238 };
239 let t = self.fraction(rect, press_x, rtl);
240 let width = (rect.width - 2.0 * self.inset).max(0.0);
241 let on = |v: f32| (t - v).abs() * width < radius;
242 if on(values[0]) && on(values[1]) {
243 // Towards the start is leftwards, or rightwards when the travel runs from the
244 // right.
245 let towards_start = if self.mirrored && rtl {
246 dx > 0.0
247 } else {
248 dx < 0.0
249 };
250 let towards_end = if self.mirrored && rtl {
251 dx < 0.0
252 } else {
253 dx > 0.0
254 };
255 return match (towards_start, towards_end) {
256 (true, _) => Some(0),
257 (_, true) => Some(1),
258 _ => None,
259 };
260 }
261 Some(if t * 2.0 < values[0] + values[1] {
262 0
263 } else {
264 1
265 })
266 }
267
268 /// The value a drag pressed at `press_x` lets go of at `x`: where the pointer is, where
269 /// the press set it, or where the slide took it.
270 pub fn released_at(self, rect: crate::Rect, press_x: f32, x: f32, rtl: bool) -> f32 {
271 match self.mode {
272 DragMode::TapOnly => self.fraction(rect, press_x, rtl),
273 _ => self
274 .value_at(rect, press_x, x, true, rtl)
275 .unwrap_or_else(|| self.fraction(rect, x, rtl)),
276 }
277 }
278}
279
280impl FillAxes {
281 /// Shrink-wrap on both axes — what a widget with no opinion answers.
282 pub const NONE: Self = Self {
283 horizontal: false,
284 vertical: false,
285 };
286 /// Take the width offered; hug the content vertically.
287 pub const WIDTH: Self = Self {
288 horizontal: true,
289 vertical: false,
290 };
291 /// Take the height offered; hug the content horizontally.
292 pub const HEIGHT: Self = Self {
293 horizontal: false,
294 vertical: true,
295 };
296 /// Take everything offered — a full-screen shell.
297 pub const BOTH: Self = Self {
298 horizontal: true,
299 vertical: true,
300 };
301
302 /// The axes asked for, as one flex direction, or `None` where that cannot be said —
303 /// neither axis, or both. For the walk, which resolves each axis separately anyway.
304 pub fn single(self) -> Option<frus_layout::FlexDirection> {
305 match (self.horizontal, self.vertical) {
306 (true, false) => Some(frus_layout::FlexDirection::Row),
307 (false, true) => Some(frus_layout::FlexDirection::Column),
308 _ => None,
309 }
310 }
311
312 /// Whether one axis is asked for.
313 pub fn wants(self, horizontal: bool) -> bool {
314 if horizontal {
315 self.horizontal
316 } else {
317 self.vertical
318 }
319 }
320
321 /// The axis a [`frus_layout::FlexDirection`] names, and nothing else.
322 pub fn along(direction: frus_layout::FlexDirection) -> Self {
323 if direction.is_horizontal() {
324 Self::WIDTH
325 } else {
326 Self::HEIGHT
327 }
328 }
329}
330
331/// A **widget**: a node of the tree that is laid out by [`Widget::style`], painted by
332/// [`Widget::paint`] and asked what a click means by [`Widget::on_click`]; `Msg` is the
333/// message it emits when the reader interacts with it.
334///
335/// Only those four are required. Everything else — focus, scrolling, editing, semantics,
336/// the hooks a container uses to build its children late — has a default that does nothing,
337/// so a widget implements what it takes part in and no more.
338pub trait Widget<Msg = crate::callback::Callback> {
339 /// Layout style (handed to `frus-layout`).
340 fn style(&self) -> Style;
341
342 /// The widget's children (possibly empty).
343 fn children(&self) -> &[Box<dyn Widget<Msg>>];
344
345 /// Paints the widget's own decoration, according to its status (hover / focus /
346 /// cursor / selection) and the current theme.
347 fn paint(&self, bounds: Rect, status: Status, theme: &Theme, scene: &mut Scene);
348
349 /// Message to emit on click (`None` = not clickable).
350 fn on_click(&self) -> Option<Msg>;
351
352 /// Whether a press that lands on this widget and on **nothing inside it** stops
353 /// here.
354 ///
355 /// An ordinary widget is transparent to a press it has no message for: the press
356 /// carries on to whatever is behind. That is right for a label on a card and wrong
357 /// for a **surface** — a floating panel, a sheet, a bar — where the thing behind is
358 /// the page and the press reaching it means the panel is dismissed by a click on its
359 /// own padding, or on a row that said it was unavailable.
360 ///
361 /// It is registered **before** the widget's children, so anything inside still wins;
362 /// all this catches is what nothing inside claimed. `false` by default, because a
363 /// widget that stops presses it does not use is the surprising one.
364 ///
365 /// This is not [`crate::AbsorbPointer`], which discards the whole subtree's targets.
366 /// Here the subtree keeps every one of them and only the gaps between them are
367 /// closed.
368 fn opaque(&self) -> bool {
369 false
370 }
371
372 /// **Stable** identity key (independent of the position among siblings).
373 /// `None` = positional identity. See [`crate::Keyed`].
374 fn key(&self) -> Option<u64> {
375 None
376 }
377
378 /// **Short** name of the widget — for the inspector and diagnostic dumps.
379 /// Defaults to the name of the concrete type, without module path or
380 /// generics (each implementation gets its own monomorphised copy of this
381 /// default body). Transparent wrappers (`Box`, [`crate::Keyed`]…) delegate
382 /// to their content.
383 fn debug_name(&self) -> &'static str {
384 short_type_name::<Self>()
385 }
386
387 /// The widget's **accessibility annotation** (role, label, value, state),
388 /// exposed to assistive technologies through the AccessKit tree. `None` =
389 /// no semantics of its own (a layout container — its children, though,
390 /// may have some). See [`frus_core::SemanticsProperties`].
391 fn semantics(&self) -> Option<SemanticsProperties> {
392 None
393 }
394
395 /// What this widget says about its **child's** subtree, when it knows something the
396 /// child cannot know about itself — the [`crate::Semantics`] wrapper, and nothing else
397 /// so far.
398 ///
399 /// [`Widget::semantics`] is a widget answering for itself and covers the ordinary
400 /// case. This covers the one it cannot: a caller handed an already-built widget, with
401 /// no way in. Read in one place in the walk, the way a
402 /// [`ModalBarrier`](crate::barrier::ModalBarrier) is — the subtree is walked exactly as
403 /// usual and what it produced is reconciled afterwards, so a widget deep inside
404 /// annotates itself without knowing anything is speaking for it.
405 fn describes(&self) -> Option<crate::semantics::Description> {
406 None
407 }
408
409 /// Applies a key to the focused widget: mutates the edit state
410 /// (cursor/selection) and returns a message if the **value** changes.
411 fn on_edit(&self, _edit: &mut Edit, _key: &Key) -> Option<Msg> {
412 None
413 }
414
415 /// **Positional** click: a message emitted according to where the click landed (local
416 /// coordinates from the widget's top-left corner, within the `width × height` box), taking
417 /// **priority** over [`on_click`](Self::on_click). For clickable sub-regions — e.g. the
418 /// **suffix** icon of a [`crate::TextField`] (clear / reveal) or a chart **point**
419 /// (milestone 221). `None` (the default) = no sub-region; the shell falls back to `on_click`.
420 fn positional_click(
421 &self,
422 _local_x: f32,
423 _local_y: f32,
424 _width: f32,
425 _height: f32,
426 ) -> Option<Msg> {
427 None
428 }
429
430 /// Shape of the **system cursor** wanted at the **local** position `(local_x, local_y)` inside
431 /// the widget's `width × height` box (milestone 205): `Some(Cursor::Pointer)` over a clickable
432 /// sub-region (a suffix icon…), `None` (the default) = no opinion, the shell keeps the default
433 /// cursor. Does not affect clicking; this is purely the pointer's appearance on hover.
434 fn cursor_icon(
435 &self,
436 _local_x: f32,
437 _local_y: f32,
438 _width: f32,
439 _height: f32,
440 ) -> Option<Cursor> {
441 None
442 }
443
444 /// Cursor index matching a local position (px from the widget's top-left
445 /// corner) — for placing the caret on click. `local_y` picks the **line** in a
446 /// multi-line field (ignored on a single line).
447 ///
448 /// `width` = the field's width, `scroll_cursor` = the cursor from which to recompute
449 /// the current **scroll** (the same one the render used), so that a click lands right
450 /// even when the text is scrolled. `None` = not a text field.
451 fn cursor_at(
452 &self,
453 _local_x: f32,
454 _local_y: f32,
455 _width: f32,
456 _scroll_cursor: usize,
457 ) -> Option<usize> {
458 None
459 }
460
461 /// SingleChildScrollView metrics of a **multi-line** field, for a widget width and a cursor:
462 /// `(content height, visible box height, caret top, caret height)`, in content
463 /// space (px). The shell uses them to register the scrollable region and to keep
464 /// the caret in view. `None` otherwise.
465 fn text_metrics(&self, _width: f32, _cursor: usize) -> Option<(f32, f32, f32, f32)> {
466 None
467 }
468
469 /// Frame (input box) of a **multi-line** field within its `rect` — the area where
470 /// the text scrolls, below the label. Used to place the scrollbar and the
471 /// scrollable region exactly on the box. `None` otherwise.
472 fn text_viewport(&self, _rect: crate::Rect) -> Option<crate::Rect> {
473 None
474 }
475
476 /// Moves the caret vertically in a multi-line field and returns
477 /// `(new index, visual column used)`.
478 ///
479 /// - `down`: down (`true`) or up. `page`: jump by a **page** (the visible
480 /// height) rather than by a **line**.
481 /// - `goal_x`: remembered target visual column (px) to preserve while crossing
482 /// shorter lines; `None` = start from the current column. The returned value
483 /// is the column to remember again for the next jump.
484 /// - **Line**: `None` if already on the first/last line (or not multi-line) —
485 /// the shell then moves the focus instead.
486 /// - **Page**: clamped to the field (it never leaves it); `None` only when not
487 /// multi-line.
488 fn caret_vertical(
489 &self,
490 _width: f32,
491 _cursor: usize,
492 _down: bool,
493 _page: bool,
494 _goal_x: Option<f32>,
495 ) -> Option<(usize, f32)> {
496 None
497 }
498
499 /// The currently selected text (for copy/cut).
500 fn selected_text(&self, _edit: &Edit) -> Option<String> {
501 None
502 }
503
504 /// The field's **whole** value, if this widget is a text field — to give the
505 /// IME its input context (suggestions). `None` otherwise.
506 fn text_value(&self) -> Option<&str> {
507 None
508 }
509
510 /// The words this widget shows, **if it takes part in a
511 /// [`SelectionArea`](crate::SelectionArea)**: a [`Text`](crate::Text), and nothing that is
512 /// not made of words. The walk registers such a widget as a text stop when it is inside an
513 /// area, so that a selection can begin, end and pass through it.
514 fn selection_text(&self) -> Option<&str> {
515 None
516 }
517
518 /// The character boundary of [`selection_text`](Self::selection_text) nearest a local
519 /// position (px from the widget's top-left corner) in a box `width` wide — the layout the
520 /// widget was **drawn** with, which is what a press is hit against.
521 fn selection_hit(&self, _local_x: f32, _local_y: f32, _width: f32) -> Option<usize> {
522 None
523 }
524
525 /// The handle that hangs from character boundary `index` of this widget's words — the
526 /// start handle when `start`, the end handle otherwise — in local coordinates, for a widget
527 /// `width` wide: where it is painted, and so where a finger takes it. `None` for anything
528 /// that is not a text.
529 fn selection_grip(
530 &self,
531 _width: f32,
532 _index: usize,
533 _start: bool,
534 ) -> Option<crate::SelectionHandle> {
535 None
536 }
537
538 /// The **bar** a [`SelectionArea`](crate::SelectionArea) offers over its selection, for
539 /// `context`, when the application has said what it holds
540 /// ([`SelectionArea::selection_toolbar`](crate::SelectionArea::selection_toolbar)): `Some`
541 /// of the bar, or `Some(None)` for no bar at all. `None` for anything else — and for an area
542 /// that was told nothing — whose texts then offer Copy and Select all.
543 fn area_toolbar(&self, _context: crate::ToolbarContext) -> Option<Option<&dyn Widget<Msg>>> {
544 None
545 }
546
547 /// The **bar** over the part of a selection area's selection that lies in this widget —
548 /// `range`, in characters — for `context`, and the box it is placed against in local
549 /// coordinates, for a widget `width` wide. `None` for anything that is not a text, or when
550 /// the list for `context` is empty.
551 fn region_toolbar(
552 &self,
553 _context: crate::ToolbarContext,
554 _width: f32,
555 _range: (usize, usize),
556 ) -> Option<(Rect, &dyn Widget<Msg>)> {
557 None
558 }
559
560 /// Whether this widget takes **typing**: a field that can be changed, which is what
561 /// the software keyboard is for. A text field that may only be read and selected — a
562 /// [`read_only`](crate::TextField::read_only) one, a [`Text`](crate::Text) made
563 /// [`selectable`](crate::Text::selectable) — answers `false`: it has a caret and a
564 /// selection, and no use for a keyboard sliding up over the words being read.
565 ///
566 /// Defaults to whether it holds a text value at all.
567 fn takes_typing(&self) -> bool {
568 self.text_value().is_some()
569 }
570
571 /// The message that puts `value` in this field: the one typing would have produced,
572 /// for a value the **framework** restores rather than the user typing it.
573 ///
574 /// Undo needs it and nothing else does. The value is the application's — a field owns
575 /// its caret and not its text — so an undo cannot reach in and set what is on screen;
576 /// it has to go back through a message like any other edit, or the next frame would
577 /// paint the value the application still holds.
578 fn replace_value(&self, _value: String) -> Option<Msg> {
579 None
580 }
581
582 /// Range `(start, end)` of the word around the given index (for double-click).
583 fn word_at(&self, _index: usize) -> Option<(usize, usize)> {
584 None
585 }
586
587 /// The two handles of the selection in `edit`, start then end, for a field `width`
588 /// wide whose content is scrolled down by `scroll_y` — where they are painted, and
589 /// so where a finger takes them. `None` when there is no selection, or this is not
590 /// a text field.
591 fn selection_handles(
592 &self,
593 _width: f32,
594 _edit: &Edit,
595 _scroll_y: f32,
596 ) -> Option<[crate::SelectionHandle; 2]> {
597 None
598 }
599
600 /// The **bar** this field shows over its selection (Cut, Copy, Paste, Select all — see
601 /// [`crate::ToolbarItem`]) for `context`, or `None` when there is none to show: this is
602 /// not a text field, or the application's list for that context is empty.
603 ///
604 /// The runtime asks it when the shell has marked this field as showing its bar, and
605 /// floats the answer over everything, anchored on [`selection_anchor`](Self::selection_anchor).
606 /// One bar per context, built once and kept — a bar is a widget the walk borrows for
607 /// the frame, and two different lists must not share an identity.
608 fn selection_toolbar(&self, _context: crate::ToolbarContext) -> Option<&dyn Widget<Msg>> {
609 None
610 }
611
612 /// The box the bar is placed against, in the field's **local** coordinates: the
613 /// selection's, or the caret's when nothing is selected. Like
614 /// [`selection_handles`](Self::selection_handles) it is the paint's own geometry.
615 fn selection_anchor(&self, _width: f32, _edit: &Edit, _scroll_y: f32) -> Option<Rect> {
616 None
617 }
618
619 /// The editing action pressing this widget performs **on the focused field**, for a
620 /// button of the bar that carries no message (see [`crate::EditAction`]).
621 fn edit_action(&self) -> Option<crate::EditAction> {
622 None
623 }
624
625 /// Keystrokes this subtree binds to **intents** — see [`crate::Shortcuts`].
626 fn shortcut_bindings(&self) -> &[(crate::shortcuts::KeyStroke, crate::shortcuts::Intent)] {
627 &[]
628 }
629
630 /// Keystrokes this subtree binds **straight to messages** — see
631 /// [`crate::CallbackShortcuts`].
632 fn shortcut_callbacks(&self) -> &[(crate::shortcuts::KeyStroke, Msg)] {
633 &[]
634 }
635
636 /// Intents this subtree **answers** — see [`crate::Actions`].
637 fn action_bindings(&self) -> &[(crate::shortcuts::Intent, Msg)] {
638 &[]
639 }
640
641 /// Intents this subtree **watches** without answering — see
642 /// [`crate::ActionListener`].
643 fn action_listeners(&self) -> &[(crate::shortcuts::Intent, Msg)] {
644 &[]
645 }
646
647 /// Every keystroke reaching this subtree, handed to a closure — see
648 /// [`crate::KeyboardListener`]. `None` (the default) is not a listener.
649 #[allow(clippy::type_complexity)]
650 fn on_keystroke(
651 &self,
652 ) -> Option<std::rc::Rc<dyn Fn(crate::shortcuts::KeyStroke) -> Option<Msg>>> {
653 None
654 }
655
656 /// If `true`, the widget can take keyboard focus (click or Tab).
657 fn focusable(&self) -> bool {
658 false
659 }
660
661 /// Message for the focus **arriving in or leaving this widget's subtree** (milestone
662 /// 660) — the reference's `onFocusChange`: `true` when the focused widget is now this
663 /// one or inside it and was not, `false` the other way. The shell asks once a frame,
664 /// after the focus has moved, every widget on the two paths from the root that the move
665 /// changed, the one that lost it first.
666 fn on_focus_change(&self, _focused: bool) -> Option<Msg> {
667 None
668 }
669
670 /// Message for a **press outside this widget while it holds the focus** (milestone
671 /// 660) — the reference's `onTapOutside`: sent before the press moves the focus.
672 fn on_tap_outside(&self) -> Option<Msg> {
673 None
674 }
675
676 /// If `true`, a focusable widget **takes the focus when it appears**: a menu's first
677 /// row when the menu opens, a field on a screen made to type into (milestone 605). Where
678 /// the focus came from is remembered, and it goes back there when this one goes.
679 fn autofocus(&self) -> bool {
680 false
681 }
682
683 /// If `false`, **nothing inside this subtree** can take focus — the reference's
684 /// `ExcludeFocus`. A dimmed panel behind a sheet is still drawn and still measured;
685 /// it simply stops being somewhere Tab can land.
686 fn descendants_focusable(&self) -> bool {
687 true
688 }
689
690 /// If `true`, this subtree's focus stops are **skipped by Tab** while remaining
691 /// focusable by a click — the reference's `ExcludeFocusTraversal`. The two are
692 /// separate questions: a toolbar button may be reachable with the pointer and still
693 /// not belong in the keyboard's order.
694 fn focus_skip_traversal(&self) -> bool {
695 false
696 }
697
698 /// A **traversal order** for this subtree's focus stops, smallest first — the
699 /// reference's `NumericFocusOrder`. `None` leaves them in tree order, which is where
700 /// everything sits until someone says otherwise.
701 fn focus_order(&self) -> Option<f32> {
702 None
703 }
704
705 /// If `true`, this subtree is a **traversal group**: an order set inside it is
706 /// resolved among its own members and nowhere else, so a reordered dialog does not
707 /// reshuffle the page behind it.
708 fn focus_group(&self) -> bool {
709 false
710 }
711
712 /// What this field is **for**, so the platform can fill it in — see
713 /// [`AutofillHint`](crate::AutofillHint). Empty (the default) is a field that takes
714 /// no part in autofill at all.
715 ///
716 /// A list, because a field can legitimately be more than one thing: a sign-in box
717 /// taking an email address is the username *and* the email.
718 fn autofill_hints(&self) -> &[crate::AutofillHint] {
719 &[]
720 }
721
722 /// If `true`, this subtree's fields are **one form** — the reference's
723 /// `AutofillGroup`. A service shown a password with no username beside it has
724 /// nothing to save the pair under.
725 fn autofill_group(&self) -> bool {
726 false
727 }
728
729 /// If `true`, the widget draws its focus indicator **itself** (the driver then
730 /// does not stroke the generic ring). E.g. `TextField`.
731 fn draws_own_focus(&self) -> bool {
732 false
733 }
734
735 /// If `true`, the widget responds to pointer dragging (sliders, handles).
736 fn draggable(&self) -> bool {
737 false
738 }
739
740 /// **Where along a [`draggable`](Self::draggable) widget its drag lands** (milestone
741 /// 648): how far in from each end the travel starts, and whether it runs from the
742 /// right in a right-to-left reading direction. The fraction [`on_drag`](Self::on_drag)
743 /// and its edges are given is measured along that travel. The default is the whole
744 /// width, left to right.
745 fn drag_track(&self) -> DragTrack {
746 DragTrack::WHOLE
747 }
748
749 /// Message for a moment of a drag on one of this widget's thumbs (milestone 651), on a
750 /// [`DragMode::Thumbs`] track: `thumb` is the one the press picked, `0` for the start,
751 /// and `fraction` the pointer's place along the travel. A press that has picked none
752 /// yet sends nothing.
753 fn on_thumb_drag(&self, _thumb: usize, _moment: ThumbDrag, _fraction: f32) -> Option<Msg> {
754 None
755 }
756
757 /// Message produced while dragging, `fraction` being the relative horizontal
758 /// position (`0.0..=1.0`) within the widget's bounds.
759 fn on_drag(&self, _fraction: f32) -> Option<Msg> {
760 None
761 }
762
763 /// Message produced when a value drag **begins** — on the press, before the
764 /// first [`on_drag`](Self::on_drag).
765 ///
766 /// With [`on_drag_end`](Self::on_drag_end) it brackets the stream: `on_drag` fires
767 /// on every pixel of the movement, and an application that saves to disk, seeks a
768 /// video or asks the network on each of those does it sixty times a second. The
769 /// bracket is what lets it do the cheap thing while the finger is down and the
770 /// expensive one when it lifts — and without an end there is no moment at which
771 /// to do it at all.
772 ///
773 /// Not to be confused with [`on_dropped`](Self::on_dropped), which belongs to
774 /// drag-and-**drop**: that one moves a thing, this one changes a number.
775 fn on_drag_start(&self, _fraction: f32) -> Option<Msg> {
776 None
777 }
778
779 /// Message produced when a value drag **ends** — on the release, with the
780 /// fraction the pointer finished on.
781 ///
782 /// See [`on_drag_start`](Self::on_drag_start).
783 fn on_drag_end(&self, _fraction: f32) -> Option<Msg> {
784 None
785 }
786
787 /// Message produced by a horizontal drag expressed as a **delta**: `dx` is the
788 /// movement (logical px) since the last event. For handles that **accumulate**
789 /// (column resizing), unlike [`on_drag`](Self::on_drag) (an absolute fraction,
790 /// e.g. a slider). The shell tries it **before** `on_drag`; a widget implements
791 /// only one of the two.
792 fn on_drag_delta(&self, _dx: f32) -> Option<Msg> {
793 None
794 }
795
796 /// If this widget is a **shared element**, its tag. Two heroes with the same tag on
797 /// the two sides of a route transition are one thing in two places.
798 /// See [`crate::Hero`].
799 fn hero_tag(&self) -> Option<u64> {
800 None
801 }
802
803 /// If this widget can be **picked up** and dropped elsewhere, what it carries.
804 /// See [`crate::Draggable`].
805 fn drag_payload(&self) -> Option<u64> {
806 None
807 }
808
809 /// Does this item lift on a **long press** rather than on the first movement?
810 /// The answer inside a scrollable, where a plain drag belongs to the scroll.
811 ///
812 /// It is asked of both kinds of lift — a [`crate::Draggable`] carrying a payload, and a
813 /// [`crate::ReorderableList`] row carrying itself — because the question is the same
814 /// one: a list that stops scrolling is a worse bug than an item that does not move.
815 fn drag_needs_long_press(&self) -> bool {
816 false
817 }
818
819 /// How solid the item left behind looks while a copy of it is being dragged.
820 fn drag_ghost_opacity(&self) -> f32 {
821 1.0
822 }
823
824 /// Message sent when a drag of this item ends, `true` if a target took it.
825 fn on_dropped(&self, _accepted: bool) -> Option<Msg> {
826 None
827 }
828
829 /// Is this widget a **drop target**? See [`crate::DragTarget`].
830 fn drop_zone(&self) -> bool {
831 false
832 }
833
834 /// Would this target take `payload`? Only asked of a drop target.
835 fn accepts_drag(&self, _payload: u64) -> bool {
836 true
837 }
838
839 /// Message sent when an accepted item is dropped on this target.
840 fn on_drop(&self, _payload: u64) -> Option<Msg> {
841 None
842 }
843
844 /// Would this target take these **files**, dragged onto the window from outside
845 /// the application? Only asked of a drop target; none takes files unless it says
846 /// so. See [`crate::DragTarget::on_files`].
847 fn accepts_files(&self, _paths: &[std::path::PathBuf]) -> bool {
848 false
849 }
850
851 /// Message sent when accepted files are dropped on this target.
852 fn on_files_dropped(&self, _paths: Vec<std::path::PathBuf>) -> Option<Msg> {
853 None
854 }
855
856 /// If this widget is a **reorderable header**, its column index. The shell uses
857 /// it to identify the **source** column (on press) and the **target** column
858 /// (under the pointer on release) of a reordering drag.
859 fn reorder_index(&self) -> Option<usize> {
860 None
861 }
862
863 /// Message emitted when this header (the source) is **dropped** on column `to`.
864 /// The widget knows its own index and the `on_reorder(from, to)` callback.
865 fn on_reorder(&self, _to: usize) -> Option<Msg> {
866 None
867 }
868
869 /// Movement **axis** of this reorderable (default [`ReorderAxis::Horizontal`]): the shell
870 /// orients the drag preview (ghost + insertion indicator) accordingly. `Kanban` cards
871 /// return [`ReorderAxis::Vertical`].
872 fn reorder_axis(&self) -> ReorderAxis {
873 ReorderAxis::Horizontal
874 }
875
876 /// Is a **horizontal** reorderable dropped *between* its neighbours, like a list's row,
877 /// rather than *into the place* of the one under the pointer, like a table's column?
878 /// `false` by default, which is the table.
879 ///
880 /// The two are different gestures, not one gesture on two axes. A column follows the
881 /// pointer with a continuous slide and takes the index of the column it lands on. A row
882 /// is inserted before or after the slot it is over — whichever half the pointer is in —
883 /// with an insertion line, a gap that opens there, and the nearest slot of its own list
884 /// when the pointer is over none. A widget that answers `true` gets the second.
885 ///
886 /// Only asked of a horizontal reorderable: every vertical one is inserted between its
887 /// neighbours already, and answering here changes nothing for it.
888 fn reorder_inserts(&self) -> bool {
889 false
890 }
891
892 /// Can this reorderable be **picked up** as a drag source? `true` by default for every
893 /// reorderable. A **target-only** slot — the drop zone at the end of a Kanban column —
894 /// returns `false`: a card can be **dropped** there, not **lifted** from it (otherwise the
895 /// drag would raise an empty ghost that moves nothing).
896 fn reorder_draggable(&self) -> bool {
897 true
898 }
899
900 /// Can this reorderable be **dropped onto**? `true` by default, and the mirror image of
901 /// [`reorder_draggable`](Self::reorder_draggable): a **source-only** grip — a list row's
902 /// drag handle — returns `false`.
903 ///
904 /// A handle is a small box inside a much larger row, and the drop is aimed at whatever
905 /// is topmost under the pointer. Without this, carrying a row over another row's handle
906 /// would aim at the handle: the insertion line would be drawn across the grip instead of
907 /// across the row, which is a promise about where the row is going that is not true.
908 fn reorder_droppable(&self) -> bool {
909 true
910 }
911
912 /// What to **say** to a screen reader once this reorderable has been moved to `to` — the
913 /// spoken counterpart of the ghost, for someone who cannot see it land.
914 ///
915 /// `None` leaves the shell its own wording, which can only speak of the axis: the index
916 /// a `Kanban` card is dropped at is a flat `column × stride + position` that means
917 /// nothing read out loud. A widget whose index **is** a position says so itself.
918 fn reorder_announcement(&self, _to: usize) -> Option<String> {
919 None
920 }
921
922 /// Text to **announce** to the screen reader when this widget is **activated** (mouse
923 /// click or Enter/Space) — a live region reads it out loud. Describes the effect the
924 /// activation **produced** ("Sorted by Name ascending", "All rows selected"), for the
925 /// blind user who cannot perceive the visual change. `None` = nothing to announce
926 /// (the default).
927 fn announce(&self) -> Option<String> {
928 None
929 }
930
931 /// If `true`, the widget is a **stack**: its children are superimposed layers
932 /// (the same box), rendered in order (the last one on top).
933 fn stack(&self) -> bool {
934 false
935 }
936
937 /// If `true`, the widget is a **section with a sticky header**
938 /// ([`crate::StickyHeader`]): its first child is painted, and takes taps, at the top of
939 /// what is visible of the section, over the second (milestone 602).
940 fn sticky_header(&self) -> bool {
941 false
942 }
943
944 /// If the widget **places its children with a function** — a
945 /// [`crate::CustomMultiChildLayout`] — the function and one key per child. The children
946 /// are then laid out and placed in the walk, by the function, and not in this node's
947 /// layout (milestone 601).
948 fn custom_layout(&self) -> Option<crate::customlayout::CustomLayout<'_>> {
949 None
950 }
951
952 /// If `true`, the widget animates **continuously** (driven by time, not by a
953 /// target): the framework keeps redrawing. E.g. `CircularProgressIndicator`.
954 fn continuous(&self) -> bool {
955 false
956 }
957
958 /// If `true`, this widget is a **repaint boundary**: its subtree is cached
959 /// (primitives + interaction maps) and **reused as is** as long as its geometry
960 /// and the interaction state of its descendants do not change — a widget
961 /// animating elsewhere no longer forces it to repaint.
962 /// See [`crate::Container::repaint_boundary`] and `paintcache.rs`.
963 fn repaint_boundary(&self) -> bool {
964 false
965 }
966
967 /// If the widget is a scrollable container, returns its content.
968 fn scroll_content(&self) -> Option<&dyn Widget<Msg>> {
969 None
970 }
971
972 /// If the widget is a **virtualised list**, returns its description (item count,
973 /// height, factory). Only the visible items are built.
974 fn virtual_list(
975 &self,
976 _viewport: frus_core::Size,
977 ) -> Option<crate::list::VirtualList<'_, Msg>> {
978 None
979 }
980
981 /// If the widget is a **paged view**, returns its description (page count,
982 /// axis, factory). Like a virtualised list, only the visible pages are built.
983 fn page_view(&self) -> Option<crate::pageview::PagedView<'_, Msg>> {
984 None
985 }
986
987 /// Message sent by a paged view when the page on screen changes.
988 fn on_page_changed(&self, _page: usize) -> Option<Msg> {
989 None
990 }
991
992 /// Message sent by a **scroll region** when its offset changes — the reading half
993 /// of [`crate::ScrollPosition`].
994 ///
995 /// Silent by default, and that is the answer to what it costs: a region nobody is
996 /// listening to reports nothing, so a fling over an ordinary list is exactly as
997 /// cheap as it was. A region somebody *is* listening to sends a message per frame
998 /// while it moves, because a bar that fades in as the page goes down needs every
999 /// frame of it — and a region that only wants to know when the end is near says so
1000 /// through [`Widget::scroll_grain`] rather than by being reported less honestly.
1001 fn on_scroll(&self, _position: crate::scrollposition::ScrollPosition) -> Option<Msg> {
1002 None
1003 }
1004
1005 /// How far this region must move before it says so again, in pixels; `0` — the
1006 /// default — reports **every** change.
1007 ///
1008 /// A grain suppresses the reports in between, never the last one: a region that
1009 /// comes to rest anywhere other than where it was last reported reports that,
1010 /// whatever the grain. Otherwise a coarse grain would leave the application
1011 /// believing a list was at 1 200 when it settled at 1 247, which is a worse answer
1012 /// than a slower one.
1013 fn scroll_grain(&self) -> f32 {
1014 0.0
1015 }
1016
1017 /// If the widget takes one axis from its content's **preferred** size, returns
1018 /// that axis and the step its measurement is rounded up to. See
1019 /// [`crate::Intrinsic`].
1020 fn intrinsic(&self) -> Option<(crate::constraints::IntrinsicAxis, Option<f32>)> {
1021 None
1022 }
1023
1024 /// If the widget lays its child out to constraints of **its own**, which the
1025 /// child may exceed, returns them. See [`crate::OverflowBox`].
1026 fn overflow_box(&self) -> Option<crate::constraints::Overflow> {
1027 None
1028 }
1029
1030 /// The box this widget **gives its child** as a function of the box it was offered,
1031 /// with the child laid out in it separately and the box then sized to what came
1032 /// back. `None` — the default — means the child shares this node's layout, as
1033 /// everything ordinary does. See [`crate::ConstraintsTransformBox`].
1034 fn constraints_transform(&self) -> Option<crate::constraints::ConstraintsTransform> {
1035 None
1036 }
1037
1038 /// If the box this widget's [`constraints_transform`](Self::constraints_transform) makes
1039 /// **follows its child's size over time** rather than at once, how (milestone 594). See
1040 /// [`crate::AnimatedSize`].
1041 fn animated_size(&self) -> Option<crate::animatedsize::SizeAnimation> {
1042 None
1043 }
1044
1045 /// If the box this widget's [`constraints_transform`](Self::constraints_transform) makes
1046 /// is **a multiple of its child's size** — `(across, down)`, `1` for as big as the child
1047 /// — the multiples (milestones 596 and 597). See [`crate::SizeTransition`] and
1048 /// [`crate::Aligned::width_factor`].
1049 fn size_factor(&self) -> Option<(f32, f32)> {
1050 None
1051 }
1052
1053 /// Whether the box this widget's [`constraints_transform`](Self::constraints_transform)
1054 /// makes **cuts its child** to itself. A reveal does; an anchor with a factor lets its
1055 /// child spill (milestone 597).
1056 fn clips_to_box(&self) -> bool {
1057 false
1058 }
1059
1060 /// If the widget builds its content **from its actual box**, returns the
1061 /// `size → widget` factory. The content is built on the fly: no retained state
1062 /// and no overlay (like a virtualised list item).
1063 fn layout_builder(&self) -> Option<&dyn Fn(Size) -> Box<dyn Widget<Msg>>> {
1064 None
1065 }
1066
1067 /// If the widget draws something **over its scroll region**, returns the
1068 /// `offset → overlay` factory. See [`crate::ScrollOverlay`].
1069 ///
1070 /// The region is this widget's first child, so the offset the walk hands over is its
1071 /// own child's and nothing has to be named. Like a `layout_builder`'s content, the
1072 /// overlay is built on the fly and has no retained state.
1073 fn scroll_overlay(&self) -> Option<&crate::scrolloverlay::OverlayBuilder<Msg>> {
1074 None
1075 }
1076
1077 /// SingleChildScrollView axis (or axes), for a scrollable container.
1078 fn scroll_axis(&self) -> crate::scroll::Axis {
1079 crate::scroll::Axis::Vertical
1080 }
1081
1082 /// The edge and fling behaviour of a scrollable container, when this widget
1083 /// wants one in particular. `None` — the usual answer — leaves the choice to
1084 /// the application, which defaults to what the platform does.
1085 fn scroll_physics(&self) -> Option<crate::physics::ScrollPhysics> {
1086 None
1087 }
1088
1089 /// **Whether this area draws a scrollbar**, when it wants its own answer rather than
1090 /// the application's. `None` — the default — follows the application, which follows
1091 /// the platform. See [`crate::Scrollbars`].
1092 fn scrollbars(&self) -> Option<crate::physics::Scrollbars> {
1093 None
1094 }
1095
1096 /// **Keep this area's scrollbar on screen**, instead of letting it fade away when
1097 /// the area stops moving (`scrollbar.dart:214`).
1098 ///
1099 /// `None` — the default — lets it fade, which is what a bar over content should do.
1100 /// `Some(true)` pins it: for an area whose content is not obviously scrollable, or
1101 /// one a reader is meant to be able to aim at without scrolling first.
1102 fn thumb_visibility(&self) -> Option<bool> {
1103 None
1104 }
1105
1106 /// What the **software keyboard** should be, when this widget is the focused
1107 /// editable one.
1108 ///
1109 /// Only ever asked of the field that has focus — the platform layer finds it the
1110 /// same way it finds the caret — so a widget that is not editable never has to
1111 /// answer, and the default is the ordinary text keyboard with a *Done* key.
1112 ///
1113 /// See [`crate::ime`] for what the two halves mean and why the mapping to the
1114 /// platform's numbers is tested rather than trusted.
1115 fn ime(&self) -> crate::ime::Ime {
1116 crate::ime::Ime::default()
1117 }
1118
1119 /// If the widget is a portal, returns its floating content and its placement.
1120 fn overlay(&self) -> Option<(&dyn Widget<Msg>, Placement)> {
1121 None
1122 }
1123
1124 /// Message emitted when the scrim of a modal is clicked (dismissal), if any.
1125 fn overlay_dismiss(&self) -> Option<Msg> {
1126 None
1127 }
1128
1129 /// The colour of the scrim behind this widget's **modal** overlay, when it wants one
1130 /// in particular. `None` — the usual answer — leaves it to the scheme's `scrim`
1131 /// role at the framework's own opacity.
1132 ///
1133 /// The alpha is the caller's: a scrim is the one colour whose *transparency* is the
1134 /// whole point, so a fully opaque value here means an opaque scrim, and
1135 /// [`Color::TRANSPARENT`](frus_core::Color::TRANSPARENT) means none at all — an
1136 /// overlay that darkens nothing, which the reference reaches by the same route.
1137 fn overlay_scrim(&self, _theme: &crate::theme::Theme) -> Option<frus_core::Color> {
1138 None
1139 }
1140
1141 /// If `true`, this widget's **anchored** overlay (a menu…) **traps focus**: Tab and the
1142 /// arrow keys cycle within its focusables while it is open (the keyboard pattern of menus).
1143 /// Modal (scrimmed) overlays already trap by default; a tooltip or an autocomplete list
1144 /// (focus stays on the field) do **not**. Default: `false`.
1145 fn overlay_traps_focus(&self) -> bool {
1146 false
1147 }
1148
1149 /// Target of the widget's own animated value (e.g. `1.0` for a switch that is on,
1150 /// `0.0` for off). The runtime drives the retained value towards this target and
1151 /// hands it back through `Status::value`. `None` = no animated value.
1152 fn anim_target(&self) -> Option<f32> {
1153 None
1154 }
1155
1156 /// **Target transform** of an animated one (`Transform::animated`): the runtime
1157 /// tweens the scales and the turn through `anim_duration`/`anim_curve` and hands the
1158 /// interpolated value back through `Runtime::anim_transform`, which the paint walk
1159 /// reads in place of the static `transform_scale`/`transform_rotate`. `None` = the
1160 /// transform does not move.
1161 ///
1162 /// The **pivot** is not part of it: see
1163 /// [`TransformValues`](crate::runtime::TransformValues).
1164 fn anim_transform(&self) -> Option<crate::runtime::TransformValues> {
1165 None
1166 }
1167
1168 /// Duration (seconds) of the animated value's transition (`anim_target`).
1169 /// Default: the framework's standard duration.
1170 fn anim_duration(&self) -> f32 {
1171 crate::runtime::ANIM_DURATION
1172 }
1173
1174 /// Easing curve of the animated value's transition (`anim_target`).
1175 /// Default: linear.
1176 fn anim_curve(&self) -> frus_core::Curve {
1177 frus_core::Curve::Linear
1178 }
1179
1180 /// Where the animated value **starts when the widget appears**. `None`, the default: at
1181 /// its target, with no transition, so a switch shown on is simply on. A widget that
1182 /// plays something from its start when it appears — an animation — says `Some(0.0)`,
1183 /// and the value travels to its target in `anim_duration` from the first frame
1184 /// (milestone 691).
1185 fn anim_initial(&self) -> Option<f32> {
1186 None
1187 }
1188
1189 /// If the widget is an **opacity group**, returns the (target) opacity `[0,1]`
1190 /// applied to its whole subtree **as one**: the paint walk wraps its primitives
1191 /// in a composited layer at that opacity — no double-blending where they
1192 /// overlap. `None` = not a group. Combined with `anim_target`, the opacity
1193 /// **animates** (a group fade).
1194 fn opacity_group(&self) -> Option<f32> {
1195 None
1196 }
1197
1198 /// **Target** background colour of an animated background
1199 /// (`Container::animated_color`): the runtime tweens it (through
1200 /// `anim_duration`/`anim_curve`) and hands the interpolated value back in
1201 /// `Status::anim_color`. `None` = no animated colour.
1202 fn anim_color(&self) -> Option<frus_core::Color> {
1203 None
1204 }
1205
1206 /// **Target** size of an animated size (`Container::animated_size`): the runtime
1207 /// tweens it (through `anim_duration`/`anim_curve`) and the interpolated size is
1208 /// injected **at layout** (see `effective_style`). `None` = fixed size.
1209 fn anim_size(&self) -> Option<Size> {
1210 None
1211 }
1212
1213 /// **Target** corner radius of an animated radius (`Container::animated_radius`):
1214 /// the runtime tweens it and hands the interpolated value back in
1215 /// `Status::anim_radius`. `None` = fixed radius.
1216 fn anim_radius(&self) -> Option<frus_core::BorderRadius> {
1217 None
1218 }
1219
1220 /// **Target** padding of an animated padding (`Container::animated_padding`):
1221 /// the runtime tweens it and the interpolated padding is injected **at layout**
1222 /// (see `effective_style`). `None` = fixed padding.
1223 fn anim_padding(&self) -> Option<frus_core::Insets> {
1224 None
1225 }
1226
1227 /// The pair of fractions this node's **offset rule** is made of, animated: an
1228 /// alignment's two fractions, or a slide's. `None` — the default — leaves the rule
1229 /// reading the widget's own numbers.
1230 ///
1231 /// One quantity serves both rules because a node has one of them. See
1232 /// [`crate::AnimatedAlign`] and [`crate::AnimatedSlide`], each of which gives the
1233 /// rule it animates a node of its own.
1234 fn anim_offset(&self) -> Option<(f32, f32)> {
1235 None
1236 }
1237
1238 /// **Target pins** of an animated stack layer ([`crate::AnimatedPositioned`]): the
1239 /// runtime tweens them and the interpolated pins are read where the stack lays its
1240 /// layers out. `None` — the default — leaves [`Widget::positioned`] alone.
1241 ///
1242 /// A pin that is **unset does not animate**: `None` on an edge is not nought there,
1243 /// it is a box not pinned on that side at all, and moving between the two would be
1244 /// interpolating between two arrangements rather than two values.
1245 fn anim_pins(&self) -> Option<crate::positioned::Positioning> {
1246 None
1247 }
1248
1249 /// **Target fractions** of an animated share of the parent
1250 /// (`FractionallySizedBox::animated`), as `(width factor, height factor)`: the
1251 /// runtime tweens them and the interpolated pair is injected **at layout** (see
1252 /// `effective_style`), like the size and the padding. `None` = fixed factors.
1253 ///
1254 /// An axis whose factor is unset follows its content, and the same rule applies:
1255 /// it does not travel to or from a factor, it changes what the axis is doing.
1256 fn anim_fractions(&self) -> Option<(Option<f32>, Option<f32>)> {
1257 None
1258 }
1259
1260 /// **Target text style** an animated subtree is heading for
1261 /// (`AnimatedDefaultTextStyle`). `None` = the subtree inherits whatever it inherits.
1262 ///
1263 /// The odd one out of the animated family: what the runtime tweens here is not this
1264 /// node's box or its paint but **the theme everything below it reads**, so the value
1265 /// is consumed by the theme swap rather than by the node. That swap happens at four
1266 /// points of the walk — the layout pass, the relayout fingerprint, the paint, and
1267 /// [`crate::build_deferred`] — and they all go through `crate::ui::scoped_theme`
1268 /// so that they cannot answer differently.
1269 fn anim_text_style(&self) -> Option<frus_core::TextStyle> {
1270 None
1271 }
1272
1273 /// **Alignment** of the single child within the box: the walk offsets the child
1274 /// through the free space according to the alignment's fractions, resolved
1275 /// against the reading direction (physical or directional — see
1276 /// [`frus_core::AlignmentGeometry`]). Being continuous, a `Tween<Alignment>`
1277 /// read in `view()` slides the child. `None` = default flex placement.
1278 fn alignment_geometry(&self) -> Option<frus_core::AlignmentGeometry> {
1279 None
1280 }
1281
1282 /// **Paint offset** `(dx, dy)` applied to the widget's whole subtree: the render
1283 /// and the hit-test are offset **without touching layout** (siblings do not move,
1284 /// the child may overflow its box). Continuous → a `Tween` read in `view()` slides
1285 /// the subtree. `None` = no offset. See [`crate::Transform`].
1286 fn transform_translate(&self) -> Option<(f32, f32)> {
1287 None
1288 }
1289
1290 /// **Paint offset as a fraction of the child's own size** `(fx, fy)`: `(0.5, 0.0)`
1291 /// slides the subtree half its own width to the right. Added to
1292 /// [`Widget::transform_translate`], and offsetting the render and the hit-test the
1293 /// same way, without touching layout. `None` = no offset.
1294 ///
1295 /// A fraction rather than a number because the number is not known where the widget
1296 /// is written: the child's size is decided by the layout, and something that has to
1297 /// slide exactly clear of itself — a panel off the edge, a badge half outside its
1298 /// anchor — would otherwise have to be told a width it was never given. See
1299 /// [`crate::FractionalTranslation`].
1300 fn translate_fraction(&self) -> Option<(f32, f32)> {
1301 None
1302 }
1303
1304 /// **Paint scaling** `(sx, sy, pivot)` of the whole subtree: the render and the
1305 /// hit-test are scaled — per axis — around the `pivot` (a
1306 /// [`frus_core::Alignment`] within the box), **without touching layout**. Stays
1307 /// axis-aligned (a scaled rect is still a rect). `None` = no scaling.
1308 /// See [`crate::Transform`].
1309 fn transform_scale(&self) -> Option<(f32, f32, frus_core::Alignment)> {
1310 None
1311 }
1312
1313 /// **Paint rotation** `(angle, pivot)` of the whole subtree: the subtree is
1314 /// painted rotated by `angle` radians (clockwise) around the `pivot` (a
1315 /// [`frus_core::Alignment`] within the box), **without touching layout**. The
1316 /// render goes through a rotated composited layer; the hit-test counter-rotates
1317 /// the point. `None` = no rotation. See [`crate::Transform`].
1318 fn transform_rotate(&self) -> Option<(f32, frus_core::Alignment)> {
1319 None
1320 }
1321
1322 /// **Shape clip** of the whole subtree: the paint walk wraps its primitives in a
1323 /// composited layer whose [`frus_core::ClipShape`] (rounded corners, ellipse)
1324 /// modulates the alpha — whatever falls outside the shape is erased, edges
1325 /// antialiased. `None` = no shape clip. See [`crate::ClipRRect`],
1326 /// [`crate::ClipOval`].
1327 fn clip_shape(&self) -> Option<frus_core::ClipShape> {
1328 None
1329 }
1330
1331 /// The widget's style **once the theme has had its say** — the layout half of the
1332 /// `caller ?? theme ?? framework` chain.
1333 ///
1334 /// Defaults to [`Widget::style`], which is what almost every widget wants: only the
1335 /// ones whose *size or spacing* a theme can set need to override this. It exists
1336 /// because `style` has no theme and cannot be given one without touching every
1337 /// implementation; a theme that could only reach `paint` would be able to recolour a
1338 /// divider but not make one thin, which is the setting an application actually asks
1339 /// for (milestone 309).
1340 ///
1341 /// A **transparent wrapper must forward this** alongside `style`, or its child's
1342 /// themed size is silently dropped for the unthemed one.
1343 fn style_themed(&self, _theme: &Theme) -> Style {
1344 self.style()
1345 }
1346
1347 /// The theme this widget imposes on **itself and its subtree**, given the one it
1348 /// inherits. `None` — the default — means "whatever came down from above", which is
1349 /// what every widget but [`crate::Themed`] answers.
1350 ///
1351 /// This is the third and last thing a theme needed to be usable: milestone 309 gave
1352 /// it per-widget defaults, and this makes those defaults *scoped*. A dark panel on a
1353 /// light page is one theme swapped for a subtree, not a colour written out by hand at
1354 /// every call site inside it.
1355 ///
1356 /// It is honoured by **layout as well as paint** — the walk and the layout pass swap
1357 /// the ambient theme on the way down and restore it on the way out — so a subtree
1358 /// theme can change a divider's height, not only its colour. A deferred overlay
1359 /// (a dialog, a drawer, a tooltip) is painted long after the walk has left the node
1360 /// that declared it, so it **carries the theme it was declared under** rather than
1361 /// the root's.
1362 ///
1363 /// Boxed because a `Theme` is a page and a half of tokens and this is asked of
1364 /// **every node, every frame**: an `Option<Box<_>>` costs a word on the stack of a
1365 /// recursion as deep as the tree, and the allocation happens only where a subtree
1366 /// actually claims a theme.
1367 fn theme_override(&self, _inherited: &Theme) -> Option<Box<Theme>> {
1368 None
1369 }
1370
1371 /// The **surface** this widget imposes on itself and its subtree, given the one it
1372 /// inherits. `None` — the default — means "whatever came down from above", which is
1373 /// what every widget but [`MediaScope`](crate::MediaScope) answers.
1374 ///
1375 /// The counterpart of [`Self::theme_override`], and it exists for the same reason one
1376 /// milestone later: a surface could until now only be narrowed **where a widget is
1377 /// constructed** (`SafeArea::build`), and the widget that knows what to narrow is often
1378 /// not the one doing the constructing. A shell hands its app bar's slot the description
1379 /// that slot should believe in; the bar then decides for itself whether to consume the
1380 /// status bar, which is how the reference splits that job across two widgets.
1381 ///
1382 /// Applied by the layout walk on the way down and held for the subtree, so anything
1383 /// reading [`MediaQuery::of`](crate::MediaQuery::of) below this node sees it — including
1384 /// a subtree deferred until [`Self::build_themed`], which runs after the swap.
1385 /// [`crate::build_deferred`], the relayout fingerprint and the paint walk make the same
1386 /// swap; the four staying in step is what keeps the cache and the picture honest.
1387 fn media_override(&self, _inherited: crate::MediaQuery) -> Option<crate::MediaQuery> {
1388 None
1389 }
1390
1391 /// The **shell** this widget imposes on its subtree: what a
1392 /// [`Scaffold`](crate::Scaffold) knows about itself and its slots do not.
1393 ///
1394 /// The third of the inherited things, after the theme and the surface, and it exists
1395 /// for the same reason as the second: a slot is handed to a shell **already built**, so
1396 /// the widget that knows there is a drawer is never the one that has to draw the button
1397 /// for it. The reference reads it from the context (`Scaffold.of`), which is how a bar
1398 /// with no `leading` grows a menu button on a screen that has a menu and stays empty on
1399 /// one that does not (`app_bar.dart:1010`).
1400 ///
1401 /// `None` — the default — means "whatever came down from above", which is what every
1402 /// widget but [`ScaffoldScope`](crate::ScaffoldScope) answers. Applied by the same four
1403 /// walks as [`Self::media_override`], and for the same reason: an
1404 /// [`AppBar`](crate::AppBar) is composed in [`Self::build_themed`], which runs after the
1405 /// swap, and the relayout fingerprint has to see what the composition saw.
1406 fn scaffold_override(&self) -> Option<crate::ScaffoldInfo> {
1407 None
1408 }
1409
1410 /// The [`ScrollBehavior`](crate::ScrollBehavior) this widget puts in force for **its
1411 /// subtree**, or `None` — the default — for whatever came down from above. Only
1412 /// [`ScrollConfiguration`](crate::ScrollConfiguration) answers otherwise. Applied by
1413 /// the same four walks as [`Self::scaffold_override`]: the scrollables under it record
1414 /// what it decides when they are registered (milestone 616).
1415 fn scroll_behavior_override(&self) -> Option<crate::ScrollBehavior> {
1416 None
1417 }
1418
1419 /// Builds this widget's subtree **from the ambient theme**, for the widgets that
1420 /// defer that decision — see [`ThemeBuilder`](crate::ThemeBuilder). Does nothing by
1421 /// default, which is what all but a handful of widgets want.
1422 ///
1423 /// [`Self::style_themed`] and [`Self::paint`] let a theme decide how a widget
1424 /// **looks**. This is for the questions a theme answers *earlier* than that: whether
1425 /// an application bar centres its title decides which children exist and in what
1426 /// order, and by the time anything is being painted the composition has already been
1427 /// made. A widget assembled by a builder — `AppBar::new().build()` — never sees a
1428 /// theme at all.
1429 ///
1430 /// Called by the layout pass on the way down, **before** [`Self::children`] is read,
1431 /// under the theme of the subtree the node sits in. It takes `&self` like every other
1432 /// hook, so an implementor needs interior mutability; that is safe here because a
1433 /// widget tree is rebuilt from `view` rather than mutated, so "once per instance" and
1434 /// "once per frame" are the same thing.
1435 fn build_themed(&self, _theme: &Theme) {}
1436
1437 /// [`Self::build_themed`], for the few widgets that also need **who they are** and
1438 /// **what the frame remembers** to compose their subtree. An
1439 /// [`AnimatedSwitcher`](crate::AnimatedSwitcher) keeps what it is letting go of in the
1440 /// runtime, under its own identity, and that is reachable nowhere else before its
1441 /// children are read.
1442 ///
1443 /// The walks call this one, and its default is `build_themed`, so a deferred widget that
1444 /// needs neither keeps implementing only that. A **transparent** wrapper must forward it
1445 /// with the identity untouched — it has none of its own — or the widget inside is built
1446 /// through `build_themed` and never learns where it is.
1447 fn build_in(
1448 &self,
1449 _id: crate::interaction::WidgetId,
1450 _runtime: &crate::runtime::Runtime,
1451 theme: &Theme,
1452 ) {
1453 self.build_themed(theme)
1454 }
1455
1456 /// **Builds what this node stands for**, before anything else is asked of it.
1457 ///
1458 /// A [`Component`](crate::Component) is a widget that is built into another, and what it
1459 /// is built into decides everything the walk asks next — its theme scope, its surface,
1460 /// its children. So the walks call this first, on the way down, before those questions
1461 /// and before [`Self::build_in`]; by the time they are asked, the node answers as what it
1462 /// built. Called under the theme of the enclosing scope, since the scope a node introduces
1463 /// is not known until it is built.
1464 ///
1465 /// Idempotent, and the default does nothing. A **transparent** wrapper must forward it
1466 /// with the identity untouched, for the same reason as `build_in`.
1467 fn expand(
1468 &self,
1469 _id: crate::interaction::WidgetId,
1470 _runtime: &crate::runtime::Runtime,
1471 _theme: &Theme,
1472 ) {
1473 }
1474
1475 /// Whether this node is an [`AnimatedSwitcher`](crate::AnimatedSwitcher). An identity
1476 /// is a position, so a switcher and the widget that comes to stand where it stood have
1477 /// the same one: this is how the runtime tells the switcher still being there from its
1478 /// having gone, and forgets what it kept for it.
1479 fn switches(&self) -> bool {
1480 false
1481 }
1482
1483 /// What the system bars over this widget should look like — see
1484 /// [`AnnotatedRegion`](crate::AnnotatedRegion). `None` for every widget but that one; a
1485 /// transparent wrapper forwards it, or a keyed region would say nothing.
1486 fn system_ui_style(&self) -> Option<crate::SystemUiOverlayStyle> {
1487 None
1488 }
1489
1490 /// If the widget takes **ink** — the splash a tap leaves on a material surface —
1491 /// the shape and colour to splash in. `None` = no ink, which is the default: a
1492 /// widget has to ask.
1493 ///
1494 /// The walk paints the ripples the runtime holds for this widget directly over
1495 /// this widget's own `paint` and **under its children**, which is where a material
1496 /// surface puts them. A widget that draws its own content (a [`crate::Button`]
1497 /// paints its label itself) therefore gets the ink *over* that content — at the
1498 /// splash's alpha, a tint rather than a veil. See [`crate::InkWell`].
1499 fn ink(&self, _theme: &Theme) -> Option<crate::ink::InkStyle> {
1500 None
1501 }
1502
1503 /// A decoration painted **over this widget's children** rather than behind them:
1504 /// the reference's `foregroundDecoration`.
1505 ///
1506 /// It is the one place in the walk where a widget paints after its own subtree,
1507 /// and it exists because there is no other way to say it. A border over a
1508 /// photograph, a wash across a tile that is disabled, a sheen over a card — every
1509 /// one of them is a decoration whose whole point is that the content does not
1510 /// cover it, and behind the content is exactly where [`Widget::paint`] puts one.
1511 ///
1512 /// The box is this widget's own, the same one `paint` is given. Inside any layer
1513 /// this widget asks for: an opacity group fades it with everything else, a
1514 /// transform carries it, and a shape clip holds it to the shape — which for a
1515 /// decoration wearing that same radius changes nothing.
1516 ///
1517 /// `None` is the default, and costs the walk one `Option` check per node.
1518 fn foreground(&self, _theme: &Theme) -> Option<frus_core::BoxDecoration> {
1519 None
1520 }
1521
1522 /// Whether this widget paints **over its own children** too, with
1523 /// [`paint_over`](Self::paint_over) (milestone 652). `false` by default, which spares
1524 /// the walk the status it would compute for it.
1525 fn paints_over(&self) -> bool {
1526 false
1527 }
1528
1529 /// Paints **over this widget's children**, after its subtree, in the box and with the
1530 /// status [`Widget::paint`] is given — the reference's `foregroundPainter`, for what a
1531 /// widget draws that its children must not cover. A range slider's thumbs are one:
1532 /// each thumb's focus stop is a child, and the halo it paints belongs under the thumb.
1533 ///
1534 /// Called only when [`paints_over`](Self::paints_over) says so.
1535 fn paint_over(&self, _bounds: Rect, _status: Status, _theme: &Theme, _scene: &mut Scene) {}
1536
1537 /// The **pixel effects** this widget applies to its whole subtree: a blur, a
1538 /// colour transform, a mask, or a filter over what is painted underneath. The
1539 /// paint walk drains the subtree into a composited layer and hands the filter to
1540 /// the renderer, exactly as it does for an opacity group or a shape clip.
1541 ///
1542 /// The [`FilterContext`] carries what only the walk knows — where the box ended
1543 /// up, and which backdrop group encloses it. A widget that needs neither ignores
1544 /// it.
1545 ///
1546 /// `None` — the default — means no layer and no cost. See [`crate::ColorFiltered`],
1547 /// [`crate::ImageFiltered`], [`crate::ShaderMask`], [`crate::BackdropFilter`].
1548 fn layer_filter(&self, _cx: FilterContext) -> Option<frus_core::LayerFilter> {
1549 None
1550 }
1551
1552 /// `true` when this widget is a **backdrop group**: the backdrops below it that
1553 /// ask to be shared are filtered once between them. See [`crate::BackdropGroup`].
1554 fn backdrop_group(&self) -> bool {
1555 false
1556 }
1557
1558 /// The widget's own **text baseline**: the distance from the top of its box down
1559 /// to the line its letters sit on. `None` — the default — means this widget has no
1560 /// text of its own, and whatever is inside it answers instead.
1561 ///
1562 /// It is what makes a price and its currency, or a heading and the note beside it,
1563 /// sit on one line rather than merely in one row. See [`crate::Baseline`] and
1564 /// `Align::Baseline`.
1565 fn text_baseline(&self, _theme: &Theme) -> Option<f32> {
1566 None
1567 }
1568
1569 /// `true` when this subtree should be **left out** of a parent's baseline
1570 /// alignment: it has a baseline, and the parent is to pretend it does not. An icon
1571 /// beside a label, where the label is what the row should line up on. See
1572 /// [`crate::IgnoreBaseline`].
1573 fn ignores_baseline(&self) -> bool {
1574 false
1575 }
1576
1577 /// The **axes this widget asks to fill**: on each, it takes the room the parent
1578 /// leaves it rather than shrink-wrapping its children. [`FillAxes::NONE`] means
1579 /// shrink-wrap on both.
1580 ///
1581 /// `MainAxisSize::Max` on a [`crate::Row`] or a [`crate::Column`] is the reason it
1582 /// exists, and there the axis is the widget's own main one; a [`crate::TabBar`] asks
1583 /// for the horizontal one, which is its cross axis; a full-screen shell asks for
1584 /// [`FillAxes::BOTH`].
1585 ///
1586 /// It is a question about the *parent*, which is why it is asked rather than written
1587 /// into the style: filling means growing when the parent runs the same way and
1588 /// stretching when it runs across, and a widget cannot know what it was put inside.
1589 /// The layout walk resolves it, where both are in view. **Declaring `width: 100%`
1590 /// instead does not work** and cannot be made to — see [`FillAxes`].
1591 ///
1592 /// The theme is here for the same reason it is on [`Widget::measure`]: a text asks to
1593 /// fill because it was told to align inside its box, and a subtree can hand that
1594 /// alignment down. A hook blind to the theme would leave the one setting that arrives
1595 /// by inheritance silently doing nothing.
1596 fn fill_axes(&self, _theme: &Theme) -> FillAxes {
1597 FillAxes::NONE
1598 }
1599
1600 /// The axes on which this widget's size is **only a default** (milestone 590): the
1601 /// room on offer replaces it wherever the widget is asked to fill that axis and the
1602 /// layout can grant it — alone in a box, or across a row or a column. Where it cannot,
1603 /// along a line shared with other children, the default stands.
1604 ///
1605 /// The reference gives a list, a page view or a field **all the room offered**, and has
1606 /// nothing to give when that room is unbounded: it stops with an error. A default that
1607 /// stands only there keeps the reference's size wherever it has one, and something on
1608 /// the screen where it has none.
1609 fn soft_extent(&self) -> FillAxes {
1610 FillAxes::NONE
1611 }
1612
1613 /// The width below which this widget must not be squeezed **when its parent runs
1614 /// horizontally** — a line of text that would rather run past the end of a row than
1615 /// be folded into a column of single words. `None` means squeeze freely.
1616 ///
1617 /// It is asked rather than written into the style because the same number means two
1618 /// different things on the two axes. Down a column a box is *handed* a width and a
1619 /// floor would refuse it; along a row a box is *asked* how wide it wants to be, and
1620 /// this is the answer it will not go below. The reference draws the same line: a flex
1621 /// leaves its inflexible children an unbounded main axis and never squeezes them,
1622 /// while across it they take the width they are given.
1623 ///
1624 /// It is handed the theme for the same reason [`Widget::style_themed`] is: the floor
1625 /// is a *measurement*, and a text whose size comes from an inherited style measures
1626 /// differently. A hook that decided a size without seeing the theme would answer for
1627 /// a font nobody is drawing.
1628 fn main_axis_floor(&self, _theme: &Theme) -> Option<f32> {
1629 None
1630 }
1631
1632 /// If this container gives all of its children the **shape of a tile**, the
1633 /// `width / height` ratio to impose on each of them. `None` = each child keeps
1634 /// its own shape.
1635 ///
1636 /// A grid's tiles are the same shape in the reference, and it is the grid that
1637 /// says so — the tile does not know how wide its column came out. Imposed during
1638 /// the walk, like the fill request and the shrink grant, because it needs the
1639 /// children's layout nodes rather than their styles.
1640 fn tile_shape(&self) -> Option<f32> {
1641 None
1642 }
1643
1644 /// If this is a layer **pinned** against its [`crate::Stack`]'s edges
1645 /// ([`crate::Positioned`]), what it pins. `None` = an ordinary layer, sized and
1646 /// placed by the stack's own fit and alignment.
1647 ///
1648 /// Read by the stack rather than written into a style: an offset from an edge is not
1649 /// something the layout engine's box model has a field for, and the number it
1650 /// resolves to depends on how big the stack came out.
1651 fn positioned(&self) -> Option<crate::positioned::Positioning> {
1652 None
1653 }
1654
1655 /// How this stack sizes its unpinned layers ([`crate::StackFit`]). Unset,
1656 /// [`Passthrough`](crate::StackFit::Passthrough): each is handed the stack's box, and
1657 /// one with a size of its own keeps it. Meaningless unless [`Widget::stack`] is true.
1658 fn stack_fit(&self) -> crate::StackFit {
1659 crate::StackFit::Passthrough
1660 }
1661
1662 /// Whether this stack is **as big as its largest unpinned layer** (milestone 639), as
1663 /// [`crate::Stack`] is, rather than the size its own style says. Meaningless unless
1664 /// [`Widget::stack`] is true.
1665 fn stack_measured(&self) -> bool {
1666 false
1667 }
1668
1669 /// Whether this stack cuts its layers at its edges. Unset, it does.
1670 fn stack_clips(&self) -> bool {
1671 true
1672 }
1673
1674 /// The reading direction this stack resolves its alignment and its layers' start and
1675 /// end pins in, when it names one. Unset, the theme's.
1676 fn stack_direction(&self) -> Option<frus_core::TextDirection> {
1677 None
1678 }
1679
1680 /// Which layer of this stack is **shown**: the one at that index paints and takes
1681 /// input, and every other one is laid out and then silenced — not drawn, not
1682 /// clickable, not read out. `None`, the default, shows all of them.
1683 ///
1684 /// This is [`crate::IndexedStack`], and it is a question for the walk rather than for
1685 /// the widget: a layer that wrapped itself in something to stay quiet would no longer
1686 /// be laid out the way a bare layer is, which is the one thing an indexed stack
1687 /// promises. Meaningless unless [`Widget::stack`] is true.
1688 fn stack_visible(&self) -> Option<usize> {
1689 None
1690 }
1691
1692 /// The box this widget asks the scroll region around it to **keep in view**, in its
1693 /// own coordinates, with a key naming which box it is.
1694 ///
1695 /// A tab bar wider than its window is what this is for: the eighth tab is off the
1696 /// side, and nothing about selecting it would otherwise bring it back. The reference
1697 /// scrolls its bar to the selected tab, and so does this.
1698 ///
1699 /// The **key** is what makes the region act on a change rather than on every frame.
1700 /// The box moves as the region scrolls, so a region that chased it would pin the
1701 /// content in place and no finger could move it; the key changes only when the widget
1702 /// means a different box.
1703 ///
1704 /// `centre` asks for the box in the middle of the window rather than merely inside
1705 /// it — what a tab bar wants, since a selected tab flush against the edge looks like
1706 /// the end of the row. Clamped either way, so the first tab stays at the start.
1707 fn keep_visible(&self, _size: Size, _theme: &Theme) -> Option<crate::ui::KeepVisible> {
1708 None
1709 }
1710
1711 /// Whether this scrollable runs **from the far end** ([`crate::SingleChildScrollView::reverse`]):
1712 /// the content is anchored to the end of the viewport and offsets are counted from
1713 /// there. Meaningless unless [`Widget::scroll_content`] is `Some`.
1714 fn scroll_reverse(&self) -> bool {
1715 false
1716 }
1717
1718 /// The insets a scrollable area puts **around its content**, inside the viewport.
1719 ///
1720 /// The padding scrolls with the content rather than shrinking the window onto it,
1721 /// which is the reference's `SliverPadding` and the only reading that is any use:
1722 /// room at the end of a list is reachable by scrolling to it, room taken out of the
1723 /// viewport is not. Read by both the scroll branch and the virtualised list.
1724 fn scroll_padding(&self) -> frus_core::Insets {
1725 frus_core::Insets::ZERO
1726 }
1727
1728 /// If the widget positions its child **by the child's baseline** ([`crate::Baseline`]),
1729 /// the distance from the top of this box at which that baseline should land.
1730 /// `None` = not a baseline box.
1731 fn baseline_target(&self) -> Option<f32> {
1732 None
1733 }
1734
1735 /// If the widget clips its child to an **arbitrary path** (`ClipPath`), returns the
1736 /// path in **local coordinates** (origin at the box's top-left corner). The walk
1737 /// offsets it to the screen and wraps it in a layer whose mask (the path) erases
1738 /// the outside. Takes priority over [`Widget::clip_shape`]. `None` = no path clip.
1739 /// See [`crate::ClipPath`].
1740 fn clip_path(&self) -> Option<&frus_core::Path> {
1741 None
1742 }
1743
1744 /// If the widget is a **dismissible item** ([`crate::Dismissible`]), its
1745 /// configuration for this frame. The shell gives a mostly-sideways drag on it to
1746 /// the dismissal and a mostly-up-and-down one to the enclosing scrollable. `None` =
1747 /// not dismissible.
1748 fn dismissible(&self) -> Option<crate::dismiss::DismissSpec> {
1749 None
1750 }
1751
1752 /// The message a dismissed item dispatches, once it has flown out **and** its gap
1753 /// has closed. `None` = the swipe is shown but removes nothing.
1754 fn on_dismissed(&self, _direction: crate::dismiss::DismissDirection) -> Option<Msg> {
1755 None
1756 }
1757
1758 /// If the widget is the moving panel of a [`crate::DraggableScrollableSheet`], its
1759 /// configuration for this frame. The layout makes it as tall as the retained height,
1760 /// and the shell shares a finger on it between the sheet and the scroll areas inside.
1761 /// `None` = not a sheet.
1762 fn sheet(&self) -> Option<&crate::sheet::SheetSpec> {
1763 None
1764 }
1765
1766 /// The message a sheet dispatches once it has been lowered to nothing. `None` = it
1767 /// cannot be dismissed, or says nothing when it is.
1768 fn on_sheet_dismissed(&self) -> Option<Msg> {
1769 None
1770 }
1771
1772 /// If the widget is a **refresh area** ([`crate::RefreshIndicator`]), its configuration for
1773 /// this frame. Any scrollable inside it routes the movement its physics refuses at
1774 /// the top edge into the pull, instead of into the overscroll glow. `None` = not a
1775 /// refresh area.
1776 fn refresh(&self) -> Option<crate::refresh::RefreshSpec> {
1777 None
1778 }
1779
1780 /// The message a refresh area dispatches when an armed pull is released. `None` =
1781 /// the pull is shown but asks for nothing, which is what an area still waiting for
1782 /// its `on_refresh` looks like.
1783 fn on_refresh(&self) -> Option<Msg> {
1784 None
1785 }
1786
1787 /// What the widget **withholds** from the frame on behalf of its whole subtree:
1788 /// input targets, primitives, accessibility nodes. The walk visits the subtree
1789 /// normally and then discards whatever it added to the selected registries, so a
1790 /// target registered deep inside is caught just as surely as one at the top.
1791 /// `None` = nothing withheld (the default). See [`crate::ModalBarrier`],
1792 /// [`crate::IgnorePointer`], [`crate::AbsorbPointer`], [`crate::Visibility`],
1793 /// [`crate::ExcludeSemantics`].
1794 fn barrier(&self) -> Option<crate::barrier::ModalBarrier> {
1795 None
1796 }
1797
1798 /// If the widget is an **interactive viewport** (`InteractiveViewer`), returns its
1799 /// scale bounds `(min, max)`. The paint walk renders its child in a transformed
1800 /// layer (retained scale + translation, clipped to the viewport); the shell routes
1801 /// drag → pan and wheel/pinch → zoom. `None` = not an interactive viewport.
1802 /// See [`crate::InteractiveViewer`].
1803 fn interactive(&self) -> Option<(f32, f32)> {
1804 None
1805 }
1806
1807 /// If the widget **fits** its child to its box (`FittedBox`), returns the
1808 /// [`frus_core::BoxFit`]: the walk measures the child at its natural size, scales
1809 /// it according to the fit and centres it (composited layer, hit-test through
1810 /// `M⁻¹`). `None` = not a fitter. See [`crate::FittedBox`].
1811 fn fitted(&self) -> Option<frus_core::BoxFit> {
1812 None
1813 }
1814
1815 /// If the widget **rotates** its child by quarter turns (`RotatedBox`), returns
1816 /// the number of quarters. Unlike `Transform`, this **affects layout**: the box
1817 /// swaps its dimensions for an odd number. `None` = not a `RotatedBox`.
1818 /// See [`crate::RotatedBox`].
1819 fn rotated_quarter_turns(&self) -> Option<i32> {
1820 None
1821 }
1822
1823 /// If the widget is a screen navigator, returns `(progress, push?)`. Its children
1824 /// (`[screen]` or `[outgoing, incoming]`) are rendered full-window with a sliding
1825 /// transition.
1826 fn navigator(&self) -> Option<(f32, bool)> {
1827 None
1828 }
1829
1830 /// Whether a finger drives the [`navigator`](Self::navigator)'s transition — a back
1831 /// gesture — so that it follows the finger linearly (milestone 620).
1832 fn navigator_gesture(&self) -> bool {
1833 false
1834 }
1835
1836 /// Whether a [`navigator`](Self::navigator) **clips its pages to its own box**.
1837 /// `true`, which is the reference's default (`Clip.hardEdge`) and the only sane one:
1838 /// a screen sliding in comes from outside the box and has to stop at its edge.
1839 ///
1840 /// Consulted only inside the navigator branch of the walk, so it costs nothing for
1841 /// every other widget.
1842 fn navigator_clips(&self) -> bool {
1843 true
1844 }
1845
1846 /// How many of a navigator's first children are **kept but not shown**: the pages under
1847 /// the one on show. They are built, so what their components hold survives, and they are
1848 /// not laid out, drawn or given input. `0`, the default, is a navigator that shows every
1849 /// page it holds.
1850 fn navigator_retained(&self) -> usize {
1851 0
1852 }
1853
1854 /// Message emitted by a **long press** (a press held ~500 ms without movement).
1855 /// The long press *pre-empts* the click: the release that follows does not emit
1856 /// `on_click`.
1857 fn on_long_press(&self) -> Option<Msg> {
1858 None
1859 }
1860
1861 /// Message emitted by a **double tap**: two taps on this widget in quick succession
1862 /// (within 300 ms and 100 px of each other, the reference's numbers). While one is
1863 /// possible, a first tap's [`on_click`](Self::on_click) waits out those 300 ms, so that
1864 /// the second tap of a double tap is not also a tap.
1865 fn on_double_tap(&self) -> Option<Msg> {
1866 None
1867 }
1868
1869 /// Message emitted by a **secondary tap**: a click of the secondary mouse button, usually
1870 /// the right one.
1871 fn on_secondary_tap(&self) -> Option<Msg> {
1872 None
1873 }
1874
1875 /// Whether this widget **hears the pointer's raw events** (milestone 586): a press inside
1876 /// it, and then that pointer wherever it goes until it lifts; and a mouse's hover.
1877 fn pointer_listener(&self) -> bool {
1878 false
1879 }
1880
1881 /// The messages for one raw event of the pointer, on a widget that is a
1882 /// [`pointer_listener`](Self::pointer_listener). Several, when listeners wrap each other at
1883 /// the same place.
1884 fn on_pointer_event(&self, _event: crate::ListenerEvent) -> Vec<Msg> {
1885 Vec::new()
1886 }
1887
1888 /// Whether this widget is a **region the mouse enters and leaves** (milestone 583), and
1889 /// how: the cursor it asks for while the pointer is over it, and whether it hides the
1890 /// regions behind it. `None` for anything that is not one.
1891 fn hover_region(&self) -> Option<crate::HoverRegion> {
1892 None
1893 }
1894
1895 /// Message for the pointer entering, moving over or leaving this region — one whose
1896 /// [`hover_region`](Self::hover_region) is set.
1897 fn on_hover_event(&self, _event: crate::HoverEvent) -> Option<Msg> {
1898 None
1899 }
1900
1901 /// Which way this widget takes a **drag**, if it takes one at all (milestone 582): the
1902 /// shell then reports it through [`on_pan`](Self::on_pan). Inside a scroll, a drag along
1903 /// the scroll's axis stays the scroll's unless this axis claims it.
1904 fn pan_axis(&self) -> Option<crate::PanAxis> {
1905 None
1906 }
1907
1908 /// Message for one moment of a drag — its start, a movement, its end — on a widget whose
1909 /// [`pan_axis`](Self::pan_axis) is set.
1910 fn on_pan(&self, _event: crate::PanEvent) -> Option<Msg> {
1911 None
1912 }
1913
1914 /// Whether this widget wants **the title bar's line** for itself (milestone 640): a
1915 /// [`WindowMenuBar`](crate::WindowMenuBar)'s row. The shell gives it the line where the
1916 /// system allows it.
1917 fn wants_title_bar(&self) -> bool {
1918 false
1919 }
1920
1921 /// What this widget is to the system on the title bar's line, which acts on it: the
1922 /// window's icon or its three buttons (milestone 640).
1923 fn title_bar_role(&self) -> Option<crate::TitleBarRole> {
1924 None
1925 }
1926
1927 /// A drag that moves **this widget's own animated value** ([`anim_target`]) — a
1928 /// switch's thumb following the finger (milestone 638). Given a moment of the drag, the
1929 /// value now and whether the text runs right to left, the value to hold it at; `None`
1930 /// leaves it alone. The shell holds the value there while the finger is down, and when
1931 /// it lifts lets it settle from there, asking [`on_value_release`] what that means.
1932 ///
1933 /// [`anim_target`]: Self::anim_target
1934 /// [`on_value_release`]: Self::on_value_release
1935 fn pan_value(&self, _event: crate::PanEvent, _value: f32, _rtl: bool) -> Option<f32> {
1936 None
1937 }
1938
1939 /// Message for a drag that moved this widget's value letting go at `value` — a switch
1940 /// flips when its thumb was let go past half way (milestone 638).
1941 fn on_value_release(&self, _value: f32) -> Option<Msg> {
1942 None
1943 }
1944
1945 /// Key received while **bubbling leaf→root**: the focused widget gets it first,
1946 /// then each ancestor as long as the response is `Ignored`. (E.g. an `OverlayPortal`
1947 /// consumes `Escape` to close itself.)
1948 fn on_key(&self, _key: &crate::interaction::Key) -> crate::interaction::KeyResponse<Msg> {
1949 crate::interaction::KeyResponse::Ignored
1950 }
1951
1952 /// **Measure under constraints**: for a widget whose size depends on the space
1953 /// offered (a paragraph that wraps…), returns the closure wired into taffy.
1954 /// `None` = size fixed by `style()`. Contract: must be `Some` **if and only if**
1955 /// [`Widget::measure_key`] is.
1956 ///
1957 /// The theme comes in because the measurement has to agree with the paint. A text
1958 /// that takes its size from an inherited style must be *measured* at that size too;
1959 /// measured at one size and drawn at another, every box on the screen is the wrong
1960 /// height at once, and nothing in the picture says which of the two numbers is wrong.
1961 fn measure(&self, _theme: &Theme) -> Option<frus_layout::MeasureFn<'_>> {
1962 None
1963 }
1964
1965 /// Fingerprint of the **content** [`Widget::measure`] depends on (text, style…),
1966 /// mixed into the relayout fingerprint: without it, two different contents with
1967 /// the same style would be conflated by the cache and would keep a stale
1968 /// geometry. Contract: `Some` if and only if `measure()` is.
1969 ///
1970 /// Whatever the theme contributes to the measurement belongs in here as well — a
1971 /// cache key that ignores half of its inputs is a stale layout waiting for the
1972 /// subtree's style to change.
1973 fn measure_key(&self, _theme: &Theme) -> Option<u64> {
1974 None
1975 }
1976}
1977
1978/// **Short** type name: without module path or generic parameters
1979/// (`frus_widgets::text::Text` → `Text`, `Container<Msg>` → `Container`).
1980pub(crate) fn short_type_name<T: ?Sized>() -> &'static str {
1981 let full = std::any::type_name::<T>();
1982 let no_generics = full.split('<').next().unwrap_or(full);
1983 no_generics.rsplit("::").next().unwrap_or(no_generics)
1984}
1985
1986/// Lets an **already boxed** widget be composed where an `impl Widget` is expected
1987/// (e.g. `Flex::child`). Delegates everything to the contained widget.
1988impl<Msg> Widget<Msg> for Box<dyn Widget<Msg>> {
1989 fn style(&self) -> Style {
1990 (**self).style()
1991 }
1992 fn style_themed(&self, theme: &Theme) -> Style {
1993 (**self).style_themed(theme)
1994 }
1995 fn theme_override(&self, inherited: &Theme) -> Option<Box<Theme>> {
1996 (**self).theme_override(inherited)
1997 }
1998 fn media_override(&self, inherited: crate::MediaQuery) -> Option<crate::MediaQuery> {
1999 (**self).media_override(inherited)
2000 }
2001 fn scaffold_override(&self) -> Option<crate::ScaffoldInfo> {
2002 (**self).scaffold_override()
2003 }
2004 fn scroll_behavior_override(&self) -> Option<crate::ScrollBehavior> {
2005 (**self).scroll_behavior_override()
2006 }
2007 fn build_themed(&self, theme: &Theme) {
2008 (**self).build_themed(theme)
2009 }
2010 fn build_in(
2011 &self,
2012 id: crate::interaction::WidgetId,
2013 runtime: &crate::runtime::Runtime,
2014 theme: &Theme,
2015 ) {
2016 (**self).build_in(id, runtime, theme)
2017 }
2018 fn expand(
2019 &self,
2020 id: crate::interaction::WidgetId,
2021 runtime: &crate::runtime::Runtime,
2022 theme: &Theme,
2023 ) {
2024 (**self).expand(id, runtime, theme)
2025 }
2026 fn switches(&self) -> bool {
2027 (**self).switches()
2028 }
2029 fn system_ui_style(&self) -> Option<crate::SystemUiOverlayStyle> {
2030 (**self).system_ui_style()
2031 }
2032 fn repaint_boundary(&self) -> bool {
2033 (**self).repaint_boundary()
2034 }
2035 fn debug_name(&self) -> &'static str {
2036 (**self).debug_name()
2037 }
2038 fn semantics(&self) -> Option<SemanticsProperties> {
2039 (**self).semantics()
2040 }
2041 fn describes(&self) -> Option<crate::semantics::Description> {
2042 (**self).describes()
2043 }
2044 fn children(&self) -> &[Box<dyn Widget<Msg>>] {
2045 (**self).children()
2046 }
2047 fn paint(&self, bounds: Rect, status: Status, theme: &Theme, scene: &mut Scene) {
2048 (**self).paint(bounds, status, theme, scene)
2049 }
2050 fn on_click(&self) -> Option<Msg> {
2051 (**self).on_click()
2052 }
2053 fn opaque(&self) -> bool {
2054 (**self).opaque()
2055 }
2056 fn positional_click(&self, local_x: f32, local_y: f32, width: f32, height: f32) -> Option<Msg> {
2057 (**self).positional_click(local_x, local_y, width, height)
2058 }
2059 fn cursor_icon(&self, local_x: f32, local_y: f32, width: f32, height: f32) -> Option<Cursor> {
2060 (**self).cursor_icon(local_x, local_y, width, height)
2061 }
2062 fn key(&self) -> Option<u64> {
2063 (**self).key()
2064 }
2065 fn on_edit(&self, edit: &mut Edit, key: &Key) -> Option<Msg> {
2066 (**self).on_edit(edit, key)
2067 }
2068 fn cursor_at(
2069 &self,
2070 local_x: f32,
2071 local_y: f32,
2072 width: f32,
2073 scroll_cursor: usize,
2074 ) -> Option<usize> {
2075 (**self).cursor_at(local_x, local_y, width, scroll_cursor)
2076 }
2077 fn text_metrics(&self, width: f32, cursor: usize) -> Option<(f32, f32, f32, f32)> {
2078 (**self).text_metrics(width, cursor)
2079 }
2080 fn text_viewport(&self, rect: crate::Rect) -> Option<crate::Rect> {
2081 (**self).text_viewport(rect)
2082 }
2083 fn caret_vertical(
2084 &self,
2085 width: f32,
2086 cursor: usize,
2087 down: bool,
2088 page: bool,
2089 goal_x: Option<f32>,
2090 ) -> Option<(usize, f32)> {
2091 (**self).caret_vertical(width, cursor, down, page, goal_x)
2092 }
2093 fn selected_text(&self, edit: &Edit) -> Option<String> {
2094 (**self).selected_text(edit)
2095 }
2096 fn text_value(&self) -> Option<&str> {
2097 (**self).text_value()
2098 }
2099 fn takes_typing(&self) -> bool {
2100 (**self).takes_typing()
2101 }
2102 fn selection_text(&self) -> Option<&str> {
2103 (**self).selection_text()
2104 }
2105 fn region_toolbar(
2106 &self,
2107 context: crate::ToolbarContext,
2108 width: f32,
2109 range: (usize, usize),
2110 ) -> Option<(Rect, &dyn Widget<Msg>)> {
2111 (**self).region_toolbar(context, width, range)
2112 }
2113 fn selection_grip(
2114 &self,
2115 width: f32,
2116 index: usize,
2117 start: bool,
2118 ) -> Option<crate::SelectionHandle> {
2119 (**self).selection_grip(width, index, start)
2120 }
2121 fn area_toolbar(&self, context: crate::ToolbarContext) -> Option<Option<&dyn Widget<Msg>>> {
2122 (**self).area_toolbar(context)
2123 }
2124 fn selection_hit(&self, local_x: f32, local_y: f32, width: f32) -> Option<usize> {
2125 (**self).selection_hit(local_x, local_y, width)
2126 }
2127 fn replace_value(&self, value: String) -> Option<Msg> {
2128 (**self).replace_value(value)
2129 }
2130 fn word_at(&self, index: usize) -> Option<(usize, usize)> {
2131 (**self).word_at(index)
2132 }
2133 fn selection_handles(
2134 &self,
2135 width: f32,
2136 edit: &Edit,
2137 scroll_y: f32,
2138 ) -> Option<[crate::SelectionHandle; 2]> {
2139 (**self).selection_handles(width, edit, scroll_y)
2140 }
2141 fn selection_toolbar(&self, context: crate::ToolbarContext) -> Option<&dyn Widget<Msg>> {
2142 (**self).selection_toolbar(context)
2143 }
2144 fn selection_anchor(&self, width: f32, edit: &Edit, scroll_y: f32) -> Option<Rect> {
2145 (**self).selection_anchor(width, edit, scroll_y)
2146 }
2147 fn edit_action(&self) -> Option<crate::EditAction> {
2148 (**self).edit_action()
2149 }
2150 fn focusable(&self) -> bool {
2151 (**self).focusable()
2152 }
2153 fn autofocus(&self) -> bool {
2154 (**self).autofocus()
2155 }
2156 fn on_focus_change(&self, focused: bool) -> Option<Msg> {
2157 (**self).on_focus_change(focused)
2158 }
2159 fn on_tap_outside(&self) -> Option<Msg> {
2160 (**self).on_tap_outside()
2161 }
2162
2163 fn shortcut_bindings(&self) -> &[(crate::shortcuts::KeyStroke, crate::shortcuts::Intent)] {
2164 (**self).shortcut_bindings()
2165 }
2166
2167 fn shortcut_callbacks(&self) -> &[(crate::shortcuts::KeyStroke, Msg)] {
2168 (**self).shortcut_callbacks()
2169 }
2170
2171 fn action_bindings(&self) -> &[(crate::shortcuts::Intent, Msg)] {
2172 (**self).action_bindings()
2173 }
2174
2175 fn action_listeners(&self) -> &[(crate::shortcuts::Intent, Msg)] {
2176 (**self).action_listeners()
2177 }
2178
2179 fn on_keystroke(
2180 &self,
2181 ) -> Option<std::rc::Rc<dyn Fn(crate::shortcuts::KeyStroke) -> Option<Msg>>> {
2182 (**self).on_keystroke()
2183 }
2184
2185 fn descendants_focusable(&self) -> bool {
2186 (**self).descendants_focusable()
2187 }
2188
2189 fn focus_skip_traversal(&self) -> bool {
2190 (**self).focus_skip_traversal()
2191 }
2192
2193 fn focus_order(&self) -> Option<f32> {
2194 (**self).focus_order()
2195 }
2196
2197 fn focus_group(&self) -> bool {
2198 (**self).focus_group()
2199 }
2200 fn autofill_hints(&self) -> &[crate::AutofillHint] {
2201 (**self).autofill_hints()
2202 }
2203 fn autofill_group(&self) -> bool {
2204 (**self).autofill_group()
2205 }
2206 fn draws_own_focus(&self) -> bool {
2207 (**self).draws_own_focus()
2208 }
2209 fn draggable(&self) -> bool {
2210 (**self).draggable()
2211 }
2212 fn drag_track(&self) -> DragTrack {
2213 (**self).drag_track()
2214 }
2215 fn on_thumb_drag(&self, thumb: usize, moment: ThumbDrag, fraction: f32) -> Option<Msg> {
2216 (**self).on_thumb_drag(thumb, moment, fraction)
2217 }
2218 fn on_drag(&self, fraction: f32) -> Option<Msg> {
2219 (**self).on_drag(fraction)
2220 }
2221 fn on_drag_start(&self, fraction: f32) -> Option<Msg> {
2222 (**self).on_drag_start(fraction)
2223 }
2224 fn on_drag_end(&self, fraction: f32) -> Option<Msg> {
2225 (**self).on_drag_end(fraction)
2226 }
2227 fn on_drag_delta(&self, dx: f32) -> Option<Msg> {
2228 (**self).on_drag_delta(dx)
2229 }
2230 fn reorder_index(&self) -> Option<usize> {
2231 (**self).reorder_index()
2232 }
2233 fn on_reorder(&self, to: usize) -> Option<Msg> {
2234 (**self).on_reorder(to)
2235 }
2236 fn reorder_draggable(&self) -> bool {
2237 (**self).reorder_draggable()
2238 }
2239 fn reorder_droppable(&self) -> bool {
2240 (**self).reorder_droppable()
2241 }
2242 fn reorder_announcement(&self, to: usize) -> Option<String> {
2243 (**self).reorder_announcement(to)
2244 }
2245 fn reorder_axis(&self) -> ReorderAxis {
2246 (**self).reorder_axis()
2247 }
2248 fn reorder_inserts(&self) -> bool {
2249 (**self).reorder_inserts()
2250 }
2251 fn announce(&self) -> Option<String> {
2252 (**self).announce()
2253 }
2254 fn stack(&self) -> bool {
2255 (**self).stack()
2256 }
2257 fn sticky_header(&self) -> bool {
2258 (**self).sticky_header()
2259 }
2260
2261 fn custom_layout(&self) -> Option<crate::customlayout::CustomLayout<'_>> {
2262 (**self).custom_layout()
2263 }
2264 fn continuous(&self) -> bool {
2265 (**self).continuous()
2266 }
2267 fn scroll_content(&self) -> Option<&dyn Widget<Msg>> {
2268 (**self).scroll_content()
2269 }
2270 fn virtual_list(&self, viewport: frus_core::Size) -> Option<crate::list::VirtualList<'_, Msg>> {
2271 (**self).virtual_list(viewport)
2272 }
2273 fn page_view(&self) -> Option<crate::pageview::PagedView<'_, Msg>> {
2274 (**self).page_view()
2275 }
2276 fn intrinsic(&self) -> Option<(crate::constraints::IntrinsicAxis, Option<f32>)> {
2277 (**self).intrinsic()
2278 }
2279 fn overflow_box(&self) -> Option<crate::constraints::Overflow> {
2280 (**self).overflow_box()
2281 }
2282 fn constraints_transform(&self) -> Option<crate::constraints::ConstraintsTransform> {
2283 (**self).constraints_transform()
2284 }
2285 fn animated_size(&self) -> Option<crate::animatedsize::SizeAnimation> {
2286 (**self).animated_size()
2287 }
2288 fn size_factor(&self) -> Option<(f32, f32)> {
2289 (**self).size_factor()
2290 }
2291 fn clips_to_box(&self) -> bool {
2292 (**self).clips_to_box()
2293 }
2294 fn hero_tag(&self) -> Option<u64> {
2295 (**self).hero_tag()
2296 }
2297 fn drag_payload(&self) -> Option<u64> {
2298 (**self).drag_payload()
2299 }
2300 fn drag_needs_long_press(&self) -> bool {
2301 (**self).drag_needs_long_press()
2302 }
2303 fn drag_ghost_opacity(&self) -> f32 {
2304 (**self).drag_ghost_opacity()
2305 }
2306 fn on_dropped(&self, accepted: bool) -> Option<Msg> {
2307 (**self).on_dropped(accepted)
2308 }
2309 fn drop_zone(&self) -> bool {
2310 (**self).drop_zone()
2311 }
2312 fn accepts_drag(&self, payload: u64) -> bool {
2313 (**self).accepts_drag(payload)
2314 }
2315 fn on_drop(&self, payload: u64) -> Option<Msg> {
2316 (**self).on_drop(payload)
2317 }
2318 fn accepts_files(&self, paths: &[std::path::PathBuf]) -> bool {
2319 (**self).accepts_files(paths)
2320 }
2321 fn on_files_dropped(&self, paths: Vec<std::path::PathBuf>) -> Option<Msg> {
2322 (**self).on_files_dropped(paths)
2323 }
2324 fn on_page_changed(&self, page: usize) -> Option<Msg> {
2325 (**self).on_page_changed(page)
2326 }
2327 fn on_scroll(&self, position: crate::scrollposition::ScrollPosition) -> Option<Msg> {
2328 (**self).on_scroll(position)
2329 }
2330 fn scroll_grain(&self) -> f32 {
2331 (**self).scroll_grain()
2332 }
2333 fn layout_builder(&self) -> Option<&dyn Fn(Size) -> Box<dyn Widget<Msg>>> {
2334 (**self).layout_builder()
2335 }
2336 fn scroll_overlay(&self) -> Option<&crate::scrolloverlay::OverlayBuilder<Msg>> {
2337 (**self).scroll_overlay()
2338 }
2339 fn scroll_axis(&self) -> Axis {
2340 (**self).scroll_axis()
2341 }
2342 fn scroll_physics(&self) -> Option<crate::physics::ScrollPhysics> {
2343 (**self).scroll_physics()
2344 }
2345 fn scrollbars(&self) -> Option<crate::physics::Scrollbars> {
2346 (**self).scrollbars()
2347 }
2348 fn thumb_visibility(&self) -> Option<bool> {
2349 (**self).thumb_visibility()
2350 }
2351 fn ime(&self) -> crate::ime::Ime {
2352 (**self).ime()
2353 }
2354 fn overlay(&self) -> Option<(&dyn Widget<Msg>, Placement)> {
2355 (**self).overlay()
2356 }
2357 fn overlay_dismiss(&self) -> Option<Msg> {
2358 (**self).overlay_dismiss()
2359 }
2360 fn overlay_scrim(&self, theme: &crate::theme::Theme) -> Option<frus_core::Color> {
2361 (**self).overlay_scrim(theme)
2362 }
2363 fn overlay_traps_focus(&self) -> bool {
2364 (**self).overlay_traps_focus()
2365 }
2366 fn anim_target(&self) -> Option<f32> {
2367 (**self).anim_target()
2368 }
2369 fn anim_transform(&self) -> Option<crate::runtime::TransformValues> {
2370 (**self).anim_transform()
2371 }
2372 fn anim_duration(&self) -> f32 {
2373 (**self).anim_duration()
2374 }
2375 fn anim_initial(&self) -> Option<f32> {
2376 (**self).anim_initial()
2377 }
2378 fn anim_curve(&self) -> frus_core::Curve {
2379 (**self).anim_curve()
2380 }
2381 fn opacity_group(&self) -> Option<f32> {
2382 (**self).opacity_group()
2383 }
2384 fn anim_color(&self) -> Option<frus_core::Color> {
2385 (**self).anim_color()
2386 }
2387 fn anim_size(&self) -> Option<Size> {
2388 (**self).anim_size()
2389 }
2390 fn anim_radius(&self) -> Option<frus_core::BorderRadius> {
2391 (**self).anim_radius()
2392 }
2393 fn anim_padding(&self) -> Option<frus_core::Insets> {
2394 (**self).anim_padding()
2395 }
2396 fn anim_offset(&self) -> Option<(f32, f32)> {
2397 (**self).anim_offset()
2398 }
2399 fn anim_pins(&self) -> Option<crate::positioned::Positioning> {
2400 (**self).anim_pins()
2401 }
2402 fn anim_fractions(&self) -> Option<(Option<f32>, Option<f32>)> {
2403 (**self).anim_fractions()
2404 }
2405 fn anim_text_style(&self) -> Option<frus_core::TextStyle> {
2406 (**self).anim_text_style()
2407 }
2408 fn alignment_geometry(&self) -> Option<frus_core::AlignmentGeometry> {
2409 (**self).alignment_geometry()
2410 }
2411 fn transform_translate(&self) -> Option<(f32, f32)> {
2412 (**self).transform_translate()
2413 }
2414 fn translate_fraction(&self) -> Option<(f32, f32)> {
2415 (**self).translate_fraction()
2416 }
2417 fn transform_scale(&self) -> Option<(f32, f32, frus_core::Alignment)> {
2418 (**self).transform_scale()
2419 }
2420 fn transform_rotate(&self) -> Option<(f32, frus_core::Alignment)> {
2421 (**self).transform_rotate()
2422 }
2423 fn clip_shape(&self) -> Option<frus_core::ClipShape> {
2424 (**self).clip_shape()
2425 }
2426 fn clip_path(&self) -> Option<&frus_core::Path> {
2427 (**self).clip_path()
2428 }
2429 fn layer_filter(&self, cx: FilterContext) -> Option<frus_core::LayerFilter> {
2430 (**self).layer_filter(cx)
2431 }
2432 fn text_baseline(&self, theme: &Theme) -> Option<f32> {
2433 (**self).text_baseline(theme)
2434 }
2435 fn ignores_baseline(&self) -> bool {
2436 (**self).ignores_baseline()
2437 }
2438 fn baseline_target(&self) -> Option<f32> {
2439 (**self).baseline_target()
2440 }
2441 fn fill_axes(&self, theme: &Theme) -> FillAxes {
2442 (**self).fill_axes(theme)
2443 }
2444 fn soft_extent(&self) -> FillAxes {
2445 (**self).soft_extent()
2446 }
2447 fn main_axis_floor(&self, theme: &Theme) -> Option<f32> {
2448 (**self).main_axis_floor(theme)
2449 }
2450 fn tile_shape(&self) -> Option<f32> {
2451 (**self).tile_shape()
2452 }
2453 fn positioned(&self) -> Option<crate::positioned::Positioning> {
2454 (**self).positioned()
2455 }
2456 fn stack_fit(&self) -> crate::StackFit {
2457 (**self).stack_fit()
2458 }
2459 fn stack_measured(&self) -> bool {
2460 (**self).stack_measured()
2461 }
2462 fn stack_clips(&self) -> bool {
2463 (**self).stack_clips()
2464 }
2465 fn stack_direction(&self) -> Option<frus_core::TextDirection> {
2466 (**self).stack_direction()
2467 }
2468 fn stack_visible(&self) -> Option<usize> {
2469 (**self).stack_visible()
2470 }
2471 fn scroll_reverse(&self) -> bool {
2472 (**self).scroll_reverse()
2473 }
2474
2475 fn keep_visible(&self, size: Size, theme: &Theme) -> Option<crate::ui::KeepVisible> {
2476 (**self).keep_visible(size, theme)
2477 }
2478 fn scroll_padding(&self) -> frus_core::Insets {
2479 (**self).scroll_padding()
2480 }
2481 fn backdrop_group(&self) -> bool {
2482 (**self).backdrop_group()
2483 }
2484 fn ink(&self, theme: &Theme) -> Option<crate::ink::InkStyle> {
2485 (**self).ink(theme)
2486 }
2487 fn foreground(&self, theme: &Theme) -> Option<frus_core::BoxDecoration> {
2488 (**self).foreground(theme)
2489 }
2490 fn paints_over(&self) -> bool {
2491 (**self).paints_over()
2492 }
2493 fn paint_over(&self, bounds: Rect, status: Status, theme: &Theme, scene: &mut Scene) {
2494 (**self).paint_over(bounds, status, theme, scene)
2495 }
2496 fn barrier(&self) -> Option<crate::barrier::ModalBarrier> {
2497 (**self).barrier()
2498 }
2499 fn dismissible(&self) -> Option<crate::dismiss::DismissSpec> {
2500 (**self).dismissible()
2501 }
2502 fn on_dismissed(&self, direction: crate::dismiss::DismissDirection) -> Option<Msg> {
2503 (**self).on_dismissed(direction)
2504 }
2505 fn sheet(&self) -> Option<&crate::sheet::SheetSpec> {
2506 (**self).sheet()
2507 }
2508 fn on_sheet_dismissed(&self) -> Option<Msg> {
2509 (**self).on_sheet_dismissed()
2510 }
2511 fn refresh(&self) -> Option<crate::refresh::RefreshSpec> {
2512 (**self).refresh()
2513 }
2514 fn on_refresh(&self) -> Option<Msg> {
2515 (**self).on_refresh()
2516 }
2517 fn interactive(&self) -> Option<(f32, f32)> {
2518 (**self).interactive()
2519 }
2520 fn fitted(&self) -> Option<frus_core::BoxFit> {
2521 (**self).fitted()
2522 }
2523 fn rotated_quarter_turns(&self) -> Option<i32> {
2524 (**self).rotated_quarter_turns()
2525 }
2526 fn navigator(&self) -> Option<(f32, bool)> {
2527 (**self).navigator()
2528 }
2529 fn navigator_gesture(&self) -> bool {
2530 (**self).navigator_gesture()
2531 }
2532 fn navigator_clips(&self) -> bool {
2533 (**self).navigator_clips()
2534 }
2535 fn navigator_retained(&self) -> usize {
2536 (**self).navigator_retained()
2537 }
2538 fn measure(&self, theme: &Theme) -> Option<frus_layout::MeasureFn<'_>> {
2539 (**self).measure(theme)
2540 }
2541 fn measure_key(&self, theme: &Theme) -> Option<u64> {
2542 (**self).measure_key(theme)
2543 }
2544 fn on_long_press(&self) -> Option<Msg> {
2545 (**self).on_long_press()
2546 }
2547 fn on_double_tap(&self) -> Option<Msg> {
2548 (**self).on_double_tap()
2549 }
2550 fn on_secondary_tap(&self) -> Option<Msg> {
2551 (**self).on_secondary_tap()
2552 }
2553 fn pan_axis(&self) -> Option<crate::PanAxis> {
2554 (**self).pan_axis()
2555 }
2556 fn hover_region(&self) -> Option<crate::HoverRegion> {
2557 (**self).hover_region()
2558 }
2559 fn pointer_listener(&self) -> bool {
2560 (**self).pointer_listener()
2561 }
2562 fn on_pointer_event(&self, event: crate::ListenerEvent) -> Vec<Msg> {
2563 (**self).on_pointer_event(event)
2564 }
2565 fn on_hover_event(&self, event: crate::HoverEvent) -> Option<Msg> {
2566 (**self).on_hover_event(event)
2567 }
2568 fn on_pan(&self, event: crate::PanEvent) -> Option<Msg> {
2569 (**self).on_pan(event)
2570 }
2571 fn wants_title_bar(&self) -> bool {
2572 (**self).wants_title_bar()
2573 }
2574 fn title_bar_role(&self) -> Option<crate::TitleBarRole> {
2575 (**self).title_bar_role()
2576 }
2577 fn pan_value(&self, event: crate::PanEvent, value: f32, rtl: bool) -> Option<f32> {
2578 (**self).pan_value(event, value, rtl)
2579 }
2580 fn on_value_release(&self, value: f32) -> Option<Msg> {
2581 (**self).on_value_release(value)
2582 }
2583 fn on_key(&self, key: &crate::interaction::Key) -> crate::interaction::KeyResponse<Msg> {
2584 (**self).on_key(key)
2585 }
2586}