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
}