Skip to main content

pfx_input/
winit.rs

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}