logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! Leverage pure, virtual widgets in your application.
//!
//! The widgets found in this module are completely stateless versions of
//! [the original widgets].
//!
//! Effectively, this means that, as a user of the library, you do not need to
//! keep track of the local state of each widget (e.g. [`button::State`]).
//! Instead, the runtime will keep track of everything for you!
//!
//! You can embed pure widgets anywhere in your [impure `Application`] using the
//! [`Pure`] widget and some [`State`].
//!
//! In case you want to only use pure widgets in your application, this module
//! offers an alternate [`Application`] trait with a completely pure `view`
//! method.
//!
//! # The Elm Architecture, purity, and continuity
//! As you may know, applications made with `iced` use [The Elm Architecture].
//!
//! In a nutshell, this architecture defines the initial state of the application, a way to `view` it, and a way to `update` it after a user interaction. The `update` logic is called after a meaningful user interaction, which in turn updates the state of the application. Then, the `view` logic is executed to redisplay the application.
//!
//! Since `view` logic is only run after an `update`, all of the mutations to the application state must only happen in the `update` logic. If the application state changes anywhere else, the `view` logic will not be rerun and, therefore, the previously generated `view` may stay outdated.
//!
//! However, the `Application` trait in `iced` defines `view` as:
//!
//! ```ignore
//! pub trait Application {
//!     fn view(&mut self) -> Element<Self::Message>;
//! }
//! ```
//!
//! As a consequence, the application state can be mutated in `view` logic. The `view` logic in `iced` is __impure__.
//!
//! This impurity is necessary because `iced` puts the burden of widget __continuity__ on its users. In other words, it's up to you to provide `iced` with the internal state of each widget every time `view` is called.
//!
//! If we take a look at the classic `counter` example:
//!
//! ```ignore
//! struct Counter {
//!     value: i32,
//!     increment_button: button::State,
//!     decrement_button: button::State,
//! }
//!
//! // ...
//!
//! impl Counter {
//!     pub fn view(&mut self) -> Column<Message> {
//!         Column::new()
//!             .push(
//!                 Button::new(&mut self.increment_button, Text::new("+"))
//!                     .on_press(Message::IncrementPressed),
//!             )
//!             .push(Text::new(self.value.to_string()).size(50))
//!             .push(
//!                 Button::new(&mut self.decrement_button, Text::new("-"))
//!                     .on_press(Message::DecrementPressed),
//!             )
//!     }
//! }
//! ```
//!
//! We can see how we need to keep track of the `button::State` of each `Button` in our `Counter` state and provide a mutable reference to the widgets in our `view` logic. The widgets produced by `view` are __stateful__.
//!
//! While this approach forces users to keep track of widget state and causes impurity, I originally chose it because it allows `iced` to directly consume the widget tree produced by `view`. Since there is no internal state decoupled from `view` maintained by the runtime, `iced` does not need to compare (e.g. reconciliate) widget trees in order to ensure continuity.
//!
//! # Stateless widgets
//! As the library matures, the need for some kind of persistent widget data (see #553) between `view` calls becomes more apparent (e.g. incremental rendering, animations, accessibility, etc.).
//!
//! If we are going to end up having persistent widget data anyways... There is no reason to have impure, stateful widgets anymore!
//!
//! With the help of this module, we can now write a pure `counter` example:
//!
//! ```ignore
//! struct Counter {
//!     value: i32,
//! }
//!
//! // ...
//!
//! impl Counter {
//!     fn view(&self) -> Column<Message> {
//!         Column::new()
//!             .push(Button::new("Increment").on_press(Message::IncrementPressed))
//!             .push(Text::new(self.value.to_string()).size(50))
//!             .push(Button::new("Decrement").on_press(Message::DecrementPressed))
//!     }
//! }
//! ```
//!
//! Notice how we no longer need to keep track of the `button::State`! The widgets in `iced_pure` do not take any mutable application state in `view`. They are __stateless__ widgets. As a consequence, we do not need mutable access to `self` in `view` anymore. `view` becomes __pure__.
//!
//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/
//!
//! [the original widgets]: crate::widget
//! [`button::State`]: crate::widget::button::State
//! [impure `Application`]: crate::Application
pub mod widget;

mod application;
mod sandbox;

pub use application::Application;
pub use sandbox::Sandbox;

pub use iced_pure::helpers::*;
pub use iced_pure::Widget;
pub use iced_pure::{Pure, State};

/// A generic, pure [`Widget`].
pub type Element<'a, Message> =
    iced_pure::Element<'a, Message, crate::Renderer>;