1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//! Primitives for handling and sending events.

mod channel;
pub mod handler;

pub use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind};

pub use self::channel::{quit, re_render};
pub(crate) use self::channel::{read, start_crossterm_events};
use self::handler::Handler;
#[cfg(doc)]
use self::handler::Propagate;
use crate::terminal::Rect;

pub(crate) enum Event {
  Mouse(MouseEvent),
  Key(KeyEvent),
  Render,
  Quit,
}

/// A handler for [`KeyEvent`]s.
///
/// # Creating a `KeyHandler`
///
/// A `KeyHandler` is used to manipulate closures or functions that take in a
/// [`KeyEvent`] as a parameter, and return a [`Propagate`]. `KeyHandler`s are often
/// created using the [`on_key!`] macro. For example,
/// ```rust
/// # use intuitive::{component, components::Text, render, on_key, state::use_state};
/// #
/// #[component(Root)]
/// fn render() {
///   let text = use_state(|| String::new());
///
///   let on_key = on_key! { [text]
///     KeyEvent { code: Char(c), .. } => text.mutate(|text| text.push(c)),
///   };
///
///   render! {
///     Text(text: format!("Hi There {}", text.get()), on_key)
///   }
/// }
/// ```
///
/// # Using a `KeyHandler`
///
/// A [`KeyEvent`] can be handled by a `KeyHandler` through the [`Handler::handle`]
/// method. `KeyHandler` implements [`Default`], and the default handler ignores the
/// `KeyEvent`, and always returns [`Propagate`]`::Next`.
///
/// Typically, components want to take some default action when implementing
/// `on_key`, but allow the user of this component to override this handler. This can
/// be done using the [`KeyHandler::handle_or`] method:
/// ```rust
/// # use intuitive::{element::Element, event::{KeyHandler, KeyEvent}};
/// #
/// struct Frozen {
///   on_key: KeyHandler,
/// }
///
/// impl Element for Frozen {
///   fn on_key(&self, event: KeyEvent) {
///     self.on_key.handle_or(event, |event| { /* default functionality here */ })
///   }
/// }
/// ```
/// Here, `Frozen::on_key` calls the handler that was provided if one was. If no
/// `KeyHandler` was provided, then `self.on_key` is the default handler,
/// which always returns [`Propagate`]`::Next`. This causes the closure above to
/// be executed.
///
/// # Propagation
///
/// A user of a component can control when the default key handler is run by
/// returning one of [`Propagate`]`::{Next, Stop}`. For example, to create an
/// input box that receives input keys, but quits on the escape key:
/// ```rust
/// # use intuitive::{component, components::experimental::input::Input, render, on_key, state::use_state};
/// #
/// #[component(Root)]
/// fn render() {
///   let text = use_state(|| String::new);
///
///   let on_key = on_key! { [text]
///     KeyEvent { code: Esc, .. } => event::quit(),
///
///     _ => return Propagate::Next,
///   };
///
///   render! {
///     Input(on_key)
///   }
/// }
/// ```
/// This will cause all key events other than `Esc` to be handled by `Input`'s
/// default key handler.
///
/// [`on_key!`]: ../macro.on_key.html
/// [`Handler::handle_or`]: handler/struct.Handler.html#method.handle_or
/// [`State`]: ../state/struct.State.html
/// [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
pub type KeyHandler = Handler<KeyEvent>;

/// A handler for [`MouseEvent`]s.
pub type MouseHandler = Handler<MouseEvent>;

/// Check if a mouse event is within a [`Rect`].
pub fn is_within(event: &MouseEvent, rect: Rect) -> bool {
  let (x, y) = (event.column, event.row);

  let x_within = rect.x <= x && x <= rect.x + rect.width;
  let y_within = rect.y <= y && y <= rect.y + rect.height;

  x_within && y_within
}