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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//! Data binding provides a way to link views to model data so that view properties update when data changes.
//!
//! # Example
//! First we declare some data for our application:
//! ```
//! # use vizia_core::prelude::*;
//!
//!
//! struct AppData {
//! count: i32,
//! }
//!
//! ```
//! Next we'll declare some events which will be sent by views to modify the data. Data binding in vizia is one-way, events are sent up the tree
//! to the app data to mutate it and updated values are sent to observers, such as a [`Binding`] view.
//! ```
//! enum AppEvent {
//! Increment,
//! Decrement,
//! }
//! ```
//! Then we implement the [`Model`](crate::model::Model) trait on our data, which allows us to modify the it in response to an [`Event`](crate::events::Event):
//! ```
//! # use vizia_core::prelude::*;
//!
//!
//! struct AppData {
//! count: i32,
//! }
//!
//! enum AppEvent {
//! Increment,
//! Decrement,
//! }
//!
//! impl Model for AppData {
//! fn event(&mut self, cx: &mut EventContext, event: &mut Event) {
//! event.map(|app_event, _| match app_event {
//! AppEvent::Increment => {
//! self.count += 1;
//! }
//!
//! AppEvent::Decrement => {
//! self.count -= 1;
//! }
//! });
//! }
//! }
//! ```
//! This trait also allows data to be built into the application [Tree](crate::prelude::Tree):
//! ```ignore
//! # use vizia_core::prelude::*;
//!
//! # use vizia_winit::application::Application;
//!
//! struct AppData {
//! count: i32,
//! }
//!
//! impl Model for AppData {}
//!
//! fn main() {
//! Application::new(|cx|{
//! AppData {
//! count: 0,
//! }.build(cx);
//! }).run();
//! }
//! ```
//! A [`Binding`] view is one way in which data can be used by views. It observes a signal and rebuilds whenever the signal changes:
//! ```ignore
//! # use vizia_core::prelude::*;
//!
//! # use vizia_winit::application::Application;
//!
//! struct AppData {
//! count: Signal<i32>,
//! }
//!
//! impl Model for AppData {
//! fn event(&mut self, cx: &mut EventContext, event: &mut Event) {
//! event.map(|app_event, _| match app_event {
//! AppEvent::Increment => {
//! self.count.update(|count| *count += 1);
//! }
//!
//! AppEvent::Decrement => {
//! self.count.update(|count| *count -= 1);
//! }
//! });
//! }
//! }
//!
//! enum AppEvent {
//! Increment,
//! Decrement,
//! }
//!
//! fn main() {
//! Application::new(|cx|{
//! let count = Signal::new(0);
//! AppData {
//! count,
//! }.build(cx);
//!
//! Binding::new(cx, count, |cx|{
//! Label::new(cx, count.get().to_string());
//! });
//!
//! Button::new(cx, |cx|{
//! Label::new(cx, "Increment")
//! })
//! .on_press(|cx| cx.emit(AppEvent::Increment));
//!
//! Button::new(cx, |cx|{
//! Label::new(cx, "Decrement")
//! })
//! .on_press(|cx| cx.emit(AppEvent::Decrement));
//! }).run();
//! }
//! ```
//! Note, the button does not need to be bound to the data to send an event to it. By default events will propagate up the tree.
//!
//! Completely rebuilding the `Label` when the data changes is unnecessary in this case. Instead we can pass a signal directly to
//! the view constructor so only the relevant property updates.
//! ```ignore
//! # use vizia_core::prelude::*;
//! # use vizia_winit::application::Application;
//!
//! fn main() {
//! Application::new(|cx|{
//! let count = Signal::new(0);
//!
//! Label::new(cx, count);
//!
//! Button::new(cx, |cx|{
//! Label::new(cx, "Increment")
//! })
//! .on_press(move |_| count.update(|v| *v += 1));
//!
//! Button::new(cx, |cx|{
//! Label::new(cx, "Decrement")
//! })
//! .on_press(move |_| count.update(|v| *v -= 1));
//! }).run();
//! }
//! ```
//!
//! Note that even though the `count` value is `i32`, the label accepts it because it implements `ToString` and is converted internally.
//! If the data is the wrong type and cannot be converted internally, use a mapped signal or a custom formatter.
pub use BindingHandler;
pub use *;
pub use Binding;