zng/toggle.rs
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
//! Toggle button widget and styles for check box, combo box, radio button and switch button.
//!
//! The [`Toggle!`](struct@Toggle) widget has three states, `Some(true)`, `Some(false)` and `None`. How
//! the widget toggles between this values is defined by what property is used to bind the state.
//!
//! The [`checked`](struct@Toggle#checked) property binds to a `bool` variable and toggles between `true` and `false` only.
//! The example below makes use of the property.
//!
//! ```
//! use zng::prelude::*;
//! # let _scope = APP.defaults();
//!
//! let checked = var(false);
//! # let _ =
//! Toggle! {
//! child = Text!(checked.map(|b| formatx!("checked = {b}")));
//! checked;
//! }
//! # ;
//! ```
//!
//! The [`checked_opt`](struct@Toggle#method.checked_opt) and [`tristate`](struct@Toggle#method.tristate) properties can be used to toggle
//! between `Some(true)` and `Some(false)` and accept the `None` value, or with tristate enabled to include `None` in the toggle cycle.
//! Note that even if tristate is not enabled the variable can be set to `None` from another source and the widget will display the
//! `None` appearance.
//!
//! ```
//! use zng::prelude::*;
//! # let _scope = APP.defaults();
//!
//! let checked = var(Some(false));
//! # let _ =
//! Toggle! {
//! child = Text!(checked.map(|b| formatx!("checked = {b:?}")));
//! tristate = true;
//! checked_opt = checked;
//! }
//! # ;
//! ```
//!
//! The [`selector`](fn@selector) and [`value`](struct@Toggle#method.value) properties can be used to have the toggle insert and
//! remove a value from a contextual selection of values. The example below declares a stack with 10 toggle buttons each
//! representing a value, the stack is also setup as a selector context for these toggle buttons, when each toggle button
//! is clicked it replaces the selected value.
//!
//! Note that the toggle does not know what the selection actually is, the [`Selector`] type abstracts over multiple
//! selection kinds, including custom implementations of [`SelectorImpl`].
//!
//! ```
//! use zng::prelude::*;
//! # let _scope = APP.defaults();
//!
//! let selected_item = var(1_i32);
//! # let _ =
//! Stack! {
//! toggle::selector = toggle::Selector::single(selected_item.clone());
//!
//! spacing = 5;
//! children = (1..=10_i32).map(|i| {
//! Toggle! {
//! child = Text!("Item {i}");
//! value::<i32> = i;
//! }
//! .boxed()
//! }).collect::<Vec<_>>();
//! }
//! # ;
//! ```
//!
//! Regardless of how the checked state of a toggle is defined the [`IS_CHECKED_VAR`] variable and [`is_checked`](fn@is_checked) property
//! can be used to track the checked state of the widget. The example below defines a toggle that changes background color to green
//! when it is in the `Some(true)` state.
//!
//! ```
//! # use zng::prelude::*;
//! # let _scope = APP.defaults();
//! # let _ =
//! Toggle! {
//! checked = var(false);
//! // checked_opt = var(Some(false));
//! // value<i32> = 42;
//!
//! widget::background_color = colors::RED;
//! when *#is_checked {
//! widget::background_color = colors::GREEN;
//! }
//! }
//! # ;
//! ```
//!
//! # Styles
//!
//! Toggle is a versatile widget, it can be styled to represent check boxes, switches, radio buttons and combo boxes.
//!
//! ## Check & Switch
//!
//! The [`CheckStyle!`](struct@CheckStyle) changes the toggle into a check box. The [`SwitchStyle!`](struct@SwitchStyle)
//! changes the toggle into an on/off switch.
//!
//! ```
//! use zng::prelude::*;
//! # let _scope = APP.defaults();
//!
//! # let _ =
//! Toggle! {
//! child = Text!(toggle::IS_CHECKED_VAR.map(|&s| match s {
//! Some(true) => Txt::from("checked text"),
//! Some(false) => Txt::from("unchecked text"),
//! None => Txt::from(""),
//! }));
//! checked = var(false);
//! style_fn = toggle::SwitchStyle!();
//! }
//! # ;
//! ```
//!
//! The example above declares a toggle switch that changes the text depending on the state.
//!
//! ## Radio
//!
//! The [`RadioStyle!`](struct@RadioStyle) can be used in `value` toggle areas. The example below
//! declares a stack that is a selector context and sets the toggle style for all toggle buttons inside.
//!
//! ```
//! # use zng::prelude::*;
//! # let _scope = APP.defaults();
//! let selected_item = var(1_i32);
//! # let _ =
//! Stack! {
//! toggle::style_fn = style_fn!(|_| toggle::RadioStyle!());
//! toggle::selector = toggle::Selector::single(selected_item.clone());
//! // ..
//! }
//! # ;
//! ```
//!
//! ## Combo
//!
//! The [`ComboStyle!`](struct@ComboStyle) together with the [`checked_popup`](struct@Toggle#method.checked_popup) property can be used
//! to declare a combo box, that is a toggle for a drop down that contains another toggle selector context that selects a value.
//!
//! Note that the `checked_popup` setups the `checked` state, you cannot set one of the other checked properties in the same
//! widget.
//!
//! The example below declares a combo box with a `TextInput!` content, users can type a custom option or open the popup and pick
//! an option. Note that the `ComboStyle!` also restyles `Toggle!` inside the popup to look like a menu item.
//!
//! ```
//! use zng::prelude::*;
//! # let _scope = APP.defaults();
//!
//! let txt = var(Txt::from_static("Combo"));
//! let options = ["Combo", "Congo", "Pombo"];
//! # let _ =
//! Toggle! {
//! child = TextInput! {
//! txt = txt.clone();
//! gesture::on_click = hn!(|a: &gesture::ClickArgs| a.propagation().stop());
//! };
//! style_fn = toggle::ComboStyle!();
//!
//! checked_popup = wgt_fn!(|_| popup::Popup! {
//! id = "popup";
//! child = Stack! {
//! toggle::selector = toggle::Selector::single(txt.clone());
//! direction = StackDirection::top_to_bottom();
//! children = options.into_iter().map(|o| Toggle! {
//! child = Text!(o);
//! value::<Txt> = o;
//! })
//! .collect::<UiVec>();
//! };
//! })
//! }
//! # ;
//! ```
//!
//! # Full API
//!
//! See [`zng_wgt_toggle`] for the full widget API.
pub use zng_wgt_toggle::{
check_spacing, combo_spacing, deselect_on_deinit, deselect_on_new, is_checked, radio_spacing, scroll_on_select, select_on_init,
select_on_new, selector, style_fn, switch_spacing, tristate, CheckStyle, ComboStyle, DefaultStyle, LightStyle, RadioStyle, Selector,
SelectorError, SelectorImpl, SwitchStyle, Toggle, IS_CHECKED_VAR,
};
/// Toggle commands.
pub mod cmd {
pub use zng_wgt_toggle::cmd::{SelectOp, SELECT_CMD, TOGGLE_CMD};
}