terminput_egui/
lib.rs

1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4use terminput::{
5    Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers, MouseButton, MouseEvent,
6    MouseEventKind, ScrollDirection, UnsupportedEvent,
7};
8
9/// Converts the egui [event](egui::Event) to a terminput [event](Event).
10pub fn to_terminput(value: egui::Event) -> Result<Event, UnsupportedEvent> {
11    match value {
12        egui::Event::Paste(text) => Ok(Event::Paste(text)),
13        egui::Event::Text(_) => Err(UnsupportedEvent(format!("{value:?}"))),
14        egui::Event::Key {
15            key,
16            physical_key: _,
17            pressed,
18            repeat,
19            modifiers,
20        } => Ok(Event::Key(KeyEvent {
21            code: key_code_to_terminput(key)?,
22            modifiers: key_modifiers_to_terminput(modifiers),
23            kind: if repeat {
24                KeyEventKind::Repeat
25            } else if pressed {
26                KeyEventKind::Press
27            } else {
28                KeyEventKind::Release
29            },
30            state: KeyEventState::empty(),
31        })),
32        egui::Event::PointerMoved(pos) => Ok(Event::Mouse(MouseEvent {
33            kind: MouseEventKind::Moved,
34            column: pos.x as u16,
35            row: pos.y as u16,
36            modifiers: KeyModifiers::empty(),
37        })),
38
39        egui::Event::PointerButton {
40            pos,
41            button,
42            pressed,
43            modifiers,
44        } => Ok(Event::Mouse(MouseEvent {
45            kind: if pressed {
46                MouseEventKind::Down(mouse_button_to_terminput(button))
47            } else {
48                MouseEventKind::Up(mouse_button_to_terminput(button))
49            },
50            column: pos.x as u16,
51            row: pos.y as u16,
52            modifiers: key_modifiers_to_terminput(modifiers),
53        })),
54        egui::Event::MouseWheel {
55            unit: _,
56            delta,
57            modifiers,
58        } => Ok(Event::Mouse(MouseEvent {
59            kind: MouseEventKind::Scroll(if delta.y < 0.0 {
60                ScrollDirection::Down
61            } else if delta.y > 0.0 {
62                ScrollDirection::Up
63            } else if delta.x < 0.0 {
64                ScrollDirection::Left
65            } else {
66                ScrollDirection::Right
67            }),
68            column: 0,
69            row: 0,
70            modifiers: key_modifiers_to_terminput(modifiers),
71        })),
72        egui::Event::WindowFocused(true) => Ok(Event::FocusGained),
73        egui::Event::WindowFocused(false) => Ok(Event::FocusLost),
74        egui::Event::Copy
75        | egui::Event::Cut
76        | egui::Event::MouseMoved(_)
77        | egui::Event::Ime(_)
78        | egui::Event::PointerGone
79        | egui::Event::Zoom(_)
80        | egui::Event::Touch { .. }
81        | egui::Event::Screenshot { .. } => Err(UnsupportedEvent(format!("{value:?}"))),
82    }
83}
84
85/// Converts the terminput [event](Event) to an egui [event](egui::Event).
86pub fn to_egui(value: Event) -> Result<egui::Event, UnsupportedEvent> {
87    Ok(match value {
88        Event::Key(key_event) => egui::Event::Key {
89            key: key_code_to_egui(key_event.code)?,
90            physical_key: None,
91            pressed: key_event.kind != KeyEventKind::Release,
92            repeat: key_event.kind == KeyEventKind::Repeat,
93            modifiers: key_modifiers_to_egui(key_event.modifiers),
94        },
95        Event::Mouse(mouse_event) => match mouse_event.kind {
96            MouseEventKind::Down(mouse_button) | MouseEventKind::Drag(mouse_button) => {
97                egui::Event::PointerButton {
98                    pos: egui::Pos2 {
99                        x: mouse_event.column as f32,
100                        y: mouse_event.row as f32,
101                    },
102                    button: mouse_button_to_egui(mouse_button),
103                    pressed: true,
104                    modifiers: key_modifiers_to_egui(mouse_event.modifiers),
105                }
106            }
107            MouseEventKind::Up(mouse_button) => egui::Event::PointerButton {
108                pos: egui::Pos2 {
109                    x: mouse_event.column as f32,
110                    y: mouse_event.row as f32,
111                },
112                button: mouse_button_to_egui(mouse_button),
113                pressed: false,
114                modifiers: key_modifiers_to_egui(mouse_event.modifiers),
115            },
116            MouseEventKind::Moved => egui::Event::PointerMoved(egui::Pos2 {
117                x: mouse_event.column as f32,
118                y: mouse_event.row as f32,
119            }),
120            MouseEventKind::Scroll(scroll_direction) => egui::Event::MouseWheel {
121                unit: egui::MouseWheelUnit::Line,
122                delta: egui::Vec2 {
123                    x: scroll_direction.delta().x as f32,
124                    y: scroll_direction.delta().y as f32,
125                },
126                modifiers: key_modifiers_to_egui(mouse_event.modifiers),
127            },
128        },
129        Event::Paste(text) => egui::Event::Paste(text),
130        Event::FocusGained => egui::Event::WindowFocused(true),
131        Event::FocusLost => egui::Event::WindowFocused(false),
132        Event::Resize { .. } => Err(UnsupportedEvent(format!("{value:?}")))?,
133    })
134}
135
136fn key_code_to_terminput(value: egui::Key) -> Result<KeyCode, UnsupportedEvent> {
137    match value {
138        egui::Key::ArrowDown => Ok(KeyCode::Down),
139        egui::Key::ArrowLeft => Ok(KeyCode::Left),
140        egui::Key::ArrowRight => Ok(KeyCode::Right),
141        egui::Key::ArrowUp => Ok(KeyCode::Up),
142        egui::Key::Escape => Ok(KeyCode::Esc),
143        egui::Key::Tab => Ok(KeyCode::Tab),
144        egui::Key::Backspace => Ok(KeyCode::Backspace),
145        egui::Key::Enter => Ok(KeyCode::Enter),
146        egui::Key::Space => Ok(KeyCode::Char(' ')),
147        egui::Key::Insert => Ok(KeyCode::Insert),
148        egui::Key::Delete => Ok(KeyCode::Delete),
149        egui::Key::Home => Ok(KeyCode::Home),
150        egui::Key::End => Ok(KeyCode::End),
151        egui::Key::PageUp => Ok(KeyCode::PageUp),
152        egui::Key::PageDown => Ok(KeyCode::PageDown),
153        egui::Key::Colon => Ok(KeyCode::Char(':')),
154        egui::Key::Comma => Ok(KeyCode::Char(',')),
155        egui::Key::Backslash => Ok(KeyCode::Char('\\')),
156        egui::Key::Slash => Ok(KeyCode::Char('/')),
157        egui::Key::Pipe => Ok(KeyCode::Char('|')),
158        egui::Key::Questionmark => Ok(KeyCode::Char('?')),
159        egui::Key::Exclamationmark => Ok(KeyCode::Char('!')),
160        egui::Key::OpenBracket => Ok(KeyCode::Char('[')),
161        egui::Key::CloseBracket => Ok(KeyCode::Char(']')),
162        egui::Key::OpenCurlyBracket => Ok(KeyCode::Char('{')),
163        egui::Key::CloseCurlyBracket => Ok(KeyCode::Char('}')),
164        egui::Key::Backtick => Ok(KeyCode::Char('`')),
165        egui::Key::Minus => Ok(KeyCode::Char('-')),
166        egui::Key::Period => Ok(KeyCode::Char('.')),
167        egui::Key::Plus => Ok(KeyCode::Char('+')),
168        egui::Key::Equals => Ok(KeyCode::Char('=')),
169        egui::Key::Semicolon => Ok(KeyCode::Char(';')),
170        egui::Key::Quote => Ok(KeyCode::Char('\'')),
171        egui::Key::Num0 => Ok(KeyCode::Char('0')),
172        egui::Key::Num1 => Ok(KeyCode::Char('1')),
173        egui::Key::Num2 => Ok(KeyCode::Char('2')),
174        egui::Key::Num3 => Ok(KeyCode::Char('3')),
175        egui::Key::Num4 => Ok(KeyCode::Char('4')),
176        egui::Key::Num5 => Ok(KeyCode::Char('5')),
177        egui::Key::Num6 => Ok(KeyCode::Char('6')),
178        egui::Key::Num7 => Ok(KeyCode::Char('7')),
179        egui::Key::Num8 => Ok(KeyCode::Char('8')),
180        egui::Key::Num9 => Ok(KeyCode::Char('9')),
181        egui::Key::A => Ok(KeyCode::Char('a')),
182        egui::Key::B => Ok(KeyCode::Char('b')),
183        egui::Key::C => Ok(KeyCode::Char('c')),
184        egui::Key::D => Ok(KeyCode::Char('d')),
185        egui::Key::E => Ok(KeyCode::Char('e')),
186        egui::Key::F => Ok(KeyCode::Char('f')),
187        egui::Key::G => Ok(KeyCode::Char('g')),
188        egui::Key::H => Ok(KeyCode::Char('h')),
189        egui::Key::I => Ok(KeyCode::Char('i')),
190        egui::Key::J => Ok(KeyCode::Char('j')),
191        egui::Key::K => Ok(KeyCode::Char('k')),
192        egui::Key::L => Ok(KeyCode::Char('l')),
193        egui::Key::M => Ok(KeyCode::Char('m')),
194        egui::Key::N => Ok(KeyCode::Char('n')),
195        egui::Key::O => Ok(KeyCode::Char('o')),
196        egui::Key::P => Ok(KeyCode::Char('p')),
197        egui::Key::Q => Ok(KeyCode::Char('q')),
198        egui::Key::R => Ok(KeyCode::Char('r')),
199        egui::Key::S => Ok(KeyCode::Char('s')),
200        egui::Key::T => Ok(KeyCode::Char('t')),
201        egui::Key::U => Ok(KeyCode::Char('u')),
202        egui::Key::V => Ok(KeyCode::Char('v')),
203        egui::Key::W => Ok(KeyCode::Char('w')),
204        egui::Key::X => Ok(KeyCode::Char('x')),
205        egui::Key::Y => Ok(KeyCode::Char('y')),
206        egui::Key::Z => Ok(KeyCode::Char('z')),
207        egui::Key::F1 => Ok(KeyCode::F(1)),
208        egui::Key::F2 => Ok(KeyCode::F(2)),
209        egui::Key::F3 => Ok(KeyCode::F(3)),
210        egui::Key::F4 => Ok(KeyCode::F(4)),
211        egui::Key::F5 => Ok(KeyCode::F(5)),
212        egui::Key::F6 => Ok(KeyCode::F(6)),
213        egui::Key::F7 => Ok(KeyCode::F(7)),
214        egui::Key::F8 => Ok(KeyCode::F(8)),
215        egui::Key::F9 => Ok(KeyCode::F(9)),
216        egui::Key::F10 => Ok(KeyCode::F(10)),
217        egui::Key::F11 => Ok(KeyCode::F(11)),
218        egui::Key::F12 => Ok(KeyCode::F(12)),
219        egui::Key::F13 => Ok(KeyCode::F(13)),
220        egui::Key::F14 => Ok(KeyCode::F(14)),
221        egui::Key::F15 => Ok(KeyCode::F(15)),
222        egui::Key::F16 => Ok(KeyCode::F(16)),
223        egui::Key::F17 => Ok(KeyCode::F(17)),
224        egui::Key::F18 => Ok(KeyCode::F(18)),
225        egui::Key::F19 => Ok(KeyCode::F(19)),
226        egui::Key::F20 => Ok(KeyCode::F(20)),
227        egui::Key::F21 => Ok(KeyCode::F(21)),
228        egui::Key::F22 => Ok(KeyCode::F(22)),
229        egui::Key::F23 => Ok(KeyCode::F(23)),
230        egui::Key::F24 => Ok(KeyCode::F(24)),
231        egui::Key::F25 => Ok(KeyCode::F(25)),
232        egui::Key::F26 => Ok(KeyCode::F(26)),
233        egui::Key::F27 => Ok(KeyCode::F(27)),
234        egui::Key::F28 => Ok(KeyCode::F(28)),
235        egui::Key::F29 => Ok(KeyCode::F(29)),
236        egui::Key::F30 => Ok(KeyCode::F(30)),
237        egui::Key::F31 => Ok(KeyCode::F(31)),
238        egui::Key::F32 => Ok(KeyCode::F(32)),
239        egui::Key::F33 => Ok(KeyCode::F(33)),
240        egui::Key::F34 => Ok(KeyCode::F(34)),
241        egui::Key::F35 => Ok(KeyCode::F(35)),
242        egui::Key::Copy | egui::Key::Cut | egui::Key::Paste => {
243            Err(UnsupportedEvent(format!("{value:?}")))
244        }
245    }
246}
247
248fn key_code_to_egui(value: KeyCode) -> Result<egui::Key, UnsupportedEvent> {
249    Ok(match value {
250        KeyCode::Backspace => egui::Key::Backspace,
251        KeyCode::Enter => egui::Key::Enter,
252        KeyCode::Left => egui::Key::ArrowLeft,
253        KeyCode::Right => egui::Key::ArrowRight,
254        KeyCode::Up => egui::Key::ArrowUp,
255        KeyCode::Down => egui::Key::ArrowDown,
256        KeyCode::Home => egui::Key::Home,
257        KeyCode::End => egui::Key::End,
258        KeyCode::PageUp => egui::Key::PageUp,
259        KeyCode::PageDown => egui::Key::PageDown,
260        KeyCode::Tab => egui::Key::Tab,
261        KeyCode::Delete => egui::Key::Delete,
262        KeyCode::Insert => egui::Key::Insert,
263        KeyCode::F(1) => egui::Key::F1,
264        KeyCode::F(2) => egui::Key::F2,
265        KeyCode::F(3) => egui::Key::F3,
266        KeyCode::F(4) => egui::Key::F4,
267        KeyCode::F(5) => egui::Key::F5,
268        KeyCode::F(6) => egui::Key::F6,
269        KeyCode::F(7) => egui::Key::F7,
270        KeyCode::F(8) => egui::Key::F8,
271        KeyCode::F(9) => egui::Key::F9,
272        KeyCode::F(10) => egui::Key::F10,
273        KeyCode::F(11) => egui::Key::F11,
274        KeyCode::F(12) => egui::Key::F12,
275        KeyCode::F(13) => egui::Key::F13,
276        KeyCode::F(14) => egui::Key::F14,
277        KeyCode::F(15) => egui::Key::F15,
278        KeyCode::F(16) => egui::Key::F16,
279        KeyCode::F(17) => egui::Key::F17,
280        KeyCode::F(18) => egui::Key::F18,
281        KeyCode::F(19) => egui::Key::F19,
282        KeyCode::F(20) => egui::Key::F20,
283        KeyCode::F(21) => egui::Key::F21,
284        KeyCode::F(22) => egui::Key::F22,
285        KeyCode::F(23) => egui::Key::F23,
286        KeyCode::F(24) => egui::Key::F24,
287        KeyCode::F(25) => egui::Key::F25,
288        KeyCode::F(26) => egui::Key::F26,
289        KeyCode::F(27) => egui::Key::F27,
290        KeyCode::F(28) => egui::Key::F28,
291        KeyCode::F(29) => egui::Key::F29,
292        KeyCode::F(30) => egui::Key::F30,
293        KeyCode::F(31) => egui::Key::F31,
294        KeyCode::F(32) => egui::Key::F32,
295        KeyCode::F(33) => egui::Key::F33,
296        KeyCode::F(34) => egui::Key::F34,
297        KeyCode::F(35) => egui::Key::F35,
298        KeyCode::F(_) => Err(UnsupportedEvent(format!("{value:?}")))?,
299        KeyCode::Char('a' | 'A') => egui::Key::A,
300        KeyCode::Char('b' | 'B') => egui::Key::B,
301        KeyCode::Char('c' | 'C') => egui::Key::C,
302        KeyCode::Char('d' | 'D') => egui::Key::D,
303        KeyCode::Char('e' | 'E') => egui::Key::E,
304        KeyCode::Char('f' | 'F') => egui::Key::F,
305        KeyCode::Char('g' | 'G') => egui::Key::G,
306        KeyCode::Char('h' | 'H') => egui::Key::H,
307        KeyCode::Char('i' | 'I') => egui::Key::I,
308        KeyCode::Char('j' | 'J') => egui::Key::J,
309        KeyCode::Char('k' | 'K') => egui::Key::K,
310        KeyCode::Char('l' | 'L') => egui::Key::L,
311        KeyCode::Char('m' | 'M') => egui::Key::M,
312        KeyCode::Char('n' | 'N') => egui::Key::N,
313        KeyCode::Char('o' | 'O') => egui::Key::O,
314        KeyCode::Char('p' | 'P') => egui::Key::P,
315        KeyCode::Char('q' | 'Q') => egui::Key::Q,
316        KeyCode::Char('r' | 'R') => egui::Key::R,
317        KeyCode::Char('s' | 'S') => egui::Key::S,
318        KeyCode::Char('t' | 'T') => egui::Key::T,
319        KeyCode::Char('u' | 'U') => egui::Key::U,
320        KeyCode::Char('v' | 'V') => egui::Key::V,
321        KeyCode::Char('w' | 'W') => egui::Key::W,
322        KeyCode::Char('x' | 'X') => egui::Key::X,
323        KeyCode::Char('y' | 'Y') => egui::Key::Y,
324        KeyCode::Char('z' | 'Z') => egui::Key::Z,
325        KeyCode::Char('0') => egui::Key::Num0,
326        KeyCode::Char('1') => egui::Key::Num1,
327        KeyCode::Char('2') => egui::Key::Num2,
328        KeyCode::Char('3') => egui::Key::Num3,
329        KeyCode::Char('4') => egui::Key::Num4,
330        KeyCode::Char('5') => egui::Key::Num5,
331        KeyCode::Char('6') => egui::Key::Num6,
332        KeyCode::Char('7') => egui::Key::Num7,
333        KeyCode::Char('8') => egui::Key::Num8,
334        KeyCode::Char('9') => egui::Key::Num9,
335        KeyCode::Char(' ') => egui::Key::Space,
336        KeyCode::Char(':') => egui::Key::Colon,
337        KeyCode::Char(',') => egui::Key::Comma,
338        KeyCode::Char('\\') => egui::Key::Backslash,
339        KeyCode::Char('/') => egui::Key::Slash,
340        KeyCode::Char('|') => egui::Key::Pipe,
341        KeyCode::Char('?') => egui::Key::Questionmark,
342        KeyCode::Char('[') => egui::Key::OpenBracket,
343        KeyCode::Char(']') => egui::Key::CloseBracket,
344        KeyCode::Char('`') => egui::Key::Backtick,
345        KeyCode::Char('-') => egui::Key::Minus,
346        KeyCode::Char('.') => egui::Key::Period,
347        KeyCode::Char('+') => egui::Key::Plus,
348        KeyCode::Char('=') => egui::Key::Equals,
349        KeyCode::Char(';') => egui::Key::Semicolon,
350        KeyCode::Char('\'') => egui::Key::Quote,
351        KeyCode::Char(_) => Err(UnsupportedEvent(format!("{value:?}")))?,
352        KeyCode::Esc => egui::Key::Escape,
353        KeyCode::CapsLock
354        | KeyCode::ScrollLock
355        | KeyCode::NumLock
356        | KeyCode::PrintScreen
357        | KeyCode::Pause
358        | KeyCode::Menu
359        | KeyCode::KeypadBegin
360        | KeyCode::Media(_)
361        | KeyCode::Modifier(_, _) => Err(UnsupportedEvent(format!("{value:?}")))?,
362    })
363}
364
365fn key_modifiers_to_terminput(value: egui::Modifiers) -> KeyModifiers {
366    let mut mapped = KeyModifiers::empty();
367    if value.alt {
368        mapped |= KeyModifiers::ALT;
369    }
370    if value.shift {
371        mapped |= KeyModifiers::SHIFT;
372    }
373    if value.command | value.ctrl | value.mac_cmd {
374        mapped |= KeyModifiers::CTRL;
375    }
376    mapped
377}
378
379fn key_modifiers_to_egui(value: KeyModifiers) -> egui::Modifiers {
380    egui::Modifiers {
381        alt: value.intersects(KeyModifiers::ALT),
382        ctrl: value.intersects(KeyModifiers::CTRL),
383        shift: value.intersects(KeyModifiers::SHIFT),
384        mac_cmd: false,
385        command: false,
386    }
387}
388
389fn mouse_button_to_terminput(value: egui::PointerButton) -> MouseButton {
390    match value {
391        egui::PointerButton::Primary => MouseButton::Left,
392        egui::PointerButton::Secondary => MouseButton::Right,
393        egui::PointerButton::Middle => MouseButton::Middle,
394        egui::PointerButton::Extra1 | egui::PointerButton::Extra2 => MouseButton::Unknown,
395    }
396}
397
398fn mouse_button_to_egui(value: MouseButton) -> egui::PointerButton {
399    match value {
400        MouseButton::Left | MouseButton::Unknown => egui::PointerButton::Primary,
401        MouseButton::Right => egui::PointerButton::Secondary,
402        MouseButton::Middle => egui::PointerButton::Middle,
403    }
404}