devela/ui/back/crossterm/
events.rs

1// devela::ui::service::crossterm::events
2//
3//! Events types conversions.
4//
5// ISSUES
6// - WAIT: [missing key combos](https://github.com/crossterm-rs/crossterm/issues/685)
7// - NOTE: ctrl+backspace == ctrl+h
8//
9// TODO
10// - [ ] KeyEventState -> discard for now: (KEYPAD, CAPS_LOCK, NUM_LOCK)
11// - MAYBE add conversions back to crossterm
12// - IMPROVE meta-docs
13
14use crate::{
15    iif,
16    // KeyCode, KeyEvent, KeyKind, KeyModifiers, MediaKey, ModifierKey, MouseButton,
17    // MouseEvent, MouseKind, WindowEvent,
18    /* Event, EventKind, */
19};
20use ::crossterm::event::{
21    Event as CtEvent, KeyCode as CtKeyCode, KeyEvent as CtKeyEvent, KeyEventKind as CtKeyEventKind,
22    KeyModifiers as CtKeyModifiers, MediaKeyCode as CtMediaKeyCode,
23    ModifierKeyCode as CtModifierKeyCode, MouseButton as CtMouseButton, MouseEvent as CtMouseEvent,
24    MouseEventKind as CtMouseEventKind,
25};
26
27// impl From<CtEvent> for Event {
28//     fn from(ct: CtEvent) -> Event {
29//         EventKind::from(ct).into()
30//     }
31// }
32//
33// // https://docs.rs/crossterm/latest/crossterm/event/enum.Event.html
34// impl From<CtEvent> for EventKind {
35//     fn from(ct: CtEvent) -> EventKind {
36//         use CtEvent as E;
37//         match ct {
38//             E::Key(k) => KeyEvent::from(k).into(),
39//             E::FocusGained => WindowEvent::FocusGained.into(),
40//             E::FocusLost => WindowEvent::FocusLost.into(),
41//             E::Resize(w, h) => WindowEvent::Resized(Some((w, h).into())).into(),
42//             #[cfg(feature = "alloc")]
43//             E::Paste(s) => WindowEvent::Paste(s).into(),
44//             #[cfg(not(feature = "alloc"))]
45//             E::Paste(_) => EventKind::None,
46//             E::Mouse(m) => MouseEvent::from(m).into(),
47//         }
48//     }
49// }
50//
51// // https://docs.rs/crossterm/latest/crossterm/event/struct.KeyEvent.html
52// impl From<CtKeyEvent> for KeyEvent {
53//     fn from(ct: CtKeyEvent) -> KeyEvent {
54//         let km = KeyModifiers::from(ct.modifiers);
55//         let kk = KeyKind::from(ct.kind);
56//         let _ks = ct.state; // THINK
57//
58//         use CtKeyCode as K;
59//
60//         match ct.code {
61//             // special transformations
62//             // THINK about: Null, KeyPadBegin
63//             K::BackTab => (KeyCode::Tab, km.with_shift(true), kk).into(),
64//             _ => (KeyCode::from(ct.code), km, kk).into(),
65//         }
66//     }
67// }
68//
69// // https://docs.rs/crossterm/latest/crossterm/event/struct.KeyModifiers.html
70// impl From<CtKeyModifiers> for KeyModifiers {
71//     fn from(ct: CtKeyModifiers) -> KeyModifiers {
72//         let mut km = KeyModifiers::None;
73//
74//         if ct.is_empty() {
75//             km
76//         } else {
77//             iif![ct.intersects(CtKeyModifiers::SHIFT); km.set_shift()];
78//             iif![ct.intersects(CtKeyModifiers::CONTROL); km.set_control()];
79//             iif![ct.intersects(CtKeyModifiers::ALT); km.set_alt()];
80//             iif![ct.intersects(CtKeyModifiers::SUPER); km.set_sup()];
81//             iif![ct.intersects(CtKeyModifiers::HYPER); km.set_hyper()];
82//             iif![ct.intersects(CtKeyModifiers::META); km.set_meta()];
83//             // no caps_lock
84//             // no num_lock
85//             km
86//         }
87//     }
88// }
89//
90// impl From<CtModifierKeyCode> for ModifierKey {
91//     fn from(ct: CtModifierKeyCode) -> ModifierKey {
92//         use CtModifierKeyCode as K;
93//         match ct {
94//             K::LeftShift => ModifierKey::LeftShift,
95//             K::LeftControl => ModifierKey::LeftControl,
96//             K::LeftAlt => ModifierKey::LeftAlt,
97//             K::LeftSuper => ModifierKey::LeftSuper,
98//             K::LeftHyper => ModifierKey::LeftHyper,
99//             K::LeftMeta => ModifierKey::LeftMeta,
100//             K::RightShift => ModifierKey::RightShift,
101//             K::RightControl => ModifierKey::RightControl,
102//             K::RightAlt => ModifierKey::RightAlt,
103//             K::RightSuper => ModifierKey::RightSuper,
104//             K::RightHyper => ModifierKey::RightHyper,
105//             K::RightMeta => ModifierKey::RightMeta,
106//             K::IsoLevel3Shift => ModifierKey::IsoLevel3Shift,
107//             K::IsoLevel5Shift => ModifierKey::IsoLevel5Shift,
108//         }
109//     }
110// }
111//
112// impl From<CtMediaKeyCode> for MediaKey {
113//     fn from(ct: CtMediaKeyCode) -> MediaKey {
114//         use CtMediaKeyCode as K;
115//         match ct {
116//             K::Play => MediaKey::Play,
117//             K::Pause => MediaKey::Pause,
118//             K::PlayPause => MediaKey::PlayPause,
119//             K::Reverse => MediaKey::Reverse,
120//             K::Stop => MediaKey::Stop,
121//             K::FastForward => MediaKey::FastForward,
122//             K::Rewind => MediaKey::Rewind,
123//             K::TrackNext => MediaKey::Next,
124//             K::TrackPrevious => MediaKey::Previous,
125//             K::Record => MediaKey::Record,
126//             K::LowerVolume => MediaKey::LowerVolume,
127//             K::RaiseVolume => MediaKey::RaiseVolume,
128//             K::MuteVolume => MediaKey::MuteVolume,
129//         }
130//     }
131// }
132//
133// impl From<CtKeyCode> for KeyCode {
134//     fn from(ct: CtKeyCode) -> KeyCode {
135//         use CtKeyCode as K;
136//         match ct {
137//             K::Backspace => KeyCode::Backspace,
138//             K::Enter => KeyCode::Enter,
139//             K::Left => KeyCode::Left,
140//             K::Right => KeyCode::Right,
141//             K::Up => KeyCode::Up,
142//             K::Down => KeyCode::Down,
143//             K::Home => KeyCode::Home,
144//             K::End => KeyCode::End,
145//             K::PageUp => KeyCode::PageUp,
146//             K::PageDown => KeyCode::PageDown,
147//             K::Tab => KeyCode::Tab,
148//             K::BackTab => KeyCode::Tab, // TODO take Shift into account in KeyEvent conversion
149//             K::Delete => KeyCode::Delete,
150//             K::Insert => KeyCode::Insert,
151//             K::F(f) => KeyCode::F(f),
152//             K::Char(c) => KeyCode::Char(c),
153//             K::Null => KeyCode::Unknown, // NOTE
154//             K::Esc => KeyCode::Escape,
155//             K::CapsLock => KeyCode::CapsLock,
156//             K::ScrollLock => KeyCode::ScrollLock,
157//             K::NumLock => KeyCode::NumLock,
158//             K::PrintScreen => KeyCode::PrintScreen,
159//             K::Pause => KeyCode::Pause,
160//             K::Menu => KeyCode::Menu,
161//             K::KeypadBegin => KeyCode::Unknown, // NOTE
162//             K::Media(m) => KeyCode::Media(m.into()),
163//             K::Modifier(m) => KeyCode::Modifier(m.into()),
164//         }
165//     }
166// }
167//
168// impl From<CtKeyEventKind> for KeyKind {
169//     fn from(ct: CtKeyEventKind) -> KeyKind {
170//         use CtKeyEventKind as K;
171//         match ct {
172//             K::Press => KeyKind::Press,
173//             K::Repeat => KeyKind::Repeat,
174//             K::Release => KeyKind::Release,
175//         }
176//     }
177// }
178//
179// /* mouse */
180//
181// // https://docs.rs/crossterm/latest/crossterm/event/struct.MouseEvent.html
182// impl From<CtMouseEvent> for MouseEvent {
183//     fn from(ct: CtMouseEvent) -> MouseEvent {
184//         let button;
185//         let kind;
186//         {
187//             use CtMouseEventKind as K;
188//             match ct.kind {
189//                 K::Down(b) => {
190//                     button = Some(b.into());
191//                     kind = MouseKind::Press;
192//                 }
193//                 K::Up(b) => {
194//                     button = Some(b.into());
195//                     kind = MouseKind::Release;
196//                 }
197//                 K::Drag(b) => {
198//                     button = Some(b.into());
199//                     // RETHINK
200//                     kind = MouseKind::Motion;
201//                 }
202//                 K::Moved => {
203//                     button = None;
204//                     kind = MouseKind::Motion;
205//                 }
206//                 K::ScrollDown => {
207//                     button = None;
208//                     kind = MouseKind::ScrollDown;
209//                 }
210//                 K::ScrollUp => {
211//                     button = None;
212//                     kind = MouseKind::ScrollUp;
213//                 }
214//             }
215//         }
216//
217//         MouseEvent {
218//             button,
219//             kind,
220//             // button: MouseButton::Left, // TEMP
221//             // kind: MouseKind::Press, // TEMP
222//             mods: ct.modifiers.into(),
223//             pos: (ct.column, ct.row).into(),
224//             offset: None,
225//         }
226//     }
227// }
228//
229// // https://docs.rs/crossterm/latest/crossterm/event/enum.MouseButton.html
230// impl From<CtMouseButton> for MouseButton {
231//     fn from(ct: CtMouseButton) -> MouseButton {
232//         use CtMouseButton as K;
233//         match ct {
234//             K::Left => MouseButton::Left,
235//             K::Right => MouseButton::Right,
236//             K::Middle => MouseButton::Middle,
237//         }
238//     }
239// }