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
use crate::{
	binding, event,
	source::{Key, MouseButton},
};
use std::convert::{TryFrom, TryInto};
use winit::event::VirtualKeyCode;

// TODO: Winit gamepad support is still in progress https://github.com/rust-windowing/winit/issues/944
pub fn parse_winit_event<'a, T>(
	event: &winit::event::Event<'a, T>,
) -> Result<(event::Source, event::Event), ()> {
	use winit::event::{DeviceEvent, ElementState, KeyboardInput, MouseScrollDelta};
	match event {
		winit::event::Event::DeviceEvent {
			event: DeviceEvent::MouseMotion { delta },
			..
		} => Ok((
			event::Source::Mouse,
			event::Event {
				source: binding::Source::Mouse(binding::Mouse::Move),
				state: event::State::MouseMove(delta.0, delta.1),
			},
		)),
		winit::event::Event::DeviceEvent {
			event:
				DeviceEvent::MouseWheel {
					delta: MouseScrollDelta::LineDelta(horizontal, vertical),
				},
			..
		} => Ok((
			event::Source::Mouse,
			event::Event {
				source: binding::Source::Mouse(binding::Mouse::Scroll),
				state: event::State::MouseScroll(*horizontal, *vertical),
			},
		)),
		winit::event::Event::DeviceEvent {
			event: DeviceEvent::Button { button, state },
			..
		} => MouseButton::try_from(*button)
			.map(|button_enum| {
				(
					event::Source::Mouse,
					event::Event {
						source: binding::Source::Mouse(binding::Mouse::Button(button_enum)),
						state: event::State::ButtonState(match state {
							ElementState::Pressed => event::ButtonState::Pressed,
							ElementState::Released => event::ButtonState::Released,
						}),
					},
				)
			})
			.map_err(|id| {
				println!("ERROR failed to parse button id {:?}", id);
				()
			}),
		winit::event::Event::DeviceEvent {
			event:
				DeviceEvent::Key(KeyboardInput {
					state,
					virtual_keycode: Some(keycode),
					..
				}),
			..
		} => (*keycode)
			.try_into()
			.map(|keycode| {
				(
					event::Source::Keyboard,
					event::Event {
						source: binding::Source::Keyboard(keycode),
						state: event::State::ButtonState(match state {
							ElementState::Pressed => event::ButtonState::Pressed,
							ElementState::Released => event::ButtonState::Released,
						}),
					},
				)
			})
			.map_err(|_| ()),
		_ => Err(()),
	}
}

impl TryFrom<winit::event::ButtonId> for MouseButton {
	type Error = winit::event::ButtonId;
	fn try_from(id: winit::event::ButtonId) -> Result<Self, Self::Error> {
		match id {
			1 => Ok(MouseButton::Left),
			2 => Ok(MouseButton::Center),
			3 => Ok(MouseButton::Right),
			_ => Err(id),
		}
	}
}

impl TryFrom<VirtualKeyCode> for Key {
	type Error = ();
	fn try_from(winit: VirtualKeyCode) -> Result<Self, Self::Error> {
		match winit {
			VirtualKeyCode::Key1 => Ok(Key::Key1),
			VirtualKeyCode::Key2 => Ok(Key::Key2),
			VirtualKeyCode::Key3 => Ok(Key::Key3),
			VirtualKeyCode::Key4 => Ok(Key::Key4),
			VirtualKeyCode::Key5 => Ok(Key::Key5),
			VirtualKeyCode::Key6 => Ok(Key::Key6),
			VirtualKeyCode::Key7 => Ok(Key::Key7),
			VirtualKeyCode::Key8 => Ok(Key::Key8),
			VirtualKeyCode::Key9 => Ok(Key::Key9),
			VirtualKeyCode::Key0 => Ok(Key::Key0),
			VirtualKeyCode::A => Ok(Key::A),
			VirtualKeyCode::B => Ok(Key::B),
			VirtualKeyCode::C => Ok(Key::C),
			VirtualKeyCode::D => Ok(Key::D),
			VirtualKeyCode::E => Ok(Key::E),
			VirtualKeyCode::F => Ok(Key::F),
			VirtualKeyCode::G => Ok(Key::G),
			VirtualKeyCode::H => Ok(Key::H),
			VirtualKeyCode::I => Ok(Key::I),
			VirtualKeyCode::J => Ok(Key::J),
			VirtualKeyCode::K => Ok(Key::K),
			VirtualKeyCode::L => Ok(Key::L),
			VirtualKeyCode::M => Ok(Key::M),
			VirtualKeyCode::N => Ok(Key::N),
			VirtualKeyCode::O => Ok(Key::O),
			VirtualKeyCode::P => Ok(Key::P),
			VirtualKeyCode::Q => Ok(Key::Q),
			VirtualKeyCode::R => Ok(Key::R),
			VirtualKeyCode::S => Ok(Key::S),
			VirtualKeyCode::T => Ok(Key::T),
			VirtualKeyCode::U => Ok(Key::U),
			VirtualKeyCode::V => Ok(Key::V),
			VirtualKeyCode::W => Ok(Key::W),
			VirtualKeyCode::X => Ok(Key::X),
			VirtualKeyCode::Y => Ok(Key::Y),
			VirtualKeyCode::Z => Ok(Key::Z),
			VirtualKeyCode::Escape => Ok(Key::Escape),
			VirtualKeyCode::F1 => Ok(Key::F1),
			VirtualKeyCode::F2 => Ok(Key::F2),
			VirtualKeyCode::F3 => Ok(Key::F3),
			VirtualKeyCode::F4 => Ok(Key::F4),
			VirtualKeyCode::F5 => Ok(Key::F5),
			VirtualKeyCode::F6 => Ok(Key::F6),
			VirtualKeyCode::F7 => Ok(Key::F7),
			VirtualKeyCode::F8 => Ok(Key::F8),
			VirtualKeyCode::F9 => Ok(Key::F9),
			VirtualKeyCode::F10 => Ok(Key::F10),
			VirtualKeyCode::F11 => Ok(Key::F11),
			VirtualKeyCode::F12 => Ok(Key::F12),
			VirtualKeyCode::F13 => Ok(Key::F13),
			VirtualKeyCode::F14 => Ok(Key::F14),
			VirtualKeyCode::F15 => Ok(Key::F15),
			VirtualKeyCode::F16 => Ok(Key::F16),
			VirtualKeyCode::F17 => Ok(Key::F17),
			VirtualKeyCode::F18 => Ok(Key::F18),
			VirtualKeyCode::F19 => Ok(Key::F19),
			VirtualKeyCode::F20 => Ok(Key::F20),
			VirtualKeyCode::F21 => Ok(Key::F21),
			VirtualKeyCode::F22 => Ok(Key::F22),
			VirtualKeyCode::F23 => Ok(Key::F23),
			VirtualKeyCode::F24 => Ok(Key::F24),
			VirtualKeyCode::Snapshot => Ok(Key::Snapshot),
			VirtualKeyCode::Scroll => Ok(Key::ScrollLock),
			VirtualKeyCode::Pause => Ok(Key::Pause),
			VirtualKeyCode::Insert => Ok(Key::Insert),
			VirtualKeyCode::Home => Ok(Key::Home),
			VirtualKeyCode::Delete => Ok(Key::Delete),
			VirtualKeyCode::End => Ok(Key::End),
			VirtualKeyCode::PageDown => Ok(Key::PageDown),
			VirtualKeyCode::PageUp => Ok(Key::PageUp),
			VirtualKeyCode::Left => Ok(Key::Left),
			VirtualKeyCode::Up => Ok(Key::Up),
			VirtualKeyCode::Right => Ok(Key::Right),
			VirtualKeyCode::Down => Ok(Key::Down),
			VirtualKeyCode::Back => Ok(Key::Back),
			VirtualKeyCode::Return => Ok(Key::Return),
			VirtualKeyCode::Space => Ok(Key::Space),
			VirtualKeyCode::Compose => Err(()),
			VirtualKeyCode::Caret => Err(()),
			VirtualKeyCode::Numlock => Ok(Key::Numlock),
			VirtualKeyCode::Numpad0 => Ok(Key::Numpad0),
			VirtualKeyCode::Numpad1 => Ok(Key::Numpad1),
			VirtualKeyCode::Numpad2 => Ok(Key::Numpad2),
			VirtualKeyCode::Numpad3 => Ok(Key::Numpad3),
			VirtualKeyCode::Numpad4 => Ok(Key::Numpad4),
			VirtualKeyCode::Numpad5 => Ok(Key::Numpad5),
			VirtualKeyCode::Numpad6 => Ok(Key::Numpad6),
			VirtualKeyCode::Numpad7 => Ok(Key::Numpad7),
			VirtualKeyCode::Numpad8 => Ok(Key::Numpad8),
			VirtualKeyCode::Numpad9 => Ok(Key::Numpad9),
			VirtualKeyCode::NumpadAdd => Ok(Key::NumpadPlus),
			VirtualKeyCode::NumpadDivide => Ok(Key::NumpadSlash),
			VirtualKeyCode::NumpadDecimal => Err(()),
			VirtualKeyCode::NumpadComma => Err(()),
			VirtualKeyCode::NumpadEnter => Ok(Key::NumpadEnter),
			VirtualKeyCode::NumpadEquals => Err(()),
			VirtualKeyCode::NumpadMultiply => Ok(Key::NumpadAsterisk),
			VirtualKeyCode::NumpadSubtract => Ok(Key::NumpadMinus),
			VirtualKeyCode::AbntC1 => Err(()),
			VirtualKeyCode::AbntC2 => Err(()),
			VirtualKeyCode::Apostrophe => Ok(Key::Apostrophe),
			VirtualKeyCode::Apps => Err(()),
			VirtualKeyCode::Asterisk => Err(()),
			VirtualKeyCode::At => Err(()),
			VirtualKeyCode::Ax => Err(()),
			VirtualKeyCode::Backslash => Ok(Key::Backslash),
			VirtualKeyCode::Calculator => Err(()),
			VirtualKeyCode::Capital => Ok(Key::CapitalLock),
			VirtualKeyCode::Colon => Err(()),
			VirtualKeyCode::Comma => Ok(Key::Comma),
			VirtualKeyCode::Convert => Err(()),
			VirtualKeyCode::Equals => Ok(Key::Equals),
			VirtualKeyCode::Grave => Ok(Key::Grave),
			VirtualKeyCode::Kana => Err(()),
			VirtualKeyCode::Kanji => Err(()),
			VirtualKeyCode::LAlt => Ok(Key::LAlt),
			VirtualKeyCode::LBracket => Ok(Key::LBracket),
			VirtualKeyCode::LControl => Ok(Key::LControl),
			VirtualKeyCode::LShift => Ok(Key::LShift),
			VirtualKeyCode::LWin => Ok(Key::LWin),
			VirtualKeyCode::Mail => Err(()),
			VirtualKeyCode::MediaSelect => Err(()),
			VirtualKeyCode::MediaStop => Err(()),
			VirtualKeyCode::Minus => Ok(Key::Minus),
			VirtualKeyCode::Mute => Err(()),
			VirtualKeyCode::MyComputer => Err(()),
			VirtualKeyCode::NavigateForward => Err(()),
			VirtualKeyCode::NavigateBackward => Err(()),
			VirtualKeyCode::NextTrack => Err(()),
			VirtualKeyCode::NoConvert => Err(()),
			VirtualKeyCode::OEM102 => Err(()),
			VirtualKeyCode::Period => Ok(Key::Period),
			VirtualKeyCode::PlayPause => Err(()),
			VirtualKeyCode::Plus => Err(()),
			VirtualKeyCode::Power => Err(()),
			VirtualKeyCode::PrevTrack => Err(()),
			VirtualKeyCode::RAlt => Ok(Key::RAlt),
			VirtualKeyCode::RBracket => Ok(Key::RBracket),
			VirtualKeyCode::RControl => Ok(Key::RControl),
			VirtualKeyCode::RShift => Ok(Key::RShift),
			VirtualKeyCode::RWin => Ok(Key::RWin),
			VirtualKeyCode::Semicolon => Ok(Key::Semicolon),
			VirtualKeyCode::Slash => Ok(Key::Slash),
			VirtualKeyCode::Sleep => Err(()),
			VirtualKeyCode::Stop => Err(()),
			VirtualKeyCode::Sysrq => Err(()),
			VirtualKeyCode::Tab => Ok(Key::Tab),
			VirtualKeyCode::Underline => Err(()),
			VirtualKeyCode::Unlabeled => Err(()),
			VirtualKeyCode::VolumeDown => Err(()),
			VirtualKeyCode::VolumeUp => Err(()),
			VirtualKeyCode::Wake => Err(()),
			VirtualKeyCode::WebBack => Err(()),
			VirtualKeyCode::WebFavorites => Err(()),
			VirtualKeyCode::WebForward => Err(()),
			VirtualKeyCode::WebHome => Err(()),
			VirtualKeyCode::WebRefresh => Err(()),
			VirtualKeyCode::WebSearch => Err(()),
			VirtualKeyCode::WebStop => Err(()),
			VirtualKeyCode::Yen => Err(()),
			VirtualKeyCode::Copy => Err(()),
			VirtualKeyCode::Paste => Err(()),
			VirtualKeyCode::Cut => Err(()),
		}
	}
}