1use winit::event::{ElementState, MouseScrollDelta, WindowEvent};
2use winit::keyboard::{KeyCode, PhysicalKey};
3
4use crate::device::{Key, MouseButton};
5use crate::event::InputEvent;
6use crate::layout::KeyLabels;
7
8pub const PIXELS_PER_LINE: f32 = 40.0;
9
10pub fn event(event: &WindowEvent) -> Option<InputEvent> {
11 match event {
12 WindowEvent::KeyboardInput {
13 event,
14 is_synthetic,
15 ..
16 } => {
17 let pressed = event.state == ElementState::Pressed;
18 if event.repeat || (*is_synthetic && pressed) {
19 return None;
20 }
21 let PhysicalKey::Code(code) = event.physical_key else {
22 return None;
23 };
24 Some(InputEvent::Key {
25 key: key(code)?,
26 pressed,
27 })
28 }
29 WindowEvent::MouseInput { state, button, .. } => Some(InputEvent::MouseButton {
30 button: mouse_button(*button)?,
31 pressed: *state == ElementState::Pressed,
32 }),
33 WindowEvent::MouseWheel { delta, .. } => {
34 let (x, y) = match *delta {
35 MouseScrollDelta::LineDelta(x, y) => (x, y),
36 MouseScrollDelta::PixelDelta(position) => (
37 position.x as f32 / PIXELS_PER_LINE,
38 position.y as f32 / PIXELS_PER_LINE,
39 ),
40 };
41 Some(InputEvent::Wheel { x, y })
42 }
43 WindowEvent::CursorMoved { position, .. } => Some(InputEvent::PointerMoved {
44 window: [position.x as f32, position.y as f32],
45 }),
46 WindowEvent::CursorLeft { .. } => Some(InputEvent::PointerLeft),
47 WindowEvent::Focused(false) => Some(InputEvent::FocusLost),
48 _ => None,
49 }
50}
51
52#[cfg(any(windows, target_os = "macos", target_os = "linux"))]
53pub fn learn(labels: &mut KeyLabels, event: &WindowEvent) -> bool {
54 use winit::keyboard::Key as Logical;
55 use winit::platform::modifier_supplement::KeyEventExtModifierSupplement;
56 let WindowEvent::KeyboardInput {
57 event,
58 is_synthetic: false,
59 ..
60 } = event
61 else {
62 return false;
63 };
64 if event.state != ElementState::Pressed {
65 return false;
66 }
67 let PhysicalKey::Code(code) = event.physical_key else {
68 return false;
69 };
70 let Some(key) = key(code) else {
71 return false;
72 };
73 match event.key_without_modifiers() {
74 Logical::Character(text) => labels.learn(key, &text),
75 Logical::Dead(Some(mark)) => labels.learn(key, mark.encode_utf8(&mut [0; 4])),
76 _ => false,
77 }
78}
79
80#[cfg(not(any(windows, target_os = "macos", target_os = "linux")))]
81pub fn learn(_labels: &mut KeyLabels, _event: &WindowEvent) -> bool {
82 false
83}
84
85pub fn mouse_button(button: winit::event::MouseButton) -> Option<MouseButton> {
86 match button {
87 winit::event::MouseButton::Left => Some(MouseButton::Left),
88 winit::event::MouseButton::Right => Some(MouseButton::Right),
89 winit::event::MouseButton::Middle => Some(MouseButton::Middle),
90 winit::event::MouseButton::Back => Some(MouseButton::Back),
91 winit::event::MouseButton::Forward => Some(MouseButton::Forward),
92 winit::event::MouseButton::Other(_) => None,
93 }
94}
95
96pub fn key(code: KeyCode) -> Option<Key> {
97 Some(match code {
98 KeyCode::KeyA => Key::A,
99 KeyCode::KeyB => Key::B,
100 KeyCode::KeyC => Key::C,
101 KeyCode::KeyD => Key::D,
102 KeyCode::KeyE => Key::E,
103 KeyCode::KeyF => Key::F,
104 KeyCode::KeyG => Key::G,
105 KeyCode::KeyH => Key::H,
106 KeyCode::KeyI => Key::I,
107 KeyCode::KeyJ => Key::J,
108 KeyCode::KeyK => Key::K,
109 KeyCode::KeyL => Key::L,
110 KeyCode::KeyM => Key::M,
111 KeyCode::KeyN => Key::N,
112 KeyCode::KeyO => Key::O,
113 KeyCode::KeyP => Key::P,
114 KeyCode::KeyQ => Key::Q,
115 KeyCode::KeyR => Key::R,
116 KeyCode::KeyS => Key::S,
117 KeyCode::KeyT => Key::T,
118 KeyCode::KeyU => Key::U,
119 KeyCode::KeyV => Key::V,
120 KeyCode::KeyW => Key::W,
121 KeyCode::KeyX => Key::X,
122 KeyCode::KeyY => Key::Y,
123 KeyCode::KeyZ => Key::Z,
124 KeyCode::Digit0 => Key::Digit0,
125 KeyCode::Digit1 => Key::Digit1,
126 KeyCode::Digit2 => Key::Digit2,
127 KeyCode::Digit3 => Key::Digit3,
128 KeyCode::Digit4 => Key::Digit4,
129 KeyCode::Digit5 => Key::Digit5,
130 KeyCode::Digit6 => Key::Digit6,
131 KeyCode::Digit7 => Key::Digit7,
132 KeyCode::Digit8 => Key::Digit8,
133 KeyCode::Digit9 => Key::Digit9,
134 KeyCode::F1 => Key::F1,
135 KeyCode::F2 => Key::F2,
136 KeyCode::F3 => Key::F3,
137 KeyCode::F4 => Key::F4,
138 KeyCode::F5 => Key::F5,
139 KeyCode::F6 => Key::F6,
140 KeyCode::F7 => Key::F7,
141 KeyCode::F8 => Key::F8,
142 KeyCode::F9 => Key::F9,
143 KeyCode::F10 => Key::F10,
144 KeyCode::F11 => Key::F11,
145 KeyCode::F12 => Key::F12,
146 KeyCode::ArrowUp => Key::Up,
147 KeyCode::ArrowDown => Key::Down,
148 KeyCode::ArrowLeft => Key::Left,
149 KeyCode::ArrowRight => Key::Right,
150 KeyCode::Escape => Key::Escape,
151 KeyCode::Tab => Key::Tab,
152 KeyCode::CapsLock => Key::CapsLock,
153 KeyCode::ShiftLeft => Key::ShiftLeft,
154 KeyCode::ShiftRight => Key::ShiftRight,
155 KeyCode::ControlLeft => Key::ControlLeft,
156 KeyCode::ControlRight => Key::ControlRight,
157 KeyCode::AltLeft => Key::AltLeft,
158 KeyCode::AltRight => Key::AltRight,
159 KeyCode::SuperLeft => Key::SuperLeft,
160 KeyCode::SuperRight => Key::SuperRight,
161 KeyCode::ContextMenu => Key::ContextMenu,
162 KeyCode::Space => Key::Space,
163 KeyCode::Enter => Key::Enter,
164 KeyCode::Backspace => Key::Backspace,
165 KeyCode::Insert => Key::Insert,
166 KeyCode::Delete => Key::Delete,
167 KeyCode::Home => Key::Home,
168 KeyCode::End => Key::End,
169 KeyCode::PageUp => Key::PageUp,
170 KeyCode::PageDown => Key::PageDown,
171 KeyCode::PrintScreen => Key::PrintScreen,
172 KeyCode::ScrollLock => Key::ScrollLock,
173 KeyCode::Pause => Key::Pause,
174 KeyCode::NumLock => Key::NumLock,
175 KeyCode::Minus => Key::Minus,
176 KeyCode::Equal => Key::Equal,
177 KeyCode::BracketLeft => Key::BracketLeft,
178 KeyCode::BracketRight => Key::BracketRight,
179 KeyCode::Backslash => Key::Backslash,
180 KeyCode::Semicolon => Key::Semicolon,
181 KeyCode::Quote => Key::Quote,
182 KeyCode::Backquote => Key::Backquote,
183 KeyCode::Comma => Key::Comma,
184 KeyCode::Period => Key::Period,
185 KeyCode::Slash => Key::Slash,
186 KeyCode::Numpad0 => Key::Numpad0,
187 KeyCode::Numpad1 => Key::Numpad1,
188 KeyCode::Numpad2 => Key::Numpad2,
189 KeyCode::Numpad3 => Key::Numpad3,
190 KeyCode::Numpad4 => Key::Numpad4,
191 KeyCode::Numpad5 => Key::Numpad5,
192 KeyCode::Numpad6 => Key::Numpad6,
193 KeyCode::Numpad7 => Key::Numpad7,
194 KeyCode::Numpad8 => Key::Numpad8,
195 KeyCode::Numpad9 => Key::Numpad9,
196 KeyCode::NumpadAdd => Key::NumpadAdd,
197 KeyCode::NumpadSubtract => Key::NumpadSubtract,
198 KeyCode::NumpadMultiply => Key::NumpadMultiply,
199 KeyCode::NumpadDivide => Key::NumpadDivide,
200 KeyCode::NumpadDecimal => Key::NumpadDecimal,
201 KeyCode::NumpadEnter => Key::NumpadEnter,
202 _ => return None,
203 })
204}