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 pub(crate) 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)]
112pub(crate) struct 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.as_ref() {
284 any = true;
285 Some (control)
286 } else if let Ok (index) = self.input_map.buttons
287 .binary_search_by_key (&button, |(b, _)| b)
288 {
289 let (b, control) = &self.input_map.buttons[index];
293 if b.modifiers.contains (input::Modifiers::ANY) {
294 any = true;
295 }
296 Some (control)
297 } else {
298 None
299 };
300 #[expect(clippy::unnecessary_literal_unwrap)]
301 if let Some (control) = control {
302 let release = Some (RefCell::new (SmallVec::new()));
303 control.fun::<A::ButtonControls>().0
304 (&release, elements, node_id, action_buffer);
305 let controls = release.unwrap().into_inner();
306 if !controls.is_empty() {
307 let mut button = *button;
308 if any {
309 button.modifiers.set (input::Modifiers::ANY, true);
310 }
311 button_release = Some (ButtonRelease::Insert (button, controls));
312 }
313 }
314 }
315 input::button::State::Released => {
316 let control = if let Ok (index) = self.input_map.release_buttons
317 .binary_search_by_key (&button, |(b, _)| b)
318 {
319 let (_, control) = &self.input_map.release_buttons[index];
320 Some (control)
321 } else {
322 None
323 };
324 if let Some (control) = control {
325 control.fun::<A::ButtonControls>().0
326 (&None, elements, node_id, action_buffer);
327 button_release =
328 Some (ButtonRelease::Remove (*button, node_id.clone()));
329 }
330 }
331 }
332 }
333 Input::Axis (axis) => {
334 if let Ok (index) = self.input_map.axes
335 .binary_search_by_key (&axis.axis, |(a, _)| *a)
336 {
337 let (_, control) = &self.input_map.axes[index];
338 control.fun::<A::AxisControls>().0
339 (&axis.value, elements, node_id, action_buffer)
340 }
341 }
342 Input::Motion (motion) => {
343 if let Some (control) = self.input_map.motion.as_ref() {
344 control.fun::<A::MotionControls>().0
345 (motion, elements, node_id, action_buffer)
346 }
347 }
348 Input::Pointer (pointer) => {
349 if let Some (control) = self.input_map.pointer.as_ref() {
350 control.fun::<A::PointerControls>().0
351 (pointer, elements, node_id, action_buffer)
352 }
353 }
354 Input::System (system) => {
355 if let Some (control) = self.input_map.system.as_ref() {
356 control.fun::<A::SystemControls>().0
357 (system, elements, node_id, action_buffer)
358 }
359 }
360 Input::Text (text) => {
361 if let Some (control) = self.input_map.text.as_ref() {
362 control.fun::<A::TextControls>().0
363 (text, elements, node_id, action_buffer)
364 }
365 }
366 Input::Wheel (wheel) => {
367 if let Some (control) = self.input_map.wheel.as_ref() {
368 control.fun::<A::WheelControls>().0
369 (wheel, elements, node_id, action_buffer)
370 }
371 }
372 }
373 log::trace!("...handle_input");
374 if action_buffer.is_empty() && button_release.is_none() {
375 Err (input)
376 } else {
377 Ok (button_release)
378 }
379 }
380
381 pub (crate) fn release_buttons (&mut self) -> Vec <controls::Button> {
382 self.input_map.release_buttons.drain (..).map (|(_, control)| control)
383 .collect()
384 }
385
386 pub (crate) fn release_button_insert (&mut self,
387 input : input::Button, control : controls::Button
388 ) {
389 if self.input_map.release_buttons.insert (input, control).is_some() {
390 log::debug!("button release control already exists: {:?}", (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().copied()
450 .map (|(button, control)| controls::button::Binding::new (control.into(), button))
451 .collect();
452 let any_button = self.button_any.map (Into::into);
453 let system = self.system.map (Into::into);
454 let text = self.text.map (Into::into);
455 let motion = self.motion.map (Into::into);
456 let pointer = self.pointer.map (Into::into);
457 Bindings { buttons, any_button, system, text, motion, pointer }
458 }
459
460 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().map (|binding| (binding.1, binding.0.0)));
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().map (|binding| (binding.1, binding.0.0)));
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()
567 .map (|binding| (binding.1, binding.0.0)));
568 let button_any = any_button.clone().map (Into::into);
569 let system = system.clone().map (Into::into);
570 let text = text.clone().map (Into::into);
571 let motion = motion.clone().map (Into::into);
572 let pointer = pointer.clone().map (Into::into);
573 InputMap {
574 buttons, button_any, system, text, motion, pointer, .. InputMap::default()
575 }
576 }
577}
578
579impl State {
580 #[inline]
582 pub fn focus (&mut self) {
583 if self != &State::Enabled {
584 log::warn!("focus state not enabled: {self:?}");
585 }
586 debug_assert_eq!(self, &State::Enabled);
587 *self = State::Focused;
588 }
589 #[inline]
591 pub fn defocus (&mut self) {
592 if self != &State::Focused {
593 log::warn!("defocus state not focused: {self:?}");
594 }
595 debug_assert_eq!(self, &State::Focused);
596 *self = State::Enabled;
597 }
598 #[inline]
600 pub fn enable (&mut self) {
601 if self != &State::Disabled {
602 log::warn!("enable state not disabled: {self:?}");
603 }
604 debug_assert_eq!(self, &State::Disabled);
605 *self = State::Enabled;
606 }
607 #[inline]
609 pub fn disable (&mut self) {
610 if self != &State::Enabled {
611 log::warn!("disable state not enabled: {self:?}");
612 }
613 debug_assert_eq!(self, &State::Enabled);
614 *self = State::Disabled;
615 }
616}
617
618
619impl Appearances {
620 #[inline]
621 pub const fn get (&self, state : State) -> &Appearance {
622 &self.0[state as usize]
623 }
624
625 #[inline]
626 pub const fn get_mut (&mut self, state : State) -> &mut Appearance {
627 &mut self.0[state as usize]
628 }
629}
630
631impl AppearancesBuilder {
632 pub fn transparent() -> Self {
633 AppearancesBuilder::default()
634 .style_fg (State::Focused, Color::TRANSPARENT)
635 .style_bg (State::Focused, Color::TRANSPARENT)
636 .style_fg (State::Enabled, Color::TRANSPARENT)
637 .style_bg (State::Enabled, Color::TRANSPARENT)
638 .style_fg (State::Disabled, Color::TRANSPARENT)
639 .style_bg (State::Disabled, Color::TRANSPARENT)
640 }
641
642 #[inline]
643 pub const fn state (mut self, state : State, appearance : Appearance) -> Self {
644 self.0[state as usize] = appearance;
645 self
646 }
647 #[inline]
648 pub const fn style (mut self, state : State, style : Style) -> Self {
649 self.0[state as usize].style = Some (style);
650 self
651 }
652 #[inline]
653 pub fn style_default (mut self, state : State) -> Self {
654 self.0[state as usize].style = Some (Style::default());
655 self
656 }
657 #[inline]
658 pub const fn sound (mut self, state : State, sound : Sound) -> Self {
659 self.0[state as usize].sound = Some (sound);
660 self
661 }
662 #[inline]
663 pub const fn pointer (mut self, state : State, pointer : Pointer) -> Self {
664 self.0[state as usize].pointer = Some (pointer);
665 self
666 }
667 #[inline]
668 pub fn style_fg (mut self, state : State, color : Color) -> Self {
669 let state = state as usize;
670 let mut style = self.0[state].style.take().unwrap_or_default();
671 style.fg = color;
672 self.0[state].style = Some (style);
673 self
674 }
675 #[inline]
676 pub fn style_bg (mut self, state : State, color : Color) -> Self {
677 let state = state as usize;
678 let mut style = self.0[state].style.take().unwrap_or_default();
679 style.bg = color;
680 self.0[state].style = Some (style);
681 self
682 }
683 #[inline]
684 pub fn style_lo (mut self, state : State, color : Color) -> Self {
685 let state = state as usize;
686 let mut style = self.0[state].style.take().unwrap_or_default();
687 style.lo = color;
688 self.0[state].style = Some (style);
689 self
690 }
691 #[inline]
692 pub fn style_hi (mut self, state : State, color : Color) -> Self {
693 let state = state as usize;
694 let mut style = self.0[state].style.take().unwrap_or_default();
695 style.hi = color;
696 self.0[state].style = Some (style);
697 self
698 }
699 #[inline]
700 pub const fn build (self) -> Appearances {
701 Appearances (self.0)
702 }
703}
704
705
706impl Orientation {
707 pub const fn toggle (self) -> Self {
708 match self {
709 Orientation::Horizontal => Orientation::Vertical,
710 Orientation::Vertical => Orientation::Horizontal
711 }
712 }
713}
714