1#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum Event {
17 Key(KeyEvent),
19 Mouse(MouseEvent),
21 Resize(u32, u32),
23 Paste(String),
25 FocusGained,
27 FocusLost,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct KeyEvent {
34 pub code: KeyCode,
36 pub modifiers: KeyModifiers,
38 pub kind: KeyEventKind,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum KeyEventKind {
45 Press,
47 Release,
49 Repeat,
51}
52
53#[derive(Debug, Clone, PartialEq, Eq)]
59pub enum KeyCode {
60 Char(char),
62 Enter,
64 Backspace,
66 Tab,
68 BackTab,
70 Esc,
72 Up,
74 Down,
76 Left,
78 Right,
80 Home,
82 End,
84 PageUp,
86 PageDown,
88 Delete,
90 F(u8),
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
99pub struct KeyModifiers(pub u8);
100
101impl KeyModifiers {
102 pub const NONE: Self = Self(0);
104 pub const SHIFT: Self = Self(1 << 0);
106 pub const CONTROL: Self = Self(1 << 1);
108 pub const ALT: Self = Self(1 << 2);
110
111 #[inline]
113 pub fn contains(self, other: Self) -> bool {
114 (self.0 & other.0) == other.0
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq)]
124pub struct MouseEvent {
125 pub kind: MouseKind,
127 pub x: u32,
129 pub y: u32,
131 pub modifiers: KeyModifiers,
133}
134
135#[derive(Debug, Clone, PartialEq, Eq)]
137pub enum MouseKind {
138 Down(MouseButton),
140 Up(MouseButton),
142 Drag(MouseButton),
144 ScrollUp,
146 ScrollDown,
148 Moved,
150}
151
152#[derive(Debug, Clone, Copy, PartialEq, Eq)]
154pub enum MouseButton {
155 Left,
157 Right,
159 Middle,
161}
162
163fn convert_modifiers(modifiers: crossterm::event::KeyModifiers) -> KeyModifiers {
164 let mut out = KeyModifiers::NONE;
165 if modifiers.contains(crossterm::event::KeyModifiers::SHIFT) {
166 out.0 |= KeyModifiers::SHIFT.0;
167 }
168 if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) {
169 out.0 |= KeyModifiers::CONTROL.0;
170 }
171 if modifiers.contains(crossterm::event::KeyModifiers::ALT) {
172 out.0 |= KeyModifiers::ALT.0;
173 }
174 out
175}
176
177fn convert_button(button: crossterm::event::MouseButton) -> MouseButton {
178 match button {
179 crossterm::event::MouseButton::Left => MouseButton::Left,
180 crossterm::event::MouseButton::Right => MouseButton::Right,
181 crossterm::event::MouseButton::Middle => MouseButton::Middle,
182 }
183}
184
185pub(crate) fn from_crossterm(raw: crossterm::event::Event) -> Option<Event> {
190 match raw {
191 crossterm::event::Event::Key(k) => {
192 let code = match k.code {
193 crossterm::event::KeyCode::Char(c) => KeyCode::Char(c),
194 crossterm::event::KeyCode::Enter => KeyCode::Enter,
195 crossterm::event::KeyCode::Backspace => KeyCode::Backspace,
196 crossterm::event::KeyCode::Tab => KeyCode::Tab,
197 crossterm::event::KeyCode::BackTab => KeyCode::BackTab,
198 crossterm::event::KeyCode::Esc => KeyCode::Esc,
199 crossterm::event::KeyCode::Up => KeyCode::Up,
200 crossterm::event::KeyCode::Down => KeyCode::Down,
201 crossterm::event::KeyCode::Left => KeyCode::Left,
202 crossterm::event::KeyCode::Right => KeyCode::Right,
203 crossterm::event::KeyCode::Home => KeyCode::Home,
204 crossterm::event::KeyCode::End => KeyCode::End,
205 crossterm::event::KeyCode::PageUp => KeyCode::PageUp,
206 crossterm::event::KeyCode::PageDown => KeyCode::PageDown,
207 crossterm::event::KeyCode::Delete => KeyCode::Delete,
208 crossterm::event::KeyCode::F(n) => KeyCode::F(n),
209 _ => return None,
210 };
211 let modifiers = convert_modifiers(k.modifiers);
212 let kind = match k.kind {
213 crossterm::event::KeyEventKind::Press => KeyEventKind::Press,
214 crossterm::event::KeyEventKind::Repeat => KeyEventKind::Repeat,
215 crossterm::event::KeyEventKind::Release => KeyEventKind::Release,
216 };
217 Some(Event::Key(KeyEvent {
218 code,
219 modifiers,
220 kind,
221 }))
222 }
223 crossterm::event::Event::Mouse(m) => {
224 let kind = match m.kind {
225 crossterm::event::MouseEventKind::Down(btn) => MouseKind::Down(convert_button(btn)),
226 crossterm::event::MouseEventKind::Up(btn) => MouseKind::Up(convert_button(btn)),
227 crossterm::event::MouseEventKind::Drag(btn) => MouseKind::Drag(convert_button(btn)),
228 crossterm::event::MouseEventKind::Moved => MouseKind::Moved,
229 crossterm::event::MouseEventKind::ScrollUp => MouseKind::ScrollUp,
230 crossterm::event::MouseEventKind::ScrollDown => MouseKind::ScrollDown,
231 _ => return None,
232 };
233
234 Some(Event::Mouse(MouseEvent {
235 kind,
236 x: m.column as u32,
237 y: m.row as u32,
238 modifiers: convert_modifiers(m.modifiers),
239 }))
240 }
241 crossterm::event::Event::Resize(cols, rows) => {
242 Some(Event::Resize(cols as u32, rows as u32))
243 }
244 crossterm::event::Event::Paste(s) => Some(Event::Paste(s)),
245 crossterm::event::Event::FocusGained => Some(Event::FocusGained),
246 crossterm::event::Event::FocusLost => Some(Event::FocusLost),
247 }
248}