Skip to main content

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