iced_widget/
keyed.rs

1//! Keyed widgets can provide hints to ensure continuity.
2//!
3//! # What is continuity?
4//! Continuity is the feeling of persistence of state.
5//!
6//! In a graphical user interface, users expect widgets to have a
7//! certain degree of continuous state. For instance, a text input
8//! that is focused should stay focused even if the widget tree
9//! changes slightly.
10//!
11//! Continuity is tricky in `iced` and the Elm Architecture because
12//! the whole widget tree is rebuilt during every `view` call. This is
13//! very convenient from a developer perspective because you can build
14//! extremely dynamic interfaces without worrying about changing state.
15//!
16//! However, the tradeoff is that determining what changed becomes hard
17//! for `iced`. If you have a list of things, adding an element at the
18//! top may cause a loss of continuity on every element on the list!
19//!
20//! # How can we keep continuity?
21//! The good news is that user interfaces generally have a static widget
22//! structure. This structure can be relied on to ensure some degree of
23//! continuity. `iced` already does this.
24//!
25//! However, sometimes you have a certain part of your interface that is
26//! quite dynamic. For instance, a list of things where items may be added
27//! or removed at any place.
28//!
29//! There are different ways to mitigate this during the reconciliation
30//! stage, but they involve comparing trees at certain depths and
31//! backtracking... Quite computationally expensive.
32//!
33//! One approach that is cheaper consists in letting the user provide some hints
34//! about the identities of the different widgets so that they can be compared
35//! directly without going deeper.
36//!
37//! The widgets in this module will all ask for a "hint" of some sort. In order
38//! to help them keep continuity, you need to make sure the hint stays the same
39//! for the same items in your user interface between `view` calls.
40pub mod column;
41
42pub use column::Column;
43
44/// Creates a keyed [`Column`] with the given children.
45///
46/// Keyed columns distribute content vertically while keeping continuity.
47///
48/// # Example
49/// ```no_run
50/// # mod iced { pub mod widget { pub use iced_widget::*; } }
51/// # pub type State = ();
52/// # pub type Element<'a, Message> = iced_widget::core::Element<'a, Message, iced_widget::Theme, iced_widget::Renderer>;
53/// use iced::widget::keyed_column;
54///
55/// enum Message {
56///     // ...
57/// }
58///
59/// fn view(state: &State) -> Element<'_, Message> {
60///     keyed_column![
61///         (0, "Item 0"),
62///         (1, "Item 1"),
63///         (2, "Item 2"),
64///     ].into()
65/// }
66/// ```
67#[macro_export]
68macro_rules! keyed_column {
69    () => (
70        $crate::keyed::Column::new()
71    );
72    ($(($key:expr, $x:expr)),+ $(,)?) => (
73        $crate::keyed::Column::with_children(vec![$(($key, $crate::core::Element::from($x))),+])
74    );
75}