1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
pub use keyboard_types::{Code, Key, Modifiers};
use winit::event::{ModifiersState, VirtualKeyCode};

// Map winit modifiers to keyboard_types modifiers
pub fn get_modifiers(modifiers: ModifiersState) -> Modifiers {
    let mut new_modifiers = Modifiers::empty();
    if modifiers.alt() {
        new_modifiers.toggle(Modifiers::ALT);
    }
    if modifiers.ctrl() {
        new_modifiers.toggle(Modifiers::CONTROL);
    }
    if modifiers.shift() {
        new_modifiers.toggle(Modifiers::SHIFT);
    }
    if modifiers.logo() {
        new_modifiers.toggle(Modifiers::META);
    }
    new_modifiers
}

/// Only return keys that aren't text
pub fn get_non_text_keys(key: &VirtualKeyCode) -> Key {
    match key {
        VirtualKeyCode::Key1 => Key::Unidentified,
        VirtualKeyCode::Key2 => Key::Unidentified,
        VirtualKeyCode::Key3 => Key::Unidentified,
        VirtualKeyCode::Key4 => Key::Unidentified,
        VirtualKeyCode::Key5 => Key::Unidentified,
        VirtualKeyCode::Key6 => Key::Unidentified,
        VirtualKeyCode::Key7 => Key::Unidentified,
        VirtualKeyCode::Key8 => Key::Unidentified,
        VirtualKeyCode::Key9 => Key::Unidentified,
        VirtualKeyCode::Key0 => Key::Unidentified,
        VirtualKeyCode::A => Key::Unidentified,
        VirtualKeyCode::B => Key::Unidentified,
        VirtualKeyCode::C => Key::Unidentified,
        VirtualKeyCode::D => Key::Unidentified,
        VirtualKeyCode::E => Key::Unidentified,
        VirtualKeyCode::F => Key::Unidentified,
        VirtualKeyCode::G => Key::Unidentified,
        VirtualKeyCode::H => Key::Unidentified,
        VirtualKeyCode::I => Key::Unidentified,
        VirtualKeyCode::J => Key::Unidentified,
        VirtualKeyCode::K => Key::Unidentified,
        VirtualKeyCode::L => Key::Unidentified,
        VirtualKeyCode::M => Key::Unidentified,
        VirtualKeyCode::N => Key::Unidentified,
        VirtualKeyCode::O => Key::Unidentified,
        VirtualKeyCode::P => Key::Unidentified,
        VirtualKeyCode::Q => Key::Unidentified,
        VirtualKeyCode::R => Key::Unidentified,
        VirtualKeyCode::S => Key::Unidentified,
        VirtualKeyCode::T => Key::Unidentified,
        VirtualKeyCode::U => Key::Unidentified,
        VirtualKeyCode::V => Key::Unidentified,
        VirtualKeyCode::W => Key::Unidentified,
        VirtualKeyCode::X => Key::Unidentified,
        VirtualKeyCode::Y => Key::Unidentified,
        VirtualKeyCode::Z => Key::Unidentified,
        VirtualKeyCode::Escape => Key::Escape,
        VirtualKeyCode::F1 => Key::F1,
        VirtualKeyCode::F2 => Key::F2,
        VirtualKeyCode::F3 => Key::F3,
        VirtualKeyCode::F4 => Key::F4,
        VirtualKeyCode::F5 => Key::F5,
        VirtualKeyCode::F6 => Key::F6,
        VirtualKeyCode::F7 => Key::F7,
        VirtualKeyCode::F8 => Key::F8,
        VirtualKeyCode::F9 => Key::F9,
        VirtualKeyCode::F10 => Key::F10,
        VirtualKeyCode::F11 => Key::F11,
        VirtualKeyCode::F12 => Key::F12,
        VirtualKeyCode::F13 => Key::F13,
        VirtualKeyCode::F14 => Key::F14,
        VirtualKeyCode::F15 => Key::F15,
        VirtualKeyCode::F16 => Key::F16,
        VirtualKeyCode::F17 => Key::F17,
        VirtualKeyCode::F18 => Key::F18,
        VirtualKeyCode::F19 => Key::F19,
        VirtualKeyCode::F20 => Key::F20,
        VirtualKeyCode::F21 => Key::F21,
        VirtualKeyCode::F22 => Key::F22,
        VirtualKeyCode::F23 => Key::F23,
        VirtualKeyCode::F24 => Key::F24,
        VirtualKeyCode::Snapshot => Key::Unidentified,
        VirtualKeyCode::Scroll => Key::Unidentified,
        VirtualKeyCode::Pause => Key::Pause,
        VirtualKeyCode::Insert => Key::Insert,
        VirtualKeyCode::Home => Key::Home,
        VirtualKeyCode::Delete => Key::Delete,
        VirtualKeyCode::End => Key::End,
        VirtualKeyCode::PageDown => Key::PageDown,
        VirtualKeyCode::PageUp => Key::PageUp,
        VirtualKeyCode::Left => Key::ArrowLeft,
        VirtualKeyCode::Up => Key::ArrowUp,
        VirtualKeyCode::Right => Key::ArrowRight,
        VirtualKeyCode::Down => Key::ArrowDown,
        VirtualKeyCode::Back => Key::Backspace,
        VirtualKeyCode::Return => Key::Enter,
        VirtualKeyCode::Space => Key::Unidentified,
        VirtualKeyCode::Compose => Key::Compose,
        VirtualKeyCode::Caret => Key::Unidentified,
        VirtualKeyCode::Numlock => Key::NumLock,
        VirtualKeyCode::Numpad0 => Key::Unidentified,
        VirtualKeyCode::Numpad1 => Key::Unidentified,
        VirtualKeyCode::Numpad2 => Key::Unidentified,
        VirtualKeyCode::Numpad3 => Key::Unidentified,
        VirtualKeyCode::Numpad4 => Key::Unidentified,
        VirtualKeyCode::Numpad5 => Key::Unidentified,
        VirtualKeyCode::Numpad6 => Key::Unidentified,
        VirtualKeyCode::Numpad7 => Key::Unidentified,
        VirtualKeyCode::Numpad8 => Key::Unidentified,
        VirtualKeyCode::Numpad9 => Key::Unidentified,
        VirtualKeyCode::NumpadAdd => Key::Unidentified,
        VirtualKeyCode::NumpadDivide => Key::Unidentified,
        VirtualKeyCode::NumpadDecimal => Key::Unidentified,
        VirtualKeyCode::NumpadComma => Key::Unidentified,
        VirtualKeyCode::NumpadEnter => Key::Unidentified,
        VirtualKeyCode::NumpadEquals => Key::Unidentified,
        VirtualKeyCode::NumpadMultiply => Key::Unidentified,
        VirtualKeyCode::NumpadSubtract => Key::Unidentified,
        VirtualKeyCode::AbntC1 => Key::Unidentified,
        VirtualKeyCode::AbntC2 => Key::Unidentified,
        VirtualKeyCode::Apostrophe => Key::Unidentified,
        VirtualKeyCode::Apps => Key::Unidentified,
        VirtualKeyCode::Asterisk => Key::Unidentified,
        VirtualKeyCode::At => Key::Unidentified,
        VirtualKeyCode::Ax => Key::Unidentified,
        VirtualKeyCode::Backslash => Key::Unidentified,
        VirtualKeyCode::Calculator => Key::Unidentified,
        VirtualKeyCode::Capital => Key::Unidentified,
        VirtualKeyCode::Colon => Key::Unidentified,
        VirtualKeyCode::Comma => Key::Unidentified,
        VirtualKeyCode::Convert => Key::Unidentified,
        VirtualKeyCode::Equals => Key::Unidentified,
        VirtualKeyCode::Grave => Key::Unidentified,
        VirtualKeyCode::Kana => Key::Unidentified,
        VirtualKeyCode::Kanji => Key::Unidentified,
        VirtualKeyCode::LAlt => Key::Alt,
        VirtualKeyCode::LBracket => Key::Unidentified,
        VirtualKeyCode::LControl => Key::Control,
        VirtualKeyCode::LShift => Key::Shift,
        VirtualKeyCode::LWin => Key::Meta,
        VirtualKeyCode::Mail => Key::Unidentified,
        VirtualKeyCode::MediaSelect => Key::Unidentified,
        VirtualKeyCode::MediaStop => Key::Unidentified,
        VirtualKeyCode::Minus => Key::Unidentified,
        VirtualKeyCode::Mute => Key::Unidentified,
        VirtualKeyCode::MyComputer => Key::Unidentified,
        VirtualKeyCode::NavigateForward => Key::Unidentified,
        VirtualKeyCode::NavigateBackward => Key::Unidentified,
        VirtualKeyCode::NextTrack => Key::Unidentified,
        VirtualKeyCode::NoConvert => Key::Unidentified,
        VirtualKeyCode::OEM102 => Key::Unidentified,
        VirtualKeyCode::Period => Key::Unidentified,
        VirtualKeyCode::PlayPause => Key::Unidentified,
        VirtualKeyCode::Plus => Key::Unidentified,
        VirtualKeyCode::Power => Key::Unidentified,
        VirtualKeyCode::PrevTrack => Key::Unidentified,
        VirtualKeyCode::RAlt => Key::AltGraph,
        VirtualKeyCode::RBracket => Key::Unidentified,
        VirtualKeyCode::RControl => Key::Control,
        VirtualKeyCode::RShift => Key::Shift,
        VirtualKeyCode::RWin => Key::Meta,
        VirtualKeyCode::Semicolon => Key::Unidentified,
        VirtualKeyCode::Slash => Key::Unidentified,
        VirtualKeyCode::Sleep => Key::Unidentified,
        VirtualKeyCode::Stop => Key::Unidentified,
        VirtualKeyCode::Sysrq => Key::Unidentified,
        VirtualKeyCode::Tab => Key::Unidentified,
        VirtualKeyCode::Underline => Key::Unidentified,
        VirtualKeyCode::Unlabeled => Key::Unidentified,
        VirtualKeyCode::VolumeDown => Key::AudioVolumeDown,
        VirtualKeyCode::VolumeUp => Key::AudioVolumeUp,
        VirtualKeyCode::Wake => Key::Unidentified,
        VirtualKeyCode::WebBack => Key::Unidentified,
        VirtualKeyCode::WebFavorites => Key::Unidentified,
        VirtualKeyCode::WebForward => Key::Unidentified,
        VirtualKeyCode::WebHome => Key::Unidentified,
        VirtualKeyCode::WebRefresh => Key::Unidentified,
        VirtualKeyCode::WebSearch => Key::Unidentified,
        VirtualKeyCode::WebStop => Key::Unidentified,
        VirtualKeyCode::Yen => Key::Unidentified,
        VirtualKeyCode::Copy => Key::Copy,
        VirtualKeyCode::Paste => Key::Paste,
        VirtualKeyCode::Cut => Key::Cut,
    }
}

