termit 0.7.0

Terminal UI over crossterm
Documentation
//! The input event model

use crate::prelude::Point;
use std::collections::HashSet;

/// The AppEvent is an extension point in termit so that
/// you can include your application specific event stream
/// in the input processing.
///
/// This is handy because the additional included stream are executed
/// in parallel with the terminal input and thus provide cheap
/// parallelism to process your application heavy duty async tasks.
///
/// AppEvent is implemented for anything that fulfils the generic [`Event`]
/// requirements.
pub trait AppEvent: std::fmt::Debug + PartialEq + Unpin + 'static {}
impl<T> AppEvent for T where T: std::fmt::Debug + PartialEq + Unpin + 'static {}

/// The main input entity extensible with application specific [`AppEvent`]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event<A: AppEvent = ()> {
    Key(KeyEvent),
    Focus(bool),
    CursorPosition(Point),
    Resize(Point),
    Mouse(MouseEvent),
    Paste(String),
    Unknown(Vec<u8>),
    /// Refresh with n beats passed
    Refresh(usize),
    /// Application specific event
    App(A),
    /// The terminal input has been closed.
    /// This may be a signal to terminate the app (or not)
    InputClosed,
}
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyCode {
    Esc,
    Left,
    Right,
    Up,
    Down,
    Home,
    End,
    F(u8),
    BackTab,
    Enter,
    Tab,
    Backspace,
    Char(char),
    Insert,
    Delete,
    PageUp,
    PageDown,
    KeypadBegin,
    CapsLock,
    ScrollLock,
    NumLock,
    PrintScreen,
    Pause,
    Menu,
    Media(MediaKeyCode),
    Modifier(ModifierKeyCode),
}
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq)]
pub enum MediaKeyCode {
    Play,
    Pause,
    PlayPause,
    Reverse,
    Stop,
    FastForward,
    Rewind,
    TrackNext,
    TrackPrevious,
    Record,
    LowerVolume,
    RaiseVolume,
    MuteVolume,
}
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModifierKeyCode {
    LeftShift,
    LeftControl,
    LeftAlt,
    LeftSuper,
    LeftHyper,
    LeftMeta,
    RightShift,
    RightControl,
    RightAlt,
    RightSuper,
    RightHyper,
    RightMeta,
    IsoLevel3Shift,
    IsoLevel5Shift,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KeyEvent {
    pub keycode: KeyCode,
    pub kind: KeyEventKind,
    pub modifiers: KeyModifiers,
    pub state: KeyEventStates,
}
impl KeyEvent {
    pub(crate) fn new(
        keycode: KeyCode,
        modifiers: impl IntoIterator<Item = KeyModifier>,
    ) -> KeyEvent {
        KeyEvent::new_with_kind(keycode, modifiers, KeyEventKind::Press)
    }

    pub(crate) fn new_with_kind(
        keycode: KeyCode,
        modifiers: impl IntoIterator<Item = KeyModifier>,
        kind: KeyEventKind,
    ) -> KeyEvent {
        KeyEvent::new_with_kind_and_state(keycode, modifiers, kind, None)
    }

    pub(crate) fn new_with_kind_and_state(
        keycode: KeyCode,
        modifiers: impl IntoIterator<Item = KeyModifier>,
        kind: KeyEventKind,
        state: impl IntoIterator<Item = KeyEventState>,
    ) -> KeyEvent {
        KeyEvent {
            keycode,
            modifiers: modifiers.into_iter().collect(),
            kind,
            state: state.into_iter().collect(),
        }
    }
}
impl From<KeyCode> for KeyEvent {
    /// converts KeyCode to KeyEvent (adds shift modifier in case of uppercase characters)
    fn from(keycode: KeyCode) -> Self {
        let modifiers = match keycode {
            KeyCode::Char(c) if c.is_uppercase() => Some(KeyModifier::Shift),
            _ => None,
        };
        KeyEvent::new(keycode, modifiers)
    }
}
pub type KeyModifiers = HashSet<KeyModifier>;
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyModifier {
    Alt,
    Control,
    Shift,
    Super,
    Hyper,
    Meta,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum KeyEventKind {
    Press,
    Release,
    Repeat,
}
pub type KeyEventStates = HashSet<KeyEventState>;

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum KeyEventState {
    CapsLock,
    NumLock,
    Keypad,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum MouseButton {
    Left,
    Middle,
    Right,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MouseEvent {
    pub column: u16,
    pub row: u16,
    pub kind: MouseEventKind,
    pub modifiers: KeyModifiers,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum MouseEventKind {
    Moved,
    Up(MouseButton),
    Drag(MouseButton),
    Down(MouseButton),
    ScrollDown,
    ScrollUp,
}