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 (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 = (self.enter().clone(), self.appearances().clone(), self.label().clone());
79 (from, to)
80 }
81
82 #[inline]
84 pub fn off (&mut self) -> (
85 Option <Trigger>,
86 (Option <Trigger>, controller::Appearances, Option <String>)
87 ) {
88 if cfg!(debug_assertions) && self.state != State::On {
89 log::debug!("switch off state not on: {:?}", self.state);
90 }
91 let from = self.exit().clone();
92 self.state = State::Off;
93 let to = (self.enter().clone(), self.appearances().clone(), self.label().clone());
94 (from, to)
95 }
96}
97
98impl Builder {
99 #[inline]
100 pub const fn appearance (mut self,
101 state : (State, controller::State),
102 appearance : view::Appearance
103 ) -> Self {
104 *self.appearances.appearance_mut (state) = appearance;
105 self
106 }
107 #[inline]
109 pub fn label (mut self, label : String) -> Self {
110 for (_, l) in self.appearances.0.iter_mut() {
111 *l = Some (label.clone());
112 }
113 self
114 }
115 #[inline]
116 pub fn label_on (mut self, label : String) -> Self {
117 self.appearances.0[State::On as usize].1 = Some (label);
118 self
119 }
120 #[inline]
121 pub fn label_off (mut self, label : String) -> Self {
122 self.appearances.0[State::Off as usize].1 = Some (label);
123 self
124 }
125 #[inline]
126 pub const fn enter (mut self, state : State, trigger : Trigger) -> Self {
127 *self.enter.get_mut (state) = Some (trigger);
128 self
129 }
130 #[inline]
131 pub const fn exit (mut self, state : State, trigger : Trigger) -> Self {
132 *self.exit.get_mut (state) = Some (trigger);
133 self
134 }
135 #[inline]
136 pub const fn style (mut self, state : (State, controller::State), style : view::Style)
137 -> Self
138 {
139 self.appearances.appearance_mut (state).style = Some(style);
140 self
141 }
142 #[inline]
143 pub fn style_default (mut self, state : (State, controller::State)) -> Self {
144 let style = Some (view::Style::default());
145 self.appearances.appearance_mut (state).style = style;
146 self
147 }
148 #[inline]
149 pub const fn sound (mut self, state : (State, controller::State), sound : view::Sound)
150 -> Self
151 {
152 self.appearances.appearance_mut (state).sound = Some (sound);
153 self
154 }
155 #[inline]
156 pub fn style_fg (mut self, state : (State, controller::State), color : view::Color)
157 -> Self
158 {
159 let style = &mut self.appearances.appearance_mut (state).style;
160 let mut s = style.take().unwrap_or_default();
161 s.fg = color;
162 *style = Some (s);
163 self
164 }
165 #[inline]
166 pub fn style_bg (mut self, state : (State, controller::State), color : view::Color)
167 -> Self
168 {
169 let appearance = &mut self.appearances.0[state.0 as usize].0.0[state.1 as usize];
170 let mut style = appearance.style.take().unwrap_or_default();
171 style.bg = color;
172 appearance.style = Some (style);
173 self
174 }
175 #[inline]
176 pub fn style_lo (mut self, state : (State, controller::State), color : view::Color)
177 -> Self
178 {
179 let appearance = &mut self.appearances.0[state.0 as usize].0.0[state.1 as usize];
180 let mut style = appearance.style.take().unwrap_or_default();
181 style.lo = color;
182 appearance.style = Some (style);
183 self
184 }
185 #[inline]
186 pub fn style_hi (mut self, state : (State, controller::State), color : view::Color)
187 -> Self
188 {
189 let appearance = &mut self.appearances.0[state.0 as usize].0.0[state.1 as usize];
190 let mut style = appearance.style.take().unwrap_or_default();
191 style.hi = color;
192 appearance.style = Some (style);
193 self
194 }
195 pub const fn toggle (mut self, toggle : bool) -> Self {
196 self.toggle = toggle;
197 self
198 }
199 #[inline]
200 pub fn build (self) -> Switch {
201 Switch {
202 appearances: self.appearances,
203 enter: self.enter,
204 exit: self.exit,
205 toggle: self.toggle,
206 .. Switch::default()
207 }
208 }
209}
210
211impl Appearances {
212 #[inline]
213 pub const fn appearance (&self, state : (State, controller::State))
214 -> &view::Appearance
215 {
216 self.0[state.0 as usize].0.get (state.1)
217 }
218
219 #[inline]
220 pub const fn appearance_mut (&mut self, state : (State, controller::State))
221 -> &mut view::Appearance
222 {
223 self.0[state.0 as usize].0.get_mut (state.1)
224 }
225}
226
227impl Triggers {
228 #[inline]
229 pub const fn get (&self, state : State) -> &Option <Trigger> {
230 &self.0[state as usize]
231 }
232
233 #[inline]
234 pub const fn get_mut (&mut self, state : State) -> &mut Option <Trigger> {
235 &mut self.0[state as usize]
236 }
237}
238
239impl Trigger {
240 #[inline]
242 pub fn new <A : Application> (control : controls::Button, target : Option <NodeId>)
243 -> Self
244 {
245 use controller::controls::Control;
246 let control_fun = control.fun::<A::ButtonControls>();
247 Trigger { control_fun, target }
248 }
249}