zng/toggle.rs
1#![cfg(feature = "toggle")]
2
3//! Toggle button widget and styles for check box, combo box, radio button and switch button.
4//!
5//! The [`Toggle!`](struct@Toggle) widget has three states, `Some(true)`, `Some(false)` and `None`. How
6//! the widget toggles between this values is defined by what property is used to bind the state.
7//!
8//! The [`checked`](struct@Toggle#checked) property binds to a `bool` variable and toggles between `true` and `false` only.
9//! The example below makes use of the property.
10//!
11//! ```
12//! use zng::prelude::*;
13//! # fn example() {
14//!
15//! let checked = var(false);
16//! # let _ =
17//! Toggle! {
18//! child = Text!(checked.map(|b| formatx!("checked = {b}")));
19//! checked;
20//! }
21//! # ; }
22//! ```
23//!
24//! The [`checked_opt`](struct@Toggle#method.checked_opt) and [`tristate`](struct@Toggle#method.tristate) properties can be used to toggle
25//! between `Some(true)` and `Some(false)` and accept the `None` value, or with tristate enabled to include `None` in the toggle cycle.
26//! Note that even if tristate is not enabled the variable can be set to `None` from another source and the widget will display the
27//! `None` appearance.
28//!
29//! ```
30//! use zng::prelude::*;
31//! # fn example() {
32//!
33//! let checked = var(Some(false));
34//! # let _ =
35//! Toggle! {
36//! child = Text!(checked.map(|b| formatx!("checked = {b:?}")));
37//! tristate = true;
38//! checked_opt = checked;
39//! }
40//! # ; }
41//! ```
42//!
43//! The [`selector`](fn@selector) and [`value`](struct@Toggle#method.value) properties can be used to have the toggle insert and
44//! remove a value from a contextual selection of values. The example below declares a stack with 10 toggle buttons each
45//! representing a value, the stack is also setup as a selector context for these toggle buttons, when each toggle button
46//! is clicked it replaces the selected value.
47//!
48//! Note that the toggle does not know what the selection actually is, the [`Selector`] type abstracts over multiple
49//! selection kinds, including custom implementations of [`SelectorImpl`].
50//!
51//! ```
52//! use zng::prelude::*;
53//! # fn example() {
54//!
55//! let selected_item = var(1_i32);
56//! # let _ =
57//! Stack! {
58//! toggle::selector = toggle::Selector::single(selected_item.clone());
59//!
60//! spacing = 5;
61//! children =
62//! (1..=10_i32)
63//! .map(|i| {
64//! Toggle! {
65//! child = Text!("Item {i}");
66//! value::<i32> = i;
67//! }
68//! })
69//! .collect::<Vec<_>>(),
70//! ;
71//! }
72//! # ; }
73//! ```
74//!
75//! Regardless of how the checked state of a toggle is defined the [`IS_CHECKED_VAR`] variable and [`is_checked`](fn@is_checked) property
76//! can be used to track the checked state of the widget. The example below defines a toggle that changes background color to green
77//! when it is in the `Some(true)` state.
78//!
79//! ```
80//! # use zng::prelude::*;
81//! # fn example() {
82//! # let _ =
83//! Toggle! {
84//! checked = var(false);
85//! // checked_opt = var(Some(false));
86//! // value<i32> = 42;
87//!
88//! widget::background_color = colors::RED;
89//! when *#is_checked {
90//! widget::background_color = colors::GREEN;
91//! }
92//! }
93//! # ; }
94//! ```
95//!
96//! # Styles
97//!
98//! Toggle is a versatile widget, it can be styled to represent check boxes, switches, radio buttons and combo boxes.
99//!
100//! ## Check & Switch
101//!
102//! The [`CheckStyle!`](struct@CheckStyle) changes the toggle into a check box. The [`SwitchStyle!`](struct@SwitchStyle)
103//! changes the toggle into an on/off switch.
104//!
105//! ```
106//! use zng::prelude::*;
107//! # fn example() {
108//!
109//! # let _ =
110//! Toggle! {
111//! child = Text!(toggle::IS_CHECKED_VAR.map(|&s| match s {
112//! Some(true) => Txt::from("checked text"),
113//! Some(false) => Txt::from("unchecked text"),
114//! None => Txt::from(""),
115//! }));
116//! checked = var(false);
117//! style_fn = toggle::SwitchStyle!();
118//! }
119//! # ; }
120//! ```
121//!
122//! The example above declares a toggle switch that changes the text depending on the state.
123//!
124//! ## Radio
125//!
126//! The [`RadioStyle!`](struct@RadioStyle) can be used in `value` toggle areas. The example below
127//! declares a stack that is a selector context and sets the toggle style for all toggle buttons inside.
128//!
129//! ```
130//! # use zng::prelude::*;
131//! # fn example() {
132//! let selected_item = var(1_i32);
133//! # let _ =
134//! Stack! {
135//! toggle::style_fn = style_fn!(|_| toggle::RadioStyle!());
136//! toggle::selector = toggle::Selector::single(selected_item.clone());
137//! // ..
138//! }
139//! # ; }
140//! ```
141//!
142//! ## Combo
143//!
144//! The [`ComboStyle!`](struct@ComboStyle) together with the [`checked_popup`](struct@Toggle#method.checked_popup) property can be used
145//! to declare a combo box, that is a toggle for a drop down that contains another toggle selector context that selects a value.
146//!
147//! Note that the `checked_popup` setups the `checked` state, you cannot set one of the other checked properties in the same
148//! widget.
149//!
150//! The example below declares a combo box with a `TextInput!` content, users can type a custom option or open the popup and pick
151//! an option. Note that this also restyles `Toggle!` inside the popup to look like a menu item.
152//!
153//! ```
154//! use zng::prelude::*;
155//! # fn example() {
156//!
157//! let txt = var(Txt::from_static("Combo"));
158//! let options = ["Combo", "Congo", "Pombo"];
159//! # let _ =
160//! Toggle! {
161//! child = TextInput! {
162//! txt = txt.clone();
163//! gesture::on_click = hn!(|a| a.propagation().stop());
164//! };
165//! style_fn = toggle::ComboStyle!();
166//!
167//! checked_popup = wgt_fn!(|_| popup::Popup! {
168//! id = "popup";
169//! child = Stack! {
170//! toggle::selector = toggle::Selector::single(txt.clone());
171//! direction = StackDirection::top_to_bottom();
172//! children = options.into_iter().map(|o| {
173//! Toggle! {
174//! child = Text!(o);
175//! value::<Txt> = o;
176//! }
177//! });
178//! };
179//! });
180//! }
181//! # ; }
182//! ```
183//!
184//! # Full API
185//!
186//! See [`zng_wgt_toggle`] for the full widget API.
187
188pub use zng_wgt_toggle::{
189 CheckStyle, ComboStyle, DefaultStyle, IS_CHECKED_VAR, LightStyle, RadioStyle, Selector, SelectorError, SelectorImpl, SwitchStyle,
190 Toggle, check_style_fn, combo_style_fn, deselect_on_deinit, deselect_on_new, is_checked, light_style_fn, radio_style_fn,
191 scroll_on_select, select_on_init, select_on_new, selector, style_fn, switch_style_fn, tristate,
192};
193
194/// Toggle commands.
195pub mod cmd {
196 pub use zng_wgt_toggle::cmd::{SELECT_CMD, SelectOp, TOGGLE_CMD};
197}