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}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
46pub enum KeyCode {
47 Char(char),
49 Enter,
51 Backspace,
53 Tab,
55 BackTab,
57 Esc,
59 Up,
61 Down,
63 Left,
65 Right,
67 Home,
69 End,
71 PageUp,
73 PageDown,
75 Delete,
77 F(u8),
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
86pub struct KeyModifiers(pub u8);
87
88impl KeyModifiers {
89 pub const NONE: Self = Self(0);
91 pub const SHIFT: Self = Self(1 << 0);
93 pub const CONTROL: Self = Self(1 << 1);
95 pub const ALT: Self = Self(1 << 2);
97
98 #[inline]
100 pub fn contains(self, other: Self) -> bool {
101 (self.0 & other.0) == other.0
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct MouseEvent {
112 pub kind: MouseKind,
114 pub x: u32,
116 pub y: u32,
118 pub modifiers: KeyModifiers,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
124pub enum MouseKind {
125 Down(MouseButton),
127 Up(MouseButton),
129 Drag(MouseButton),
131 ScrollUp,
133 ScrollDown,
135 Moved,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq)]
141pub enum MouseButton {
142 Left,
144 Right,
146 Middle,
148}
149
150fn convert_modifiers(modifiers: crossterm::event::KeyModifiers) -> KeyModifiers {
151 let mut out = KeyModifiers::NONE;
152 if modifiers.contains(crossterm::event::KeyModifiers::SHIFT) {
153 out.0 |= KeyModifiers::SHIFT.0;
154 }
155 if modifiers.contains(crossterm::event::KeyModifiers::CONTROL) {
156 out.0 |= KeyModifiers::CONTROL.0;
157 }
158 if modifiers.contains(crossterm::event::KeyModifiers::ALT) {
159 out.0 |= KeyModifiers::ALT.0;
160 }
161 out
162}
163
164fn convert_button(button: crossterm::event::MouseButton) -> MouseButton {
165 match button {
166 crossterm::event::MouseButton::Left => MouseButton::Left,
167 crossterm::event::MouseButton::Right => MouseButton::Right,
168 crossterm::event::MouseButton::Middle => MouseButton::Middle,
169 }
170}
171
172pub(crate) fn from_crossterm(raw: crossterm::event::Event) -> Option<Event> {
177 match raw {
178 crossterm::event::Event::Key(k) => {
179 if k.kind != crossterm::event::KeyEventKind::Press {
181 return None;
182 }
183 let code = match k.code {
184 crossterm::event::KeyCode::Char(c) => KeyCode::Char(c),
185 crossterm::event::KeyCode::Enter => KeyCode::Enter,
186 crossterm::event::KeyCode::Backspace => KeyCode::Backspace,
187 crossterm::event::KeyCode::Tab => KeyCode::Tab,
188 crossterm::event::KeyCode::BackTab => KeyCode::BackTab,
189 crossterm::event::KeyCode::Esc => KeyCode::Esc,
190 crossterm::event::KeyCode::Up => KeyCode::Up,
191 crossterm::event::KeyCode::Down => KeyCode::Down,
192 crossterm::event::KeyCode::Left => KeyCode::Left,
193 crossterm::event::KeyCode::Right => KeyCode::Right,
194 crossterm::event::KeyCode::Home => KeyCode::Home,
195 crossterm::event::KeyCode::End => KeyCode::End,
196 crossterm::event::KeyCode::PageUp => KeyCode::PageUp,
197 crossterm::event::KeyCode::PageDown => KeyCode::PageDown,
198 crossterm::event::KeyCode::Delete => KeyCode::Delete,
199 crossterm::event::KeyCode::F(n) => KeyCode::F(n),
200 _ => return None,
201 };
202 let modifiers = convert_modifiers(k.modifiers);
203 Some(Event::Key(KeyEvent { code, modifiers }))
204 }
205 crossterm::event::Event::Mouse(m) => {
206 let kind = match m.kind {
207 crossterm::event::MouseEventKind::Down(btn) => MouseKind::Down(convert_button(btn)),
208 crossterm::event::MouseEventKind::Up(btn) => MouseKind::Up(convert_button(btn)),
209 crossterm::event::MouseEventKind::Drag(btn) => MouseKind::Drag(convert_button(btn)),
210 crossterm::event::MouseEventKind::Moved => MouseKind::Moved,
211 crossterm::event::MouseEventKind::ScrollUp => MouseKind::ScrollUp,
212 crossterm::event::MouseEventKind::ScrollDown => MouseKind::ScrollDown,
213 _ => return None,
214 };
215
216 Some(Event::Mouse(MouseEvent {
217 kind,
218 x: m.column as u32,
219 y: m.row as u32,
220 modifiers: convert_modifiers(m.modifiers),
221 }))
222 }
223 crossterm::event::Event::Resize(cols, rows) => {
224 Some(Event::Resize(cols as u32, rows as u32))
225 }
226 crossterm::event::Event::Paste(s) => Some(Event::Paste(s)),
227 crossterm::event::Event::FocusGained => Some(Event::FocusGained),
228 crossterm::event::Event::FocusLost => Some(Event::FocusLost),
229 }
230}