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
113
114
115
116
117
118
119
120
121
122
123
|
use crate::pure;
use crate::{Command, Error, Settings, Subscription, Theme};
/// A pure version of [`Sandbox`].
///
/// Unlike the impure version, the `view` method of this trait takes an
/// immutable reference to `self` and returns a pure [`Element`].
///
/// [`Sandbox`]: crate::Sandbox
/// [`Element`]: pure::Element
pub trait Sandbox {
/// The type of __messages__ your [`Sandbox`] will produce.
type Message: std::fmt::Debug + Send;
/// Initializes the [`Sandbox`].
///
/// Here is where you should return the initial state of your app.
fn new() -> Self;
/// Returns the current title of the [`Sandbox`].
///
/// This title can be dynamic! The runtime will automatically update the
/// title of your application when necessary.
fn title(&self) -> String;
/// Handles a __message__ and updates the state of the [`Sandbox`].
///
/// This is where you define your __update logic__. All the __messages__,
/// produced by user interactions, will be handled by this method.
fn update(&mut self, message: Self::Message);
/// Returns the widgets to display in the [`Sandbox`].
///
/// These widgets can produce __messages__ based on user interaction.
fn view(&self) -> pure::Element<'_, Self::Message>;
/// Returns the current [`Theme`] of the [`Sandbox`].
///
/// If you want to use your own custom theme type, you will have to use an
/// [`Application`].
///
/// By default, it returns [`Theme::default`].
fn theme(&self) -> Theme {
Theme::default()
}
/// Returns the scale factor of the [`Sandbox`].
///
/// It can be used to dynamically control the size of the UI at runtime
/// (i.e. zooming).
///
/// For instance, a scale factor of `2.0` will make widgets twice as big,
/// while a scale factor of `0.5` will shrink them to half their size.
///
/// By default, it returns `1.0`.
fn scale_factor(&self) -> f64 {
1.0
}
/// Returns whether the [`Sandbox`] should be terminated.
///
/// By default, it returns `false`.
fn should_exit(&self) -> bool {
false
}
/// Runs the [`Sandbox`].
///
/// On native platforms, this method will take control of the current thread
/// and __will NOT return__.
///
/// It should probably be that last thing you call in your `main` function.
fn run(settings: Settings<()>) -> Result<(), Error>
where
Self: 'static + Sized,
{
<Self as pure::Application>::run(settings)
}
}
impl<T> pure::Application for T
where
T: Sandbox,
{
type Executor = iced_futures::backend::null::Executor;
type Flags = ();
type Message = T::Message;
type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<T::Message>) {
(T::new(), Command::none())
}
fn title(&self) -> String {
T::title(self)
}
fn update(&mut self, message: T::Message) -> Command<T::Message> {
T::update(self, message);
Command::none()
}
fn view(&self) -> pure::Element<'_, T::Message> {
T::view(self)
}
fn theme(&self) -> Self::Theme {
T::theme(self)
}
fn subscription(&self) -> Subscription<T::Message> {
Subscription::none()
}
fn scale_factor(&self) -> f64 {
T::scale_factor(self)
}
fn should_exit(&self) -> bool {
T::should_exit(self)
}
}
|