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