gooey/interface/controller/component/
switch.rs1use strum::EnumCount;
2use crate::Application;
3use crate::tree::NodeId;
4use crate::interface::view;
5use crate::interface::controller::{self, controls};
6use super::impl_kind;
7
8#[derive(Clone, Debug, Default)]
10pub struct Switch {
11 pub state : State,
12 pub appearances : Appearances,
13 pub enter : Triggers,
14 pub exit : Triggers,
15 pub toggle : bool
16 }
19impl_kind!(Switch);
20
21#[derive(Clone, Debug, Eq, PartialEq, EnumCount)]
22pub enum State {
23 On,
24 Off
25}
26
27#[derive(Clone, Debug, Default)]
29pub struct Appearances (
30 pub [(controller::Appearances, Option <String>); State::COUNT]);
31
32#[derive(Clone, Debug, Default)]
33pub struct Triggers (pub [Option <Trigger>; State::COUNT]);
34
35#[derive(Clone, Debug)]
36pub struct Trigger {
37 pub control_fun : controls::Fun <controls::button::Release>,
38 pub target : Option <NodeId>
39}
40
41#[derive(Clone, Default)]
42pub struct Builder {
43 pub appearances : Appearances,
44 pub enter : Triggers,
45 pub exit : Triggers,
46 pub toggle : bool
47}
48
49impl Switch {
50 #[inline]
51 pub fn enter (&self) -> &Option <Trigger> {
52 &self.enter.0[self.state.clone() as usize]
53 }
54 #[inline]
55 pub fn exit (&self) -> &Option <Trigger> {
56 &self.exit.0[self.state.clone() as usize]
57 }
58 #[inline]
59 pub fn appearances (&self) -> &controller::Appearances {
60 &self.appearances.0[self.state.clone() as usize].0
61 }
62 #[inline]
63 pub fn label (&self) -> &Option <String> {
64 &self.appearances.0[self.state.clone() as usize].1
65 }
66
67 #[inline]
69 pub fn on (&mut self) -> (
70 Option <Trigger>,
71 (Option <Trigger>, controller::Appearances, Option <String>)
72 ) {
73 if cfg!(debug_assertions) && self.state != State::Off {
74 log::debug!("switch on state not off: {:?}", self.state);
75 }
76 let from = self.exit().clone();
77 self.state = State::On;
78 let to =
79 (self.enter().clone(), self.appearances().clone(), self.label().clone());
80 (from, to)
81 }
82
83 #[inline]
85 pub fn off (&mut self) -> (
86 Option <Trigger>,
87 (Option <Trigger>, controller::Appearances, Option <String>)
88 ) {
89 if cfg!(debug_assertions) && self.state != State::On {
90 log::debug!("switch off state not on: {:?}", self.state);
91 }
92 let from = self.exit().clone();
93 self.state = State::Off;
94 let to =
95 (self.enter().clone(), self.appearances().clone(), self.label().clone());
96 (from, to)
97 }
98}
99
100impl Builder {
101 #[inline]
102 pub fn appearance (mut self,
103 state : (State, controller::State),
104 appearance : view::Appearance
105 ) -> Self {
106 *self.appearances.appearance_mut (state) = appearance;
107 self
108 }
109 #[inline]
111 pub fn label (mut self, label : String) -> Self {
112 for (_, l) in self.appearances.0.iter_mut() {
113 *l = Some (label.clone());
114 }
115 self
116 }
117 #[inline]
118 pub fn label_on (mut self, label : String) -> Self {
119 self.appearances.0[State::On as usize].1 = Some (label);
120 self
121 }
122 #[inline]
123 pub fn label_off (mut self, label : String) -> Self {
124 self.appearances.0[State::Off as usize].1 = Some (label);
125 self
126 }
127 #[inline]
128 pub fn enter (mut self, state : State, trigger : Trigger) -> Self {
129 *self.enter.get_mut (state) = Some (trigger);
130 self
131 }
132 #[inline]
133 pub fn exit (mut self, state : State, trigger : Trigger) -> Self {
134 *self.exit.get_mut (state) = Some (trigger);
135 self
136 }
137 #[inline]
138 pub fn style (mut self,
139 state : (State, controller::State), style : view::Style
140 ) -> Self {
141 self.appearances.appearance_mut (state).style = Some(style);
142 self
143 }
144 #[inline]
145 pub fn style_default (mut self, state : (State, controller::State)) -> Self {
146 let style = Some (view::Style::default());
147 self.appearances.appearance_mut (state).style = style;
148 self
149 }
150 #[inline]
151 pub fn sound (mut self,
152 state : (State, controller::State), sound : view::Sound
153 ) -> Self {
154 self.appearances.appearance_mut (state).sound = Some (sound);
155 self
156 }
157 #[inline]
158 pub fn style_fg (mut self,
159 state : (State, controller::State), color : view::Color
160 ) -> Self {
161 let style = &mut self.appearances.appearance_mut (state).style;
162 let mut s = style.take().unwrap_or_default();
163 s.fg = color;
164 *style = Some (s);
165 self
166 }
167 #[inline]
168 pub fn style_bg (mut self,
169 state : (State, controller::State), color : view::Color
170 ) -> Self {
171 let appearance = &mut self.appearances.0[state.0 as usize]
172 .0.0[state.1 as usize];
173 let mut style = appearance.style.take().unwrap_or_default();
174 style.bg = color;
175 appearance.style = Some (style);
176 self
177 }
178 #[inline]
179 pub fn style_lo (mut self,
180 state : (State, controller::State), color : view::Color
181 ) -> Self {
182 let appearance = &mut self.appearances.0[state.0 as usize]
183 .0.0[state.1 as usize];
184 let mut style = appearance.style.take().unwrap_or_default();
185 style.lo = color;
186 appearance.style = Some (style);
187 self
188 }
189 #[inline]
190 pub fn style_hi (mut self,
191 state : (State, controller::State), color : view::Color
192 ) -> Self {
193 let appearance = &mut self.appearances.0[state.0 as usize]
194 .0.0[state.1 as usize];
195 let mut style = appearance.style.take().unwrap_or_default();
196 style.hi = color;
197 appearance.style = Some (style);
198 self
199 }
200 pub fn toggle (mut self, toggle : bool) -> Self {
201 self.toggle = toggle;
202 self
203 }
204 #[inline]
205 pub fn build (self) -> Switch {
206 Switch {
207 appearances: self.appearances,
208 enter: self.enter,
209 exit: self.exit,
210 toggle: self.toggle,
211 .. Switch::default()
212 }
213 }
214}
215
216impl Appearances {
217 #[inline]
218 pub fn appearance (&self, state : (State, controller::State))
219 -> &view::Appearance
220 {
221 self.0[state.0 as usize].0.get (state.1)
222 }
223
224 #[inline]
225 pub fn appearance_mut (&mut self, state : (State, controller::State))
226 -> &mut view::Appearance
227 {
228 self.0[state.0 as usize].0.get_mut (state.1)
229 }
230}
231
232impl Triggers {
233 #[inline]
234 pub fn get (&self, state : State) -> &Option <Trigger> {
235 &self.0[state as usize]
236 }
237
238 #[inline]
239 pub fn get_mut (&mut self, state : State) -> &mut Option <Trigger> {
240 &mut self.0[state as usize]
241 }
242}
243
244impl Trigger {
245 #[inline]
247 pub fn new <A : Application>
248 (control : controls::Button, target : Option <NodeId>) -> Self
249 {
250 use controller::controls::Control;
251 let control_fun = control.fun::<A::ButtonControls>();
252 Trigger { control_fun, target }
253 }
254}
255
256impl Default for State {
257 fn default() -> Self {
258 State::Off
259 }
260}