1#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum Event {
8 Key(KeyEvent),
10 Mouse(MouseEvent),
12 Resize(u32, u32),
14 Paste(String),
16 FocusGained,
18 FocusLost,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct KeyEvent {
25 pub code: KeyCode,
27 pub modifiers: KeyModifiers,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum KeyCode {
38 Char(char),
40 Enter,
42 Backspace,
44 Tab,
46 BackTab,
48 Esc,
50 Up,
52 Down,
54 Left,
56 Right,
58 Home,
60 End,
62 PageUp,
64 PageDown,
66 Delete,
68 F(u8),
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
77pub struct KeyModifiers(pub u8);
78
79impl KeyModifiers {
80 pub const NONE: Self = Self(0);
82 pub const SHIFT: Self = Self(1 << 0);
84 pub const CONTROL: Self = Self(1 << 1);
86 pub const ALT: Self = Self(1 << 2);
88
89 #[inline]
91 pub fn contains(self, other: Self) -> bool {
92 (self.0 & other.0) == other.0
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct MouseEvent {
103 pub kind: MouseKind,
105 pub x: u32,
107 pub y: u32,
109 pub modifiers: KeyModifiers,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
115pub enum MouseKind {
116 Down(MouseButton),
118 Up(MouseButton),
120 Drag(MouseButton),
122 ScrollUp,
124 ScrollDown,
126 Moved,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132pub enum MouseButton {
133 Left,
135 Right,
137 Middle,
139}
140
141fn convert_modifiers(modifiers: crossterm::event::KeyModifiers) -> KeyModifiers {
142 let mut out = KeyModifiers::NONE;
143 if modifiers.contains(crossterm::event::KeyModifiers::SHIFT) {
144 out.0 |= KeyModifiers::SHIFT.0;
145 }
146 if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) {
147 out.0 |= KeyModifiers::CONTROL.0;
148 }
149 if modifiers.contains(crossterm::event::KeyModifiers::ALT) {
150 out.0 |= KeyModifiers::ALT.0;
151 }
152 out
153}
154
155fn convert_button(button: crossterm::event::MouseButton) -> MouseButton {
156 match button {
157 crossterm::event::MouseButton::Left => MouseButton::Left,
158 crossterm::event::MouseButton::Right => MouseButton::Right,
159 crossterm::event::MouseButton::Middle => MouseButton::Middle,
160 }
161}
162
163pub(crate) fn from_crossterm(raw: crossterm::event::Event) -> Option<Event> {
168 match raw {
169 crossterm::event::Event::Key(k) => {
170 if k.kind != crossterm::event::KeyEventKind::Press {
172 return None;
173 }
174 let code = match k.code {
175 crossterm::event::KeyCode::Char(c) => KeyCode::Char(c),
176 crossterm::event::KeyCode::Enter => KeyCode::Enter,
177 crossterm::event::KeyCode::Backspace => KeyCode::Backspace,
178 crossterm::event::KeyCode::Tab => KeyCode::Tab,
179 crossterm::event::KeyCode::BackTab => KeyCode::BackTab,
180 crossterm::event::KeyCode::Esc => KeyCode::Esc,
181 crossterm::event::KeyCode::Up => KeyCode::Up,
182 crossterm::event::KeyCode::Down => KeyCode::Down,
183 crossterm::event::KeyCode::Left => KeyCode::Left,
184 crossterm::event::KeyCode::Right => KeyCode::Right,
185 crossterm::event::KeyCode::Home => KeyCode::Home,
186 crossterm::event::KeyCode::End => KeyCode::End,
187 crossterm::event::KeyCode::PageUp => KeyCode::PageUp,
188 crossterm::event::KeyCode::PageDown => KeyCode::PageDown,
189 crossterm::event::KeyCode::Delete => KeyCode::Delete,
190 crossterm::event::KeyCode::F(n) => KeyCode::F(n),
191 _ => return None,
192 };
193 let modifiers = convert_modifiers(k.modifiers);
194 Some(Event::Key(KeyEvent { code, modifiers }))
195 }
196 crossterm::event::Event::Mouse(m) => {
197 let kind = match m.kind {
198 crossterm::event::MouseEventKind::Down(btn) => MouseKind::Down(convert_button(btn)),
199 crossterm::event::MouseEventKind::Up(btn) => MouseKind::Up(convert_button(btn)),
200 crossterm::event::MouseEventKind::Drag(btn) => MouseKind::Drag(convert_button(btn)),
201 crossterm::event::MouseEventKind::Moved => MouseKind::Moved,
202 crossterm::event::MouseEventKind::ScrollUp => MouseKind::ScrollUp,
203 crossterm::event::MouseEventKind::ScrollDown => MouseKind::ScrollDown,
204 _ => return None,
205 };
206
207 Some(Event::Mouse(MouseEvent {
208 kind,
209 x: m.column as u32,
210 y: m.row as u32,
211 modifiers: convert_modifiers(m.modifiers),
212 }))
213 }
214 crossterm::event::Event::Resize(cols, rows) => {
215 Some(Event::Resize(cols as u32, rows as u32))
216 }
217 crossterm::event::Event::Paste(s) => Some(Event::Paste(s)),
218 crossterm::event::Event::FocusGained => Some(Event::FocusGained),
219 crossterm::event::Event::FocusLost => Some(Event::FocusLost),
220 }
221}