furmint_input/keyboard.rs
1//! Keyboard input handling
2
3use std::collections::HashSet;
4
5/// Represents a physical keyboard key.
6///
7/// Taken from <https://docs.rs/winit/latest/src/winit/keyboard.rs.html#296-740>
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9#[non_exhaustive]
10pub enum KeyCode {
11 /// <kbd>`</kbd> on a US keyboard. This is also called a backtick or grave.
12 /// This is the <kbd>半角</kbd>/<kbd>全角</kbd>/<kbd>漢字</kbd>
13 /// (hankaku/zenkaku/kanji) key on Japanese keyboards
14 Backquote,
15 /// Used for both the US <kbd>\\</kbd> (on the 101-key layout) and also for the key
16 /// located between the <kbd>"</kbd> and <kbd>Enter</kbd> keys on row C of the 102-,
17 /// 104- and 106-key layouts.
18 /// Labeled <kbd>#</kbd> on a UK (102) keyboard.
19 Backslash,
20 /// <kbd>[</kbd> on a US keyboard.
21 BracketLeft,
22 /// <kbd>]</kbd> on a US keyboard.
23 BracketRight,
24 /// <kbd>,</kbd> on a US keyboard.
25 Comma,
26 /// <kbd>0</kbd> on a US keyboard.
27 Digit0,
28 /// <kbd>1</kbd> on a US keyboard.
29 Digit1,
30 /// <kbd>2</kbd> on a US keyboard.
31 Digit2,
32 /// <kbd>3</kbd> on a US keyboard.
33 Digit3,
34 /// <kbd>4</kbd> on a US keyboard.
35 Digit4,
36 /// <kbd>5</kbd> on a US keyboard.
37 Digit5,
38 /// <kbd>6</kbd> on a US keyboard.
39 Digit6,
40 /// <kbd>7</kbd> on a US keyboard.
41 Digit7,
42 /// <kbd>8</kbd> on a US keyboard.
43 Digit8,
44 /// <kbd>9</kbd> on a US keyboard.
45 Digit9,
46 /// <kbd>=</kbd> on a US keyboard.
47 Equal,
48 /// Located between the left <kbd>Shift</kbd> and <kbd>Z</kbd> keys.
49 /// Labeled <kbd>\\</kbd> on a UK keyboard.
50 IntlBackslash,
51 /// Located between the <kbd>/</kbd> and right <kbd>Shift</kbd> keys.
52 /// Labeled <kbd>\\</kbd> (ro) on a Japanese keyboard.
53 IntlRo,
54 /// Located between the <kbd>=</kbd> and <kbd>Backspace</kbd> keys.
55 /// Labeled <kbd>¥</kbd> (yen) on a Japanese keyboard. <kbd>\\</kbd> on a
56 /// Russian keyboard.
57 IntlYen,
58 /// <kbd>a</kbd> on a US keyboard.
59 /// Labeled <kbd>q</kbd> on an AZERTY (e.g., French) keyboard.
60 KeyA,
61 /// <kbd>b</kbd> on a US keyboard.
62 KeyB,
63 /// <kbd>c</kbd> on a US keyboard.
64 KeyC,
65 /// <kbd>d</kbd> on a US keyboard.
66 KeyD,
67 /// <kbd>e</kbd> on a US keyboard.
68 KeyE,
69 /// <kbd>f</kbd> on a US keyboard.
70 KeyF,
71 /// <kbd>g</kbd> on a US keyboard.
72 KeyG,
73 /// <kbd>h</kbd> on a US keyboard.
74 KeyH,
75 /// <kbd>i</kbd> on a US keyboard.
76 KeyI,
77 /// <kbd>j</kbd> on a US keyboard.
78 KeyJ,
79 /// <kbd>k</kbd> on a US keyboard.
80 KeyK,
81 /// <kbd>l</kbd> on a US keyboard.
82 KeyL,
83 /// <kbd>m</kbd> on a US keyboard.
84 KeyM,
85 /// <kbd>n</kbd> on a US keyboard.
86 KeyN,
87 /// <kbd>o</kbd> on a US keyboard.
88 KeyO,
89 /// <kbd>p</kbd> on a US keyboard.
90 KeyP,
91 /// <kbd>q</kbd> on a US keyboard.
92 /// Labeled <kbd>a</kbd> on an AZERTY (e.g., French) keyboard.
93 KeyQ,
94 /// <kbd>r</kbd> on a US keyboard.
95 KeyR,
96 /// <kbd>s</kbd> on a US keyboard.
97 KeyS,
98 /// <kbd>t</kbd> on a US keyboard.
99 KeyT,
100 /// <kbd>u</kbd> on a US keyboard.
101 KeyU,
102 /// <kbd>v</kbd> on a US keyboard.
103 KeyV,
104 /// <kbd>w</kbd> on a US keyboard.
105 /// Labeled <kbd>z</kbd> on an AZERTY (e.g., French) keyboard.
106 KeyW,
107 /// <kbd>x</kbd> on a US keyboard.
108 KeyX,
109 /// <kbd>y</kbd> on a US keyboard.
110 /// Labeled <kbd>z</kbd> on a QWERTZ (e.g., German) keyboard.
111 KeyY,
112 /// <kbd>z</kbd> on a US keyboard.
113 /// Labeled <kbd>w</kbd> on an AZERTY (e.g., French) keyboard, and <kbd>y</kbd> on a
114 /// QWERTZ (e.g., German) keyboard.
115 KeyZ,
116 /// <kbd>-</kbd> on a US keyboard.
117 Minus,
118 /// <kbd>.</kbd> on a US keyboard.
119 Period,
120 /// <kbd>'</kbd> on a US keyboard.
121 Quote,
122 /// <kbd>;</kbd> on a US keyboard.
123 Semicolon,
124 /// <kbd>/</kbd> on a US keyboard.
125 Slash,
126 /// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
127 AltLeft,
128 /// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
129 /// This is labeled <kbd>AltGr</kbd> on many keyboard layouts.
130 AltRight,
131 /// <kbd>Backspace</kbd> or <kbd>⌫</kbd>.
132 /// Labeled <kbd>Delete</kbd> on Apple keyboards.
133 Backspace,
134 /// <kbd>CapsLock</kbd> or <kbd>⇪</kbd>
135 CapsLock,
136 /// The application context menu key, which is typically found between the right
137 /// <kbd>Super</kbd> key and the right <kbd>Control</kbd> key.
138 ContextMenu,
139 /// <kbd>Control</kbd> or <kbd>⌃</kbd>
140 ControlLeft,
141 /// <kbd>Control</kbd> or <kbd>⌃</kbd>
142 ControlRight,
143 /// <kbd>Enter</kbd> or <kbd>↵</kbd>. Labeled <kbd>Return</kbd> on Apple keyboards.
144 Enter,
145 /// The Windows, <kbd>⌘</kbd>, <kbd>Command</kbd>, or other OS symbol key.
146 SuperLeft,
147 /// The Windows, <kbd>⌘</kbd>, <kbd>Command</kbd>, or other OS symbol key.
148 SuperRight,
149 /// <kbd>Shift</kbd> or <kbd>⇧</kbd>
150 ShiftLeft,
151 /// <kbd>Shift</kbd> or <kbd>⇧</kbd>
152 ShiftRight,
153 /// <kbd> </kbd> (space)
154 Space,
155 /// <kbd>Tab</kbd> or <kbd>⇥</kbd>
156 Tab,
157 /// Japanese: <kbd>変</kbd> (henkan)
158 Convert,
159 /// Japanese: <kbd>カタカナ</kbd>/<kbd>ひらがな</kbd>/<kbd>ローマ字</kbd>
160 /// (katakana/hiragana/romaji)
161 KanaMode,
162 /// Korean: HangulMode <kbd>한/영</kbd> (han/yeong)
163 ///
164 /// Japanese (Mac keyboard): <kbd>か</kbd> (kana)
165 Lang1,
166 /// Korean: Hanja <kbd>한</kbd> (hanja)
167 ///
168 /// Japanese (Mac keyboard): <kbd>英</kbd> (eisu)
169 Lang2,
170 /// Japanese (word-processing keyboard): Katakana
171 Lang3,
172 /// Japanese (word-processing keyboard): Hiragana
173 Lang4,
174 /// Japanese (word-processing keyboard): Zenkaku/Hankaku
175 Lang5,
176 /// Japanese: <kbd>無変換</kbd> (muhenkan)
177 NonConvert,
178 /// <kbd>⌦</kbd>. The forward delete key.
179 /// Note that on Apple keyboards, the key labelled <kbd>Delete</kbd> on the main part of
180 /// the keyboard is encoded as [`Backspace`].
181 ///
182 /// [`Backspace`]: Self::Backspace
183 Delete,
184 /// <kbd>Page Down</kbd>, <kbd>End</kbd>, or <kbd>↘</kbd>
185 End,
186 /// <kbd>Help</kbd>. Not present on standard PC keyboards.
187 Help,
188 /// <kbd>Home</kbd> or <kbd>↖</kbd>
189 Home,
190 /// <kbd>Insert</kbd> or <kbd>Ins</kbd>. Not present on Apple keyboards.
191 Insert,
192 /// <kbd>Page Down</kbd>, <kbd>PgDn</kbd>, or <kbd>⇟</kbd>
193 PageDown,
194 /// <kbd>Page Up</kbd>, <kbd>PgUp</kbd>, or <kbd>⇞</kbd>
195 PageUp,
196 /// <kbd>↓</kbd>
197 ArrowDown,
198 /// <kbd>←</kbd>
199 ArrowLeft,
200 /// <kbd>→</kbd>
201 ArrowRight,
202 /// <kbd>↑</kbd>
203 ArrowUp,
204 /// On the Mac, this is used for the numpad <kbd>Clear</kbd> key.
205 NumLock,
206 /// <kbd>0 Ins</kbd> on a keyboard. <kbd>0</kbd> on a phone or remote control
207 Numpad0,
208 /// <kbd>1 End</kbd> on a keyboard. <kbd>1</kbd> or <kbd>1 QZ</kbd> on a phone or remote
209 /// control
210 Numpad1,
211 /// <kbd>2 ↓</kbd> on a keyboard. <kbd>2 ABC</kbd> on a phone or remote control
212 Numpad2,
213 /// <kbd>3 PgDn</kbd> on a keyboard. <kbd>3 DEF</kbd> on a phone or remote control
214 Numpad3,
215 /// <kbd>4 ←</kbd> on a keyboard. <kbd>4 GHI</kbd> on a phone or remote control
216 Numpad4,
217 /// <kbd>5</kbd> on a keyboard. <kbd>5 JKL</kbd> on a phone or remote control
218 Numpad5,
219 /// <kbd>6 →</kbd> on a keyboard. <kbd>6 MNO</kbd> on a phone or remote control
220 Numpad6,
221 /// <kbd>7 Home</kbd> on a keyboard. <kbd>7 PQRS</kbd> or <kbd>7 PRS</kbd> on a phone
222 /// or remote control
223 Numpad7,
224 /// <kbd>8 ↑</kbd> on a keyboard. <kbd>8 TUV</kbd> on a phone or remote control
225 Numpad8,
226 /// <kbd>9 PgUp</kbd> on a keyboard. <kbd>9 WXYZ</kbd> or <kbd>9 WXY</kbd> on a phone
227 /// or remote control
228 Numpad9,
229 /// <kbd>+</kbd>
230 NumpadAdd,
231 /// Found on the Microsoft Natural Keyboard.
232 NumpadBackspace,
233 /// <kbd>C</kbd> or <kbd>A</kbd> (All Clear). Also for use with numpads that have a
234 /// <kbd>Clear</kbd> key that is separate from the <kbd>NumLock</kbd> key. On the Mac, the
235 /// numpad <kbd>Clear</kbd> key is encoded as [`NumLock`].
236 ///
237 /// [`NumLock`]: Self::NumLock
238 NumpadClear,
239 /// <kbd>C</kbd> (Clear Entry)
240 NumpadClearEntry,
241 /// <kbd>,</kbd> (thousands separator). For locales where the thousands separator
242 /// is a "." (e.g., Brazil), this key may generate a <kbd>.</kbd>.
243 NumpadComma,
244 /// <kbd>. Del</kbd>. For locales where the decimal separator is "," (e.g.,
245 /// Brazil), this key may generate a <kbd>,</kbd>.
246 NumpadDecimal,
247 /// <kbd>/</kbd>
248 NumpadDivide,
249 /// Numpad enter button
250 NumpadEnter,
251 /// <kbd>=</kbd>
252 NumpadEqual,
253 /// <kbd>#</kbd> on a phone or remote control device. This key is typically found
254 /// below the <kbd>9</kbd> key and to the right of the <kbd>0</kbd> key.
255 NumpadHash,
256 /// <kbd>M</kbd> Add current entry to the value stored in memory.
257 NumpadMemoryAdd,
258 /// <kbd>M</kbd> Clear the value stored in memory.
259 NumpadMemoryClear,
260 /// <kbd>M</kbd> Replace the current entry with the value stored in memory.
261 NumpadMemoryRecall,
262 /// <kbd>M</kbd> Replace the value stored in memory with the current entry.
263 NumpadMemoryStore,
264 /// <kbd>M</kbd> Subtract current entry from the value stored in memory.
265 NumpadMemorySubtract,
266 /// <kbd>*</kbd> on a keyboard. For use with numpads that provide mathematical
267 /// operations (<kbd>+</kbd>, <kbd>-</kbd> <kbd>*</kbd> and <kbd>/</kbd>).
268 ///
269 /// Use `NumpadStar` for the <kbd>*</kbd> key on phones and remote controls.
270 NumpadMultiply,
271 /// <kbd>(</kbd> Found on the Microsoft Natural Keyboard.
272 NumpadParenLeft,
273 /// <kbd>)</kbd> Found on the Microsoft Natural Keyboard.
274 NumpadParenRight,
275 /// <kbd>*</kbd> on a phone or remote control device.
276 ///
277 /// This key is typically found below the <kbd>7</kbd> key and to the left of
278 /// the <kbd>0</kbd> key.
279 ///
280 /// Use <kbd>"NumpadMultiply"</kbd> for the <kbd>*</kbd> key on
281 /// numeric keypads.
282 NumpadStar,
283 /// <kbd>-</kbd>
284 NumpadSubtract,
285 /// <kbd>Esc</kbd> or <kbd>⎋</kbd>
286 Escape,
287 /// <kbd>Fn</kbd> This is typically a hardware key that does not generate a separate code.
288 Fn,
289 /// <kbd>FLock</kbd> or <kbd>FnLock</kbd>. Function Lock key. Found on the Microsoft
290 /// Natural Keyboard.
291 FnLock,
292 /// <kbd>PrtScr SysRq</kbd> or <kbd>Print Screen</kbd>
293 PrintScreen,
294 /// <kbd>Scroll Lock</kbd>
295 ScrollLock,
296 /// <kbd>Pause Break</kbd>
297 Pause,
298 /// Some laptops place this key to the left of the <kbd>↑</kbd> key.
299 ///
300 /// This also the "back" button (triangle) on Android.
301 BrowserBack,
302 /// Some laptops place this key to the right of the <kbd>↑</kbd> key.
303 BrowserForward,
304 /// The "home" button on Android.
305 BrowserHome,
306 /// <kbd>Eject</kbd> or <kbd>⏏</kbd>. This key is placed in the function section on some Apple
307 /// keyboards.
308 Eject,
309 /// Sometimes labelled <kbd>My Computer</kbd> on the keyboard
310 LaunchApp1,
311 /// Sometimes labelled <kbd>Calculator</kbd> on the keyboard
312 LaunchApp2,
313 /// This key is placed in the function section on some Apple keyboards, replacing the
314 /// <kbd>Eject</kbd> key.
315 Power,
316 /// Legacy modifier key. Also called "Super" in certain places.
317 Meta,
318 /// Legacy modifier key.
319 Hyper,
320 /// Found on Sun’s USB keyboard.
321 Again,
322 /// Found on Sun’s USB keyboard.
323 Copy,
324 /// Found on Sun’s USB keyboard.
325 Cut,
326 /// Found on Sun’s USB keyboard.
327 Find,
328 /// Found on Sun’s USB keyboard.
329 Open,
330 /// Found on Sun’s USB keyboard.
331 Paste,
332 /// Found on Sun’s USB keyboard.
333 Props,
334 /// Found on Sun’s USB keyboard.
335 Select,
336 /// Found on Sun’s USB keyboard.
337 Undo,
338 /// Use for dedicated <kbd>ひらがな</kbd> key found on some Japanese word processing keyboards.
339 Hiragana,
340 /// Use for dedicated <kbd>カタカナ</kbd> key found on some Japanese word processing keyboards.
341 Katakana,
342 /// General-purpose function key.
343 /// Usually found at the top of the keyboard.
344 F1,
345 /// General-purpose function key.
346 /// Usually found at the top of the keyboard.
347 F2,
348 /// General-purpose function key.
349 /// Usually found at the top of the keyboard.
350 F3,
351 /// General-purpose function key.
352 /// Usually found at the top of the keyboard.
353 F4,
354 /// General-purpose function key.
355 /// Usually found at the top of the keyboard.
356 F5,
357 /// General-purpose function key.
358 /// Usually found at the top of the keyboard.
359 F6,
360 /// General-purpose function key.
361 /// Usually found at the top of the keyboard.
362 F7,
363 /// General-purpose function key.
364 /// Usually found at the top of the keyboard.
365 F8,
366 /// General-purpose function key.
367 /// Usually found at the top of the keyboard.
368 F9,
369 /// General-purpose function key.
370 /// Usually found at the top of the keyboard.
371 F10,
372 /// General-purpose function key.
373 /// Usually found at the top of the keyboard.
374 F11,
375 /// General-purpose function key.
376 /// Usually found at the top of the keyboard.
377 F12,
378 /// General-purpose function key.
379 /// Usually found at the top of the keyboard.
380 F13,
381 /// General-purpose function key.
382 /// Usually found at the top of the keyboard.
383 F14,
384 /// General-purpose function key.
385 /// Usually found at the top of the keyboard.
386 F15,
387 /// General-purpose function key.
388 /// Usually found at the top of the keyboard.
389 F16,
390 /// General-purpose function key.
391 /// Usually found at the top of the keyboard.
392 F17,
393 /// General-purpose function key.
394 /// Usually found at the top of the keyboard.
395 F18,
396 /// General-purpose function key.
397 /// Usually found at the top of the keyboard.
398 F19,
399 /// General-purpose function key.
400 /// Usually found at the top of the keyboard.
401 F20,
402 /// General-purpose function key.
403 /// Usually found at the top of the keyboard.
404 F21,
405 /// General-purpose function key.
406 /// Usually found at the top of the keyboard.
407 F22,
408 /// General-purpose function key.
409 /// Usually found at the top of the keyboard.
410 F23,
411 /// General-purpose function key.
412 /// Usually found at the top of the keyboard.
413 F24,
414 /// General-purpose function key.
415 F25,
416 /// General-purpose function key.
417 F26,
418 /// General-purpose function key.
419 F27,
420 /// General-purpose function key.
421 F28,
422 /// General-purpose function key.
423 F29,
424 /// General-purpose function key.
425 F30,
426 /// General-purpose function key.
427 F31,
428 /// General-purpose function key.
429 F32,
430 /// General-purpose function key.
431 F33,
432 /// General-purpose function key.
433 F34,
434 /// General-purpose function key.
435 F35,
436}
437
438/// Stores the current keyboard state
439#[derive(Debug, Default)]
440pub struct KeyboardInput {
441 pressed: HashSet<KeyCode>,
442 just_pressed: HashSet<KeyCode>,
443 just_released: HashSet<KeyCode>,
444}
445
446impl KeyboardInput {
447 /// Marks a key as pressed
448 pub fn press(&mut self, key: KeyCode) {
449 if self.pressed.insert(key) {
450 self.just_pressed.insert(key);
451 }
452 }
453
454 /// Marks a key as released
455 pub fn release(&mut self, key: KeyCode) {
456 if self.pressed.remove(&key) {
457 self.just_released.insert(key);
458 }
459 }
460
461 /// Returns `true` if the key is currently held down
462 pub fn pressed(&self, key: KeyCode) -> bool {
463 self.pressed.contains(&key)
464 }
465
466 /// Returns `true` if the key was pressed during this frame
467 pub fn just_pressed(&self, key: KeyCode) -> bool {
468 self.just_pressed.contains(&key)
469 }
470
471 /// Returns `true` if the key was released during this frame
472 pub fn just_released(&self, key: KeyCode) -> bool {
473 self.just_released.contains(&key)
474 }
475
476 /// Clears the state
477 pub fn clear(&mut self) {
478 self.just_pressed.clear();
479 self.just_released.clear();
480 }
481}
482
483impl KeyCode {
484 /// Is this key a modifier?
485 pub fn is_modifier(self) -> bool {
486 matches!(
487 self,
488 KeyCode::ShiftLeft
489 | KeyCode::ShiftRight
490 | KeyCode::ControlLeft
491 | KeyCode::ControlRight
492 | KeyCode::AltLeft
493 | KeyCode::AltRight
494 | KeyCode::SuperLeft
495 | KeyCode::SuperRight
496 )
497 }
498}