Skip to main content

ratatui_hypertile/
input.rs

1use ratatui::layout::Direction;
2use std::ops::{BitOr, BitOrAssign};
3
4/// Event delivered to the layout engine or runtime.
5#[derive(Debug, Clone, Copy, PartialEq)]
6pub enum HypertileEvent {
7    Key(KeyChord),
8    Action(HypertileAction),
9    Tick,
10}
11
12/// Backend-agnostic key code.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum KeyCode {
15    Char(char),
16    Enter,
17    Escape,
18    Tab,
19    BackTab,
20    Backspace,
21    Home,
22    End,
23    PageUp,
24    PageDown,
25    Delete,
26    Insert,
27    F(u8),
28    Up,
29    Down,
30    Left,
31    Right,
32}
33
34/// Modifier keys.
35///
36/// ```
37/// use ratatui_hypertile::Modifiers;
38///
39/// let combo = Modifiers::SHIFT | Modifiers::CTRL;
40/// assert!(combo.contains(Modifiers::SHIFT));
41/// ```
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
43pub struct Modifiers(u8);
44
45impl Modifiers {
46    pub const NONE: Self = Self(0);
47    pub const SHIFT: Self = Self(1 << 0);
48    pub const CTRL: Self = Self(1 << 1);
49    pub const ALT: Self = Self(1 << 2);
50
51    pub fn contains(self, other: Self) -> bool {
52        (self.0 & other.0) == other.0
53    }
54
55    pub fn is_empty(self) -> bool {
56        self.0 == 0
57    }
58}
59
60impl BitOr for Modifiers {
61    type Output = Self;
62
63    fn bitor(self, rhs: Self) -> Self::Output {
64        Self(self.0 | rhs.0)
65    }
66}
67
68impl BitOrAssign for Modifiers {
69    fn bitor_assign(&mut self, rhs: Self) {
70        self.0 |= rhs.0;
71    }
72}
73
74/// Key code plus modifiers.
75///
76/// ```
77/// use ratatui_hypertile::{KeyChord, KeyCode, Modifiers};
78///
79/// let chord = KeyChord::with_modifiers(KeyCode::Char('h'), Modifiers::CTRL);
80/// ```
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct KeyChord {
83    pub code: KeyCode,
84    pub modifiers: Modifiers,
85}
86
87impl KeyChord {
88    pub const fn new(code: KeyCode) -> Self {
89        Self {
90            code,
91            modifiers: Modifiers::NONE,
92        }
93    }
94
95    pub const fn with_modifiers(code: KeyCode, modifiers: Modifiers) -> Self {
96        Self { code, modifiers }
97    }
98}
99
100/// `Start` means left or up. `End` means right or down.
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
102pub enum Towards {
103    Start,
104    End,
105}
106
107/// How pane moves are resolved.
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109pub enum MoveScope {
110    /// Swap with the nearest pane in that direction.
111    Window,
112    /// Swap inside the nearest ancestor split on that axis.
113    Split,
114}
115
116/// Command understood by [`crate::Hypertile`].
117#[derive(Debug, Clone, Copy, PartialEq)]
118pub enum HypertileAction {
119    FocusNext,
120    FocusPrev,
121    FocusDirection {
122        direction: Direction,
123        towards: Towards,
124    },
125    SplitFocused {
126        direction: Direction,
127    },
128    CloseFocused,
129    ResizeFocused {
130        delta: f32,
131    },
132    SetFocusedRatio {
133        ratio: f32,
134    },
135    MoveFocused {
136        direction: Direction,
137        towards: Towards,
138        scope: MoveScope,
139    },
140}
141
142/// Whether an event handler consumed an event.
143#[derive(Debug, Clone, Copy, PartialEq, Eq)]
144pub enum EventOutcome {
145    Ignored,
146    Consumed,
147}
148
149impl EventOutcome {
150    pub fn is_consumed(self) -> bool {
151        matches!(self, Self::Consumed)
152    }
153}