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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
//! Data binding provides a way to link views to model data so that view properties update when data changes.
//!
//! # Example
//! Fist we declare some data for our application. The [Lens] trait has been derived for the data, which allows us to bind to fields of the struct:
//! ```
//! # use vizia_core::prelude::*;
//! # use vizia_derive::*;
//! #[derive(Lens)]
//! 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::*;
//! # use vizia_derive::*;
//! #[derive(Lens)]
//! 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):
//! ```no_run
//! # use vizia_core::prelude::*;
//! # use vizia_derive::*;
//! # use vizia_winit::application::Application;
//! #[derive(Lens)]
//! 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. A [`Lens`] is used to determine what data the binding should react to:
//! ```no_run
//! # use vizia_core::prelude::*;
//! # use vizia_derive::*;
//! # use vizia_winit::application::Application;
//! #[derive(Lens)]
//! struct AppData {
//! count: i32,
//! }
//!
//! impl Model for AppData {}
//!
//! fn main() {
//! Application::new(|cx|{
//! AppData {
//! count: 0,
//! }.build(cx);
//!
//! Binding::new(cx, AppData::count, |cx, count|{
//! Label::new(cx, &count.get(cx).to_string());
//! });
//! }).run();
//! }
//! ```
//! The second parameter to the [Binding] view is a [Lens], allowing us to bind to some field of the application data.
//! The third parameter is a closure which provides the context and the lens, which can be used to retrieve the bound data using the `.get()`
//! method, which takes the [Context](crate::prelude::Context) as an argument.
//!
//! Now when the data is modified, the binding will rebuild its contents and the label will update, for example:
//! ```no_run
//! # use vizia_core::prelude::*;
//! # use vizia_derive::*;
//! # use vizia_winit::application::Application;
//! #[derive(Lens)]
//! struct AppData {
//! count: 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 += 1;
//! }
//!
//! AppEvent::Decrement => {
//! self.count -= 1;
//! }
//! });
//! }
//! }
//!
//! enum AppEvent {
//! Increment,
//! Decrement,
//! }
//!
//! fn main() {
//! Application::new(|cx|{
//! AppData {
//! count: 0,
//! }.build(cx);
//!
//! Binding::new(cx, AppData::count, |cx, count|{
//! Label::new(cx, &count.get(cx).to_string());
//! });
//!
//! Button::new(cx, |cx| cx.emit(AppEvent::Increment), |cx|{
//! Label::new(cx, "Increment")
//! });
//!
//! Button::new(cx, |cx| cx.emit(AppEvent::Increment), |cx|{
//! Label::new(cx, "Decrement")
//! });
//! }).run();
//! }
//! ```
//! Note, the checkbox 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 update just the text of the label
//! by binding the `text()` property modifier to the application data. This is called a property binding.
//! ```no_run
//! # use vizia_core::prelude::*;
//! # use vizia_winit::application::Application;
//!
//! # #[derive(Lens)]
//! # struct AppData {
//! # count: 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 += 1;
//! # }
//! # AppEvent::Decrement => {
//! # self.count -= 1;
//! # }
//! # });
//! # }
//! # }
//! # enum AppEvent {
//! # Increment,
//! # Decrement,
//! # }
//! fn main() {
//! Application::new(|cx|{
//! AppData {
//! count: 0,
//! }.build(cx);
//!
//! Label::new(cx, AppData::count);
//!
//! 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::Increment));
//! }).run();
//! }
//! ```
//!
//! Note that even though the `count` value is `i32`, the label accepts a lens to this data because it implements `ToString` and is converted internally.
//! If the data is the wrong type and cannot be converted internally, use the [`map()`](crate::binding::LensExt::map) method on the lens.
mod lens;
pub use lens::*;
mod store;
pub(crate) use store::*;
mod binding_view;
pub use binding_view::*;
mod data;
pub use data::*;
mod res;
pub use res::*;
mod map;
pub(crate) use map::MapId;