/// Return the equivalent code of Winit and `keyboard_types`
pub fn from_winit_to_code(key: &VirtualKeyCode) -> Code {
    match key {
        VirtualKeyCode::Key1 => Code::Digit1,
        VirtualKeyCode::Key2 => Code::Digit2,
        VirtualKeyCode::Key3 => Code::Digit3,
        VirtualKeyCode::Key4 => Code::Digit4,
        VirtualKeyCode::Key5 => Code::Digit5,
        VirtualKeyCode::Key6 => Code::Digit6,
        VirtualKeyCode::Key7 => Code::Digit7,
        VirtualKeyCode::Key8 => Code::Digit8,
        VirtualKeyCode::Key9 => Code::Digit9,
        VirtualKeyCode::Key0 => Code::Digit0,
        VirtualKeyCode::A => Code::KeyA,
        VirtualKeyCode::B => Code::KeyB,
        VirtualKeyCode::C => Code::KeyC,
        VirtualKeyCode::D => Code::KeyD,
        VirtualKeyCode::E => Code::KeyE,
        VirtualKeyCode::F => Code::KeyF,
        VirtualKeyCode::G => Code::KeyG,
        VirtualKeyCode::H => Code::KeyH,
        VirtualKeyCode::I => Code::KeyI,
        VirtualKeyCode::J => Code::KeyJ,
        VirtualKeyCode::K => Code::KeyK,
        VirtualKeyCode::L => Code::KeyL,
        VirtualKeyCode::M => Code::KeyM,
        VirtualKeyCode::N => Code::KeyN,
        VirtualKeyCode::O => Code::KeyO,
        VirtualKeyCode::P => Code::KeyP,
        VirtualKeyCode::Q => Code::KeyQ,
        VirtualKeyCode::R => Code::KeyR,
        VirtualKeyCode::S => Code::KeyS,
        VirtualKeyCode::T => Code::KeyT,
        VirtualKeyCode::U => Code::KeyU,
        VirtualKeyCode::V => Code::KeyV,
        VirtualKeyCode::W => Code::KeyW,
        VirtualKeyCode::X => Code::KeyX,
        VirtualKeyCode::Y => Code::KeyY,
        VirtualKeyCode::Z => Code::KeyZ,
        VirtualKeyCode::Escape => Code::Escape,
        VirtualKeyCode::F1 => Code::F1,
        VirtualKeyCode::F2 => Code::F2,
        VirtualKeyCode::F3 => Code::F3,
        VirtualKeyCode::F4 => Code::F4,
        VirtualKeyCode::F5 => Code::F5,
        VirtualKeyCode::F6 => Code::F6,
        VirtualKeyCode::F7 => Code::F7,
        VirtualKeyCode::F8 => Code::F8,
        VirtualKeyCode::F9 => Code::F9,
        VirtualKeyCode::F10 => Code::F10,
        VirtualKeyCode::F11 => Code::F11,
        VirtualKeyCode::F12 => Code::F12,
        VirtualKeyCode::F13 => Code::F13,
        VirtualKeyCode::F14 => Code::F14,
        VirtualKeyCode::F15 => Code::F15,
        VirtualKeyCode::F16 => Code::F16,
        VirtualKeyCode::F17 => Code::F17,
        VirtualKeyCode::F18 => Code::F18,
        VirtualKeyCode::F19 => Code::F19,
        VirtualKeyCode::F20 => Code::F20,
        VirtualKeyCode::F21 => Code::F21,
        VirtualKeyCode::F22 => Code::F22,
        VirtualKeyCode::F23 => Code::F23,
        VirtualKeyCode::F24 => Code::F24,
        VirtualKeyCode::Snapshot => Code::Unidentified,
        VirtualKeyCode::Scroll => Code::Unidentified,
        VirtualKeyCode::Pause => Code::Pause,
        VirtualKeyCode::Insert => Code::Insert,
        VirtualKeyCode::Home => Code::Home,
        VirtualKeyCode::Delete => Code::Delete,
        VirtualKeyCode::End => Code::End,
        VirtualKeyCode::PageDown => Code::PageDown,
        VirtualKeyCode::PageUp => Code::PageUp,
        VirtualKeyCode::Left => Code::ArrowLeft,
        VirtualKeyCode::Up => Code::ArrowUp,
        VirtualKeyCode::Right => Code::ArrowRight,
        VirtualKeyCode::Down => Code::ArrowDown,
        VirtualKeyCode::Back => Code::Backspace,
        VirtualKeyCode::Return => Code::Enter,
        VirtualKeyCode::Space => Code::Space,
        VirtualKeyCode::Compose => Code::Unidentified,
        VirtualKeyCode::Caret => Code::Unidentified,
        VirtualKeyCode::Numlock => Code::NumLock,
        VirtualKeyCode::Numpad0 => Code::Numpad0,
        VirtualKeyCode::Numpad1 => Code::Numpad1,
        VirtualKeyCode::Numpad2 => Code::Numpad2,
        VirtualKeyCode::Numpad3 => Code::Numpad3,
        VirtualKeyCode::Numpad4 => Code::Numpad4,
        VirtualKeyCode::Numpad5 => Code::Numpad5,
        VirtualKeyCode::Numpad6 => Code::Numpad6,
        VirtualKeyCode::Numpad7 => Code::Numpad7,
        VirtualKeyCode::Numpad8 => Code::Numpad8,
        VirtualKeyCode::Numpad9 => Code::Numpad9,
        VirtualKeyCode::NumpadAdd => Code::NumpadAdd,
        VirtualKeyCode::NumpadDivide => Code::NumpadDivide,
        VirtualKeyCode::NumpadDecimal => Code::NumpadDecimal,
        VirtualKeyCode::NumpadComma => Code::NumpadComma,
        VirtualKeyCode::NumpadEnter => Code::NumpadEnter,
        VirtualKeyCode::NumpadEquals => Code::NumpadEqual,
        VirtualKeyCode::NumpadMultiply => Code::NumpadMultiply,
        VirtualKeyCode::NumpadSubtract => Code::NumpadSubtract,
        VirtualKeyCode::AbntC1 => Code::Unidentified,
        VirtualKeyCode::AbntC2 => Code::Unidentified,
        VirtualKeyCode::Apostrophe => Code::Unidentified,
        VirtualKeyCode::Apps => Code::Unidentified,
        VirtualKeyCode::Asterisk => Code::Unidentified,
        VirtualKeyCode::At => Code::Unidentified,
        VirtualKeyCode::Ax => Code::Unidentified,
        VirtualKeyCode::Backslash => Code::Backslash,
        VirtualKeyCode::Calculator => Code::Unidentified,
        VirtualKeyCode::Capital => Code::Unidentified,
        VirtualKeyCode::Colon => Code::Unidentified,
        VirtualKeyCode::Comma => Code::Comma,
        VirtualKeyCode::Convert => Code::Convert,
        VirtualKeyCode::Equals => Code::Equal,
        VirtualKeyCode::Grave => Code::Unidentified,
        VirtualKeyCode::Kana => Code::Unidentified,
        VirtualKeyCode::Kanji => Code::Unidentified,
        VirtualKeyCode::LAlt => Code::Unidentified,
        VirtualKeyCode::LBracket => Code::BracketLeft,
        VirtualKeyCode::LControl => Code::ControlLeft,
        VirtualKeyCode::LShift => Code::ShiftLeft,
        VirtualKeyCode::LWin => Code::MetaLeft,
        VirtualKeyCode::Mail => Code::Unidentified,
        VirtualKeyCode::MediaSelect => Code::Unidentified,
        VirtualKeyCode::MediaStop => Code::Unidentified,
        VirtualKeyCode::Minus => Code::Unidentified,
        VirtualKeyCode::Mute => Code::Unidentified,
        VirtualKeyCode::MyComputer => Code::Unidentified,
        VirtualKeyCode::NavigateForward => Code::Unidentified,
        VirtualKeyCode::NavigateBackward => Code::Unidentified,
        VirtualKeyCode::NextTrack => Code::Unidentified,
        VirtualKeyCode::NoConvert => Code::Unidentified,
        VirtualKeyCode::OEM102 => Code::Unidentified,
        VirtualKeyCode::Period => Code::Unidentified,
        VirtualKeyCode::PlayPause => Code::Unidentified,
        VirtualKeyCode::Plus => Code::Unidentified,
        VirtualKeyCode::Power => Code::Unidentified,
        VirtualKeyCode::PrevTrack => Code::Unidentified,
        VirtualKeyCode::RAlt => Code::AltRight,
        VirtualKeyCode::RBracket => Code::BracketRight,
        VirtualKeyCode::RControl => Code::ControlRight,
        VirtualKeyCode::RShift => Code::ShiftRight,
        VirtualKeyCode::RWin => Code::MetaRight,
        VirtualKeyCode::Semicolon => Code::Semicolon,
        VirtualKeyCode::Slash => Code::Unidentified,
        VirtualKeyCode::Sleep => Code::Unidentified,
        VirtualKeyCode::Stop => Code::Unidentified,
        VirtualKeyCode::Sysrq => Code::Unidentified,
        VirtualKeyCode::Tab => Code::Tab,
        VirtualKeyCode::Underline => Code::Unidentified,
        VirtualKeyCode::Unlabeled => Code::Unidentified,
        VirtualKeyCode::VolumeDown => Code::AudioVolumeDown,
        VirtualKeyCode::VolumeUp => Code::AudioVolumeUp,
        VirtualKeyCode::Wake => Code::Unidentified,
        VirtualKeyCode::WebBack => Code::Unidentified,
        VirtualKeyCode::WebFavorites => Code::Unidentified,
        VirtualKeyCode::WebForward => Code::Unidentified,
        VirtualKeyCode::WebHome => Code::Unidentified,
        VirtualKeyCode::WebRefresh => Code::Unidentified,
        VirtualKeyCode::WebSearch => Code::Unidentified,
        VirtualKeyCode::WebStop => Code::Unidentified,
        VirtualKeyCode::Yen => Code::IntlYen,
        VirtualKeyCode::Copy => Code::Copy,
        VirtualKeyCode::Paste => Code::Paste,
        VirtualKeyCode::Cut => Code::Cut,
    }
}

/// Data of a Keyboard event.
#[derive(Debug, Clone)]
pub struct KeyboardData {
    pub key: Key,
    pub code: Code,
    pub modifiers: Modifiers,
}

impl KeyboardData {
    pub fn new(key: Key, code: Code, modifiers: Modifiers) -> Self {
        Self {
            key,
            code,
            modifiers,
        }
    }
}

impl KeyboardData {
    /// Try to get the text of the character
    pub fn to_text(&self) -> Option<&str> {
        if let Key::Character(c) = &self.key {
            Some(c)
        } else {
            None
        }
    }
}