zng_wgt_toggle/
cmd.rs

1//! Commands that control toggle.
2
3use parking_lot::Mutex;
4use std::{fmt, sync::Arc};
5use zng_var::AnyVarValue;
6
7use zng_wgt::prelude::*;
8
9use super::SELECTOR;
10
11command! {
12    /// Represents the **toggle** action.
13    ///
14    /// # Handlers
15    ///
16    /// * [`checked`]: The property toggles for no param and or sets to the `bool` param or to
17    /// the `Option<bool>` param coercing `None` to `false`.
18    ///
19    /// * [`checked_opt`]: The property cycles or toggles depending on [`tristate`] for no params, otherwise
20    /// it sets the `bool` or `Option<bool>` param.
21    ///
22    /// * [`value`]: The property toggles select/unselect the value for no params, otherwise it selects the value
23    /// for param `true` or `Some(true)` and deselects the value for param `false` or `None::<bool>`. Note that you
24    /// can also use the [`SELECT_CMD`] for value.
25    ///
26    /// [`checked`]: fn@super::checked
27    /// [`checked_opt`]: fn@super::checked_opt
28    /// [`tristate`]: fn@super::tristate
29    /// [`value`]: fn@super::value
30    pub static TOGGLE_CMD;
31
32    /// Represents the **select** action.
33    ///
34    /// # Handlers
35    ///
36    /// * [`value`]: The property selects the value if the command has no param.
37    ///
38    /// * [`selector`]: The property applies the [`SelectOp`] param.
39    ///
40    /// [`value`]: fn@super::value
41    /// [`selector`]: fn@super::selector
42    pub static SELECT_CMD;
43}
44
45/// Represents a select operation that can be send to [`selector`] using [`SELECT_CMD`].
46///
47/// [`selector`]: fn@super::selector
48#[derive(Clone)]
49pub struct SelectOp {
50    op: Arc<Mutex<dyn FnMut() + Send>>,
51}
52impl fmt::Debug for SelectOp {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        f.debug_struct("SelectOp").finish_non_exhaustive()
55    }
56}
57impl SelectOp {
58    /// New (de)select operation.
59    ///
60    /// The [`selector`] property handles [`SELECT_CMD`] by calling `op` during event handling.
61    /// You can use [`SELECTOR`] to get and set the selection.
62    ///
63    /// [`selector`]: fn@super::selector
64    pub fn new(op: impl FnMut() + Send + 'static) -> Self {
65        Self {
66            op: Arc::new(Mutex::new(op)),
67        }
68    }
69
70    /// Select the `value`.
71    pub fn select(value: Box<dyn AnyVarValue>) -> Self {
72        let mut value = Some(value);
73        Self::new(move || {
74            if let Some(value) = value.take() {
75                if let Err(e) = SELECTOR.get().select(value) {
76                    tracing::error!("select error: {e}");
77                }
78            }
79        })
80    }
81
82    /// Deselect the `value`.
83    pub fn deselect(value: Box<dyn AnyVarValue>) -> Self {
84        Self::new(move || {
85            if let Err(e) = SELECTOR.get().deselect(&*value) {
86                tracing::error!("deselect error: {e}");
87            }
88        })
89    }
90
91    /// Run the operation.
92    pub fn call(&self) {
93        (self.op.lock())()
94    }
95}