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> {}