vizia_core/modifiers/
abilities.rs

1use super::internal;
2use crate::prelude::*;
3
4/// Modifiers for changing the abilities of a view.
5pub trait AbilityModifiers: internal::Modifiable {
6    /// Sets whether the view can be hovered by the mouse and receive mouse events.
7    ///
8    /// Accepts a bool or a lens to some boolean state.
9    /// Views which cannot be hovered will not receive mouse input events unless
10    /// the view has captured the mouse input, see [`cx.capture()`](crate::prelude::EventContext::capture).
11    ///
12    /// # Example
13    /// ```
14    /// # use vizia_core::prelude::*;
15    /// # let cx = &mut Context::default();
16    /// Label::new(cx, "Hello Vizia")
17    ///     .hoverable(false);
18    /// ```
19    fn hoverable<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
20        let entity = self.entity();
21        let current = self.entity();
22        self.context().with_current(current, move |cx| {
23            state.set_or_bind(cx, entity, move |cx, v| {
24                let val = v.get(cx).into();
25                if let Some(abilities) = cx.style.abilities.get_mut(entity) {
26                    abilities.set(Abilities::HOVERABLE, val);
27                    cx.needs_restyle(entity);
28                }
29            });
30        });
31
32        self
33    }
34
35    /// Sets whether the view can be focused to receive keyboard input events.
36    ///
37    /// Accepts a bool or a lens to some boolean state.
38    /// # Example
39    /// ```
40    /// # use vizia_core::prelude::*;
41    /// # let cx = &mut Context::default();
42    /// Label::new(cx, "Hello Vizia")
43    ///     .focusable(false);
44    /// ```
45    fn focusable<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
46        let entity = self.entity();
47        let current = self.current();
48        self.context().with_current(current, move |cx| {
49            state.set_or_bind(cx, entity, move |cx, v| {
50                let state = v.get(cx).into();
51                if let Some(abilities) = cx.style.abilities.get_mut(entity) {
52                    abilities.set(Abilities::FOCUSABLE, state);
53
54                    // If an element is not focusable then it can't be keyboard navigable.
55                    if !state {
56                        abilities.set(Abilities::NAVIGABLE, false);
57                    }
58
59                    cx.needs_restyle(entity);
60                }
61            });
62        });
63
64        self
65    }
66
67    /// Sets whether the view can be checked.
68    ///
69    /// Accepts a bool or a lens to some boolean state.
70    /// # Example
71    /// ```
72    /// # use vizia_core::prelude::*;
73    /// # let cx = &mut Context::default();
74    /// Label::new(cx, "Hello Vizia")
75    ///     .checkable(false);
76    /// ```
77    fn checkable<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
78        let entity = self.entity();
79        let current = self.current();
80        self.context().with_current(current, move |cx| {
81            state.set_or_bind(cx, entity, move |cx, v| {
82                let state = v.get(cx).into();
83                if let Some(abilities) = cx.style.abilities.get_mut(cx.current) {
84                    abilities.set(Abilities::CHECKABLE, state);
85
86                    cx.needs_restyle(entity);
87                }
88            });
89        });
90
91        self
92    }
93
94    /// Sets whether the view can be navigated to, i.e. focused, by the keyboard.
95    ///
96    /// Accepts a bool or a lens to some boolean state.
97    /// Navigating to a view with the keyboard gives the view keyboard focus and is typically done with `tab` and `shift + tab` key combinations.
98    /// # Example
99    /// ```
100    /// # use vizia_core::prelude::*;
101    /// # let cx = &mut Context::default();
102    /// Label::new(cx, "Hello Vizia")
103    ///     .checkable(false);
104    /// ```
105    fn navigable<U: Into<bool>>(mut self, state: impl Res<U>) -> Self {
106        let entity = self.entity();
107        let current = self.current();
108        self.context().with_current(current, move |cx| {
109            state.set_or_bind(cx, entity, move |cx, v| {
110                let val = v.get(cx).into();
111                if let Some(abilities) = cx.style.abilities.get_mut(entity) {
112                    abilities.set(Abilities::NAVIGABLE, val);
113                    cx.needs_restyle(entity);
114                }
115            });
116        });
117
118        self
119    }
120}
121
122impl<V> AbilityModifiers for Handle<'_, V> {}