1use std::cell::RefCell;
4use std::convert::TryFrom;
5use std::iter::FromIterator;
6use log;
7use bitflags::bitflags;
8use key_vec::KeyVec;
9use smallvec::SmallVec;
10use strum::EnumCount;
11
12use crate::prelude::*;
13
14pub mod controls;
16pub use self::controls::Controls;
17pub mod bindings;
19pub use self::bindings::Bindings;
20pub mod component;
22pub use self::component::Component;
23pub mod alignment;
25pub mod offset;
26pub mod size;
27pub use self::alignment::Alignment;
28pub use self::offset::Offset;
29pub use self::size::Size;
30
31#[derive(Clone, Debug, Default)]
37pub struct Controller {
38 pub component : Component,
39 pub state : State,
41 pub appearances : Appearances,
43 pub focus_top : bool,
50 pub bubble_trap : InputMask,
56 input_map : InputMap
58}
59
60#[derive(Clone, Debug, Default, Eq, PartialEq, EnumCount)]
62pub enum State {
63 #[default]
64 Enabled,
65 Focused,
66 Disabled
67}
68
69#[derive(Clone, Debug, Default, Eq, PartialEq)]
70pub enum Area {
71 #[default]
73 Interior,
74 Exterior
76}
77
78#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
80pub enum Orientation {
81 #[default]
82 Horizontal,
83 Vertical
84}
85
86#[derive(Clone, Debug, Default, Eq, PartialEq)]
88pub struct Appearances (pub [Appearance; State::COUNT]);
89#[derive(Default)]
90pub struct AppearancesBuilder ([Appearance; State::COUNT]);
91
92bitflags! {
93 #[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
94 pub struct InputMask : u8 {
95 const AXIS = 0b0000_0001;
96 const BUTTON = 0b0000_0010;
97 const MOTION = 0b0000_0100;
98 const POINTER = 0b0000_1000;
99 const SYSTEM = 0b0001_0000;
100 const TEXT = 0b0010_0000;
101 const WHEEL = 0b0100_0000;
102 }
103}
104
105#[derive(Clone, Debug, Default, Eq, PartialEq)]
112struct InputMap {
113 pub button_any : Option <controls::Button>,
114 pub buttons : KeyVec <input::Button, controls::Button>,
115 pub release_buttons : KeyVec <input::Button, controls::Button>,
116 pub axes : KeyVec <u32, controls::Axis>,
117 pub motion : Option <controls::Motion>,
118 pub pointer : Option <controls::Pointer>,
119 pub system : Option <controls::System>,
120 pub text : Option <controls::Text>,
121 pub wheel : Option <controls::Wheel>
122}
123
124#[derive(Debug)]
129pub (crate) enum ButtonRelease {
130 Insert (input::Button, SmallVec <[(controls::Button, NodeId); 1]>),
131 Remove (input::Button, NodeId)
132}
133
134pub (crate) fn refocus (node_id : &NodeId, elements : &Tree <Element>)
140 -> Option <NodeId>
141{
142 let node = elements.get (node_id).unwrap();
143 let element = node.data();
144 if element.controller.state != State::Focused {
145 log::warn!("refocus state not focused: {:?}", element.controller.state);
146 debug_assert!(false);
147 }
148 let mut refocus_id = None;
149 if Frame::try_from (element).is_ok() {
151 let mut children_ids = node.children().iter();
152 if let Some (child_id) = children_ids.next() {
154 let child = elements.get_element (child_id);
155 if Field::try_from (child).is_ok() || Numbox::try_from (child).is_ok() {
156 refocus_id = Some (child_id.clone());
157 } else if let Ok (Widget (selection, _, _)) = Menu::try_from (child) {
158 refocus_id = selection.current.clone()
160 .or_else (|| menu::find_first_item (elements, children_ids));
161 }
162 }
163 }
164 refocus_id
165}
166
167impl Controller {
168 #[inline]
169 pub fn with_bindings <A : Application> (bindings : &Bindings <A>) -> Self {
170 Controller { input_map: bindings.into(), .. Controller::default() }
171 }
172
173 #[inline]
174 pub fn get_appearance (&self) -> &Appearance {
175 self.appearances.get (self.state.clone())
176 }
177
178 #[inline]
179 pub fn get_bindings <A : Application> (&self) -> Bindings <A> {
180 self.input_map.to_bindings()
181 }
182
183 #[inline]
185 pub fn set_bindings <A : Application> (&mut self, bindings : &Bindings <A>) {
186 self.clear_bindings();
187 self.add_bindings (bindings);
188 }
189
190 #[inline]
192 pub fn add_bindings <A : Application> (&mut self, bindings : &Bindings <A>) {
193 self.input_map.add_bindings (bindings)
194 }
195
196 #[inline]
198 pub fn insert_bindings <A : Application> (&mut self, bindings : &Bindings <A>) {
199 self.input_map.insert_bindings (bindings)
200 }
201
202 #[inline]
204 pub fn remove_bindings (&mut self, controls : &Controls) {
205 self.input_map.remove_bindings (controls)
206 }
207
208 #[inline]
209 pub fn clear_buttons (&mut self) {
210 self.input_map.buttons.clear()
211 }
212
213 #[inline]
214 pub const fn remove_any_button (&mut self) {
215 self.input_map.button_any = None
216 }
217
218 #[inline]
219 pub const fn remove_system (&mut self) {
220 self.input_map.system = None
221 }
222
223 #[inline]
224 pub const fn remove_text (&mut self) {
225 self.input_map.text = None
226 }
227
228 #[inline]
229 pub const fn remove_motion (&mut self) {
230 self.input_map.motion = None
231 }
232
233 #[inline]
234 pub const fn remove_pointer (&mut self) {
235 self.input_map.pointer = None
236 }
237
238 #[inline]
239 pub fn clear_bindings (&mut self) {
240 self.input_map.clear()
241 }
242
243 pub (crate) fn handle_input <A : Application> (&self,
244 input : Input,
245 elements : &Tree <Element>,
246 node_id : &NodeId,
247 action_buffer : &mut Vec <(NodeId, Action)>
248 ) -> Result <Option <ButtonRelease>, Input> {
249 use controls::Control;
250 log::trace!("handle_input...");
251 let mut button_release = None;
252 match &input {
253 Input::Button (button, state) => {
254 if let Component::Cursor (cursor) = &self.component &&
255 let input::button::Variant::Keycode (keycode) = button.variant &&
256 !button.modifiers.intersects (
257 input::Modifiers::ALT | input::Modifiers::CTRL | input::Modifiers::SUPER)
258 {
259 if cursor.ignore.contains (&keycode) {
260 return Err (input)
263 } else if keycode.is_printable() {
264 return Ok (None)
267 }
268 }
269 match state {
270 input::button::State::Pressed => {
271 let mut any = false;
275 if self.input_map.release_buttons
279 .binary_search_by_key (&button, |(b, _)| b).is_ok()
280 {
281 return Ok (None)
282 }
283 let control = if let Some (control) = self.input_map.button_any
284 .as_ref()
285 {
286 any = true;
287 Some (control.clone())
288 } else if let Ok (index) = self.input_map.buttons
289 .binary_search_by_key (&button, |(b, _)| b)
290 {
291 let (b, control) = &self.input_map.buttons[index];
292 if b.modifiers.contains (input::Modifiers::ANY) {
293 any = true;
294 }
295 Some (control.clone())
296 } else {
297 None
298 };
299 #[expect(clippy::unnecessary_literal_unwrap)]
300 if let Some (control) = control {
301 let release = Some (RefCell::new (SmallVec::new()));
302 control.fun::<A::ButtonControls>().0
303 (&release, elements, node_id, action_buffer);
304 let controls = release.unwrap().into_inner();
305 if !controls.is_empty() {
306 let mut button = *button;
307 if any {
308 button.modifiers.set (input::Modifiers::ANY, true);
309 }
310 button_release = Some (ButtonRelease::Insert (button, controls));
311 }
312 }
313 }
314 input::button::State::Released => {
315 let control = if let Ok (index) = self.input_map.release_buttons
316 .binary_search_by_key (&button, |(b, _)| b)
317 {
318 let (_, control) = &self.input_map.release_buttons[index];
319 Some (control.clone())
320 } else {
321 None
322 };
323 if let Some (control) = control {
324 control.fun::<A::ButtonControls>().0
325 (&None, elements, node_id, action_buffer);
326 button_release =
327 Some (ButtonRelease::Remove (*button, node_id.clone()));
328 }
329 }
330 }
331 }
332 Input::Axis (axis) => {
333 if let Ok (index) = self.input_map.axes
334 .binary_search_by_key (&axis.axis, |(a, _)| *a)
335 {
336 let (_, control) = &self.input_map.axes[index];
337 control.clone().fun::<A::AxisControls>().0
338 (&axis.value, elements, node_id, action_buffer)
339 }
340 }
341 Input::Motion (motion) => {
342 if let Some (control) = self.input_map.motion.as_ref() {
343 control.clone().fun::<A::MotionControls>().0
344 (motion, elements, node_id, action_buffer)
345 }
346 }
347 Input::Pointer (pointer) => {
348 if let Some (control) = self.input_map.pointer.as_ref() {
349 control.clone().fun::<A::PointerControls>().0
350 (pointer, elements, node_id, action_buffer)
351 }
352 }
353 Input::System (system) => {
354 if let Some (control) = self.input_map.system.as_ref() {
355 control.clone().fun::<A::SystemControls>().0
356 (system, elements, node_id, action_buffer)
357 }
358 }
359 Input::Text (text) => {
360 if let Some (control) = self.input_map.text.as_ref() {
361 control.clone().fun::<A::TextControls>().0
362 (text, elements, node_id, action_buffer)
363 }
364 }
365 Input::Wheel (wheel) => {
366 if let Some (control) = self.input_map.wheel.as_ref() {
367 control.clone().fun::<A::WheelControls>().0
368 (wheel, elements, node_id, action_buffer)
369 }
370 }
371 }
372 log::trace!("...handle_input");
373 if action_buffer.is_empty() && button_release.is_none() {
374 Err (input)
375 } else {
376 Ok (button_release)
377 }
378 }
379
380 pub (crate) fn release_buttons (&mut self) -> Vec <controls::Button> {
381 self.input_map.release_buttons.drain (..).map (|(_, control)| control)
382 .collect()
383 }
384
385 pub (crate) fn release_button_insert (&mut self,
386 input : input::Button, control : controls::Button
387 ) {
388 if self.input_map.release_buttons.insert (input, control.clone()).is_some() {
389 log::debug!("button release control already exists: {:?}",
390 (input, control));
391 }
392 }
393
394 pub (crate) fn release_button_remove (&mut self, input : input::Button) {
395 match self.input_map.release_buttons
396 .binary_search_by_key (&&input, |(b, _)| b)
397 {
398 Ok (index) => {
399 let _ = self.input_map.release_buttons.remove_index (index);
400 }
401 Err (_) => {
402 log::warn!("remove release button not present: {input:?}");
403 debug_assert!(false);
404 }
405 }
406 }
407
408 pub (crate) fn update_view_focus (&self, view : &mut View) {
409 view.appearance = self.get_appearance().clone();
410 if let view::Component::Body (body) = &mut view.component &&
411 let Component::Cursor (cursor) = &self.component
412 {
413 match self.state {
414 State::Focused => {
415 let caret = char::try_from (cursor.caret).unwrap();
416 body.0.push (caret);
417 }
418 State::Enabled => {
419 let _ = body.0.pop().unwrap();
420 }
421 State::Disabled => {}
422 }
423 }
424 }
425}
426
427impl From <Component> for Controller {
428 fn from (component : Component) -> Self {
429 Controller { component, .. Controller::default() }
430 }
431}
432
433impl From<&Input> for InputMask {
434 fn from (input : &Input) -> Self {
435 match input {
436 Input::Axis (_) => InputMask::AXIS,
437 Input::Button (_, _) => InputMask::BUTTON,
438 Input::Motion (_) => InputMask::MOTION,
439 Input::Pointer(_) => InputMask::POINTER,
440 Input::System (_) => InputMask::SYSTEM,
441 Input::Text (_) => InputMask::TEXT,
442 Input::Wheel (_) => InputMask::WHEEL
443 }
444 }
445}
446
447impl InputMap {
448 pub(crate) fn to_bindings <A : Application> (&self) -> Bindings <A> {
449 let buttons = self.buttons.iter().cloned().map (Into::into).collect();
450 let any_button = self.button_any.clone().map (Into::into);
451 let system = self.system.clone().map (Into::into);
452 let text = self.text.clone().map (Into::into);
453 let motion = self.motion.clone().map (Into::into);
454 let pointer = self.pointer.clone().map (Into::into);
455 Bindings { buttons, any_button, system, text, motion, pointer }
456 }
457
458 pub(crate) fn add_bindings <A : Application> (&mut self, bindings : &Bindings <A>) {
479 let Bindings { buttons, any_button, system, text, motion, pointer } = bindings;
480 let buttons_len = self.buttons.len();
482 let bindings_len = buttons.len();
483 self.buttons.extend (buttons.iter().cloned().map (Into::into));
484 assert_eq!(self.buttons.len(), buttons_len + bindings_len);
485 any_button.clone().map (|button| {
487 assert!(self.button_any.is_none());
488 self.button_any = Some (button.into());
489 });
490 system.clone().map (|system| {
492 assert!(self.system.is_none());
493 self.system = Some (system.into());
494 });
495 text.clone().map (|text| {
497 assert!(self.text.is_none());
498 self.text = Some (text.into());
499 });
500 motion.clone().map (|motion| {
502 assert!(self.motion.is_none());
503 self.motion = Some (motion.into());
504 });
505 pointer.clone().map (|pointer| {
507 assert!(self.pointer.is_none());
508 self.pointer = Some (pointer.into());
509 });
510 }
511
512 pub(crate) fn insert_bindings <A : Application> (&mut self, bindings : &Bindings <A>) {
514 let Bindings { buttons, any_button, system, text, motion, pointer } = bindings;
515 self.buttons.extend (buttons.iter().cloned().map (Into::into));
517 any_button.clone().map (|button| self.button_any = Some (button.into()));
519 system.clone().map (|system| self.system = Some (system.into()));
521 text.clone().map (|text| self.text = Some (text.into()));
523 motion.clone().map (|motion| self.motion = Some (motion.into()));
525 pointer.clone().map (|pointer| self.pointer = Some (pointer.into()));
527 }
528
529 pub(crate) fn remove_bindings (&mut self, controls : &Controls) {
531 let Controls { buttons, any_button, system, text, motion, pointer } = controls;
532 self.buttons.retain (|(_, button)| !buttons.contains (button));
534 if &self.button_any == any_button {
536 self.button_any = None;
537 }
538 if &self.system == system {
540 self.system = None;
541 }
542 if &self.text == text {
544 self.text = None;
545 }
546 if &self.motion == motion {
548 self.motion = None;
549 }
550 if &self.pointer == pointer {
552 self.pointer = None;
553 }
554 }
555
556 #[inline]
557 pub(crate) fn clear (&mut self) {
558 *self = InputMap::default()
559 }
560}
561
562impl <A : Application> From <&Bindings <A>> for InputMap {
563 fn from (bindings : &Bindings <A>) -> Self {
565 let Bindings { buttons, any_button, system, text, motion, pointer } = bindings;
566 let buttons = KeyVec::from_iter (buttons.iter().cloned().map (Into::into));
567 let button_any = any_button.clone().map (Into::into);
568 let system = system.clone().map (Into::into);
569 let text = text.clone().map (Into::into);
570 let motion = motion.clone().map (Into::into);
571 let pointer = pointer.clone().map (Into::into);
572 InputMap {
573 buttons, button_any, system, text, motion, pointer, .. InputMap::default()
574 }
575 }
576}
577
578impl State {
579 #[inline]
581 pub fn focus (&mut self) {
582 if self != &State::Enabled {
583 log::warn!("focus state not enabled: {self:?}");
584 }
585 debug_assert_eq!(self, &State::Enabled);
586 *self = State::Focused;
587 }
588 #[inline]
590 pub fn defocus (&mut self) {
591 if self != &State::Focused {
592 log::warn!("defocus state not focused: {self:?}");
593 }
594 debug_assert_eq!(self, &State::Focused);
595 *self = State::Enabled;
596 }
597 #[inline]
599 pub fn enable (&mut self) {
600 if self != &State::Disabled {
601 log::warn!("enable state not disabled: {self:?}");
602 }
603 debug_assert_eq!(self, &State::Disabled);
604 *self = State::Enabled;
605 }
606 #[inline]
608 pub fn disable (&mut self) {
609 if self != &State::Enabled {
610 log::warn!("disable state not enabled: {self:?}");
611 }
612 debug_assert_eq!(self, &State::Enabled);
613 *self = State::Disabled;
614 }
615}
616
617
618impl Appearances {
619 #[inline]
620 pub const fn get (&self, state : State) -> &Appearance {
621 &self.0[state as usize]
622 }
623
624 #[inline]
625 pub const fn get_mut (&mut self, state : State) -> &mut Appearance {
626 &mut self.0[state as usize]
627 }
628}
629
630impl AppearancesBuilder {
631 pub fn transparent() -> Self {
632 AppearancesBuilder::default()
633 .style_fg (State::Focused, color::TRANSPARENT.into())
634 .style_bg (State::Focused, color::TRANSPARENT.into())
635 .style_fg (State::Enabled, color::TRANSPARENT.into())
636 .style_bg (State::Enabled, color::TRANSPARENT.into())
637 .style_fg (State::Disabled, color::TRANSPARENT.into())
638 .style_bg (State::Disabled, color::TRANSPARENT.into())
639 }
640
641 #[inline]
642 pub const fn state (mut self, state : State, appearance : Appearance) -> Self {
643 self.0[state as usize] = appearance;
644 self
645 }
646 #[inline]
647 pub const fn style (mut self, state : State, style : Style) -> Self {
648 self.0[state as usize].style = Some (style);
649 self
650 }
651 #[inline]
652 pub fn style_default (mut self, state : State) -> Self {
653 self.0[state as usize].style = Some (Style::default());
654 self
655 }
656 #[inline]
657 pub const fn sound (mut self, state : State, sound : Sound) -> Self {
658 self.0[state as usize].sound = Some (sound);
659 self
660 }
661 #[inline]
662 pub const fn pointer (mut self, state : State, pointer : Pointer) -> Self {
663 self.0[state as usize].pointer = Some (pointer);
664 self
665 }
666 #[inline]
667 pub fn style_fg (mut self, state : State, color : Color) -> Self {
668 let state = state as usize;
669 let mut style = self.0[state].style.take().unwrap_or_default();
670 style.fg = color;
671 self.0[state].style = Some (style);
672 self
673 }
674 #[inline]
675 pub fn style_bg (mut self, state : State, color : Color) -> Self {
676 let state = state as usize;
677 let mut style = self.0[state].style.take().unwrap_or_default();
678 style.bg = color;
679 self.0[state].style = Some (style);
680 self
681 }
682 #[inline]
683 pub fn style_lo (mut self, state : State, color : Color) -> Self {
684 let state = state as usize;
685 let mut style = self.0[state].style.take().unwrap_or_default();
686 style.lo = color;
687 self.0[state].style = Some (style);
688 self
689 }
690 #[inline]
691 pub fn style_hi (mut self, state : State, color : Color) -> Self {
692 let state = state as usize;
693 let mut style = self.0[state].style.take().unwrap_or_default();
694 style.hi = color;
695 self.0[state].style = Some (style);
696 self
697 }
698 #[inline]
699 pub const fn build (self) -> Appearances {
700 Appearances (self.0)
701 }
702}
703
704
705impl Orientation {
706 pub const fn toggle (self) -> Self {
707 match self {
708 Orientation::Horizontal => Orientation::Vertical,
709 Orientation::Vertical => Orientation::Horizontal
710 }
711 }
712}
713