Skip to main content

egui/data/
key.rs

1/// Keyboard keys.
2///
3/// egui usually uses logical keys, i.e. after applying any user keymap.\
4// See comment at the end of `Key { … }` on how to add new keys.
5#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
7pub enum Key {
8    // ----------------------------------------------
9    // Commands:
10    ArrowDown,
11    ArrowLeft,
12    ArrowRight,
13    ArrowUp,
14
15    Escape,
16    Tab,
17    Backspace,
18    Enter,
19    Space,
20
21    Insert,
22    Delete,
23    Home,
24    End,
25    PageUp,
26    PageDown,
27
28    Copy,
29    Cut,
30    Paste,
31
32    // ----------------------------------------------
33    // Punctuation:
34    /// `:`
35    Colon,
36
37    /// `,`
38    Comma,
39
40    /// `\`
41    Backslash,
42
43    /// `/`
44    Slash,
45
46    /// `|`, a vertical bar
47    Pipe,
48
49    /// `?`
50    Questionmark,
51
52    // '!'
53    Exclamationmark,
54
55    // `[`
56    OpenBracket,
57
58    // `]`
59    CloseBracket,
60
61    // `{`
62    OpenCurlyBracket,
63
64    // `}`
65    CloseCurlyBracket,
66
67    /// Also known as "backquote" or "grave"
68    Backtick,
69
70    /// `-`
71    Minus,
72
73    /// `.`
74    Period,
75
76    /// `+`
77    Plus,
78
79    /// `=`
80    Equals,
81
82    /// `;`
83    Semicolon,
84
85    /// `'`
86    Quote,
87
88    // ----------------------------------------------
89    // Digits:
90    /// `0` (from main row or numpad)
91    Num0,
92
93    /// `1` (from main row or numpad)
94    Num1,
95
96    /// `2` (from main row or numpad)
97    Num2,
98
99    /// `3` (from main row or numpad)
100    Num3,
101
102    /// `4` (from main row or numpad)
103    Num4,
104
105    /// `5` (from main row or numpad)
106    Num5,
107
108    /// `6` (from main row or numpad)
109    Num6,
110
111    /// `7` (from main row or numpad)
112    Num7,
113
114    /// `8` (from main row or numpad)
115    Num8,
116
117    /// `9` (from main row or numpad)
118    Num9,
119
120    // ----------------------------------------------
121    // Letters:
122    A, // Used for cmd+A (select All)
123    B,
124    C, // |CMD COPY|
125    D, // |CMD BOOKMARK|
126    E, // |CMD SEARCH|
127    F, // |CMD FIND firefox & chrome|
128    G, // |CMD FIND chrome|
129    H, // |CMD History|
130    I, // italics
131    J, // |CMD SEARCH firefox/DOWNLOAD chrome|
132    K, // Used for ctrl+K (delete text after cursor)
133    L,
134    M,
135    N,
136    O, // |CMD OPEN|
137    P, // |CMD PRINT|
138    Q,
139    R, // |CMD REFRESH|
140    S, // |CMD SAVE|
141    T, // |CMD TAB|
142    U, // Used for ctrl+U (delete text before cursor)
143    V, // |CMD PASTE|
144    W, // Used for ctrl+W (delete previous word)
145    X, // |CMD CUT|
146    Y,
147    Z, // |CMD UNDO|
148
149    // ----------------------------------------------
150    // Function keys:
151    F1,
152    F2,
153    F3,
154    F4,
155    F5, // |CMD REFRESH|
156    F6,
157    F7,
158    F8,
159    F9,
160    F10,
161    F11,
162    F12,
163    F13,
164    F14,
165    F15,
166    F16,
167    F17,
168    F18,
169    F19,
170    F20,
171    F21,
172    F22,
173    F23,
174    F24,
175    F25,
176    F26,
177    F27,
178    F28,
179    F29,
180    F30,
181    F31,
182    F32,
183    F33,
184    F34,
185    F35,
186
187    /// Back navigation key from multimedia keyboard.
188    /// Android sends this key on Back button press.
189    /// Does not work on Web.
190    BrowserBack,
191
192    // ----------------------------------------------
193    // Modifier keys (exposed as distinct left/right variants so that
194    // games and input-capture UIs can bind them independently). egui's
195    // `Modifiers` struct still collapses both sides for the common case
196    // (e.g. "Ctrl+C"); these variants are emitted only as physical
197    // `Event::Key` presses.
198    /// Left Shift key.
199    ShiftLeft,
200
201    /// Right Shift key.
202    ShiftRight,
203
204    /// Left Control key.
205    ControlLeft,
206
207    /// Right Control key.
208    ControlRight,
209
210    /// Left Alt / Option key.
211    AltLeft,
212
213    /// Right Alt / `AltGr` / Option key.
214    AltRight,
215
216    /// Left Super / Meta / Command / Windows key.
217    SuperLeft,
218
219    /// Right Super / Meta / Command / Windows key.
220    SuperRight,
221
222    // ----------------------------------------------
223    // International keys — physical positions that only exist on
224    // non-US keyboards.
225    /// ISO 102nd key: physically located between the left Shift and Z
226    /// on ISO layouts. On French AZERTY it produces `<>|`; on UK
227    /// QWERTY a secondary `\` / `|`. Missing from US ANSI keyboards.
228    IntlBackslash,
229    // When adding keys, remember to also update:
230    // * crates/egui-winit/src/lib.rs
231    // * Key::ALL
232    // * Key::from_name
233    // You should test that it works using the "Input Event History" window in the egui demo app.
234    // Make sure to test both natively and on web!
235    // Also: don't add keys last; add them to the group they best belong to.
236}
237
238impl Key {
239    /// All egui keys
240    pub const ALL: &'static [Self] = &[
241        // Commands:
242        Self::ArrowDown,
243        Self::ArrowLeft,
244        Self::ArrowRight,
245        Self::ArrowUp,
246        Self::Escape,
247        Self::Tab,
248        Self::Backspace,
249        Self::Enter,
250        Self::Insert,
251        Self::Delete,
252        Self::Home,
253        Self::End,
254        Self::PageUp,
255        Self::PageDown,
256        Self::Copy,
257        Self::Cut,
258        Self::Paste,
259        // Punctuation:
260        Self::Space,
261        Self::Colon,
262        Self::Comma,
263        Self::Minus,
264        Self::Period,
265        Self::Plus,
266        Self::Equals,
267        Self::Semicolon,
268        Self::OpenBracket,
269        Self::CloseBracket,
270        Self::OpenCurlyBracket,
271        Self::CloseCurlyBracket,
272        Self::Backtick,
273        Self::Backslash,
274        Self::Slash,
275        Self::Pipe,
276        Self::Questionmark,
277        Self::Exclamationmark,
278        Self::Quote,
279        // Digits:
280        Self::Num0,
281        Self::Num1,
282        Self::Num2,
283        Self::Num3,
284        Self::Num4,
285        Self::Num5,
286        Self::Num6,
287        Self::Num7,
288        Self::Num8,
289        Self::Num9,
290        // Letters:
291        Self::A,
292        Self::B,
293        Self::C,
294        Self::D,
295        Self::E,
296        Self::F,
297        Self::G,
298        Self::H,
299        Self::I,
300        Self::J,
301        Self::K,
302        Self::L,
303        Self::M,
304        Self::N,
305        Self::O,
306        Self::P,
307        Self::Q,
308        Self::R,
309        Self::S,
310        Self::T,
311        Self::U,
312        Self::V,
313        Self::W,
314        Self::X,
315        Self::Y,
316        Self::Z,
317        // Function keys:
318        Self::F1,
319        Self::F2,
320        Self::F3,
321        Self::F4,
322        Self::F5,
323        Self::F6,
324        Self::F7,
325        Self::F8,
326        Self::F9,
327        Self::F10,
328        Self::F11,
329        Self::F12,
330        Self::F13,
331        Self::F14,
332        Self::F15,
333        Self::F16,
334        Self::F17,
335        Self::F18,
336        Self::F19,
337        Self::F20,
338        Self::F21,
339        Self::F22,
340        Self::F23,
341        Self::F24,
342        Self::F25,
343        Self::F26,
344        Self::F27,
345        Self::F28,
346        Self::F29,
347        Self::F30,
348        Self::F31,
349        Self::F32,
350        Self::F33,
351        Self::F34,
352        Self::F35,
353        // Navigation keys:
354        Self::BrowserBack,
355        // Modifier keys (physical L/R):
356        Self::ShiftLeft,
357        Self::ShiftRight,
358        Self::ControlLeft,
359        Self::ControlRight,
360        Self::AltLeft,
361        Self::AltRight,
362        Self::SuperLeft,
363        Self::SuperRight,
364        // International keys:
365        Self::IntlBackslash,
366    ];
367
368    /// Converts `"A"` to `Key::A`, `Space` to `Key::Space`, etc.
369    ///
370    /// Makes sense for logical keys.
371    ///
372    /// This will parse the output of both [`Self::name`] and [`Self::symbol_or_name`],
373    /// but will also parse single characters, so that both `"-"` and `"Minus"` will return `Key::Minus`.
374    ///
375    /// This should support both the names generated in a web browser,
376    /// and by winit. Please test on both with `eframe`.
377    pub fn from_name(key: &str) -> Option<Self> {
378        Some(match key {
379            "⏷" | "ArrowDown" | "Down" => Self::ArrowDown,
380            "⏴" | "ArrowLeft" | "Left" => Self::ArrowLeft,
381            "⏵" | "ArrowRight" | "Right" => Self::ArrowRight,
382            "⏶" | "ArrowUp" | "Up" => Self::ArrowUp,
383
384            "Escape" | "Esc" => Self::Escape,
385            "Tab" => Self::Tab,
386            "Backspace" => Self::Backspace,
387            "Enter" | "Return" | "NumpadEnter" => Self::Enter,
388
389            "Help" | "Insert" => Self::Insert,
390            "Delete" => Self::Delete,
391            "Home" => Self::Home,
392            "End" => Self::End,
393            "PageUp" => Self::PageUp,
394            "PageDown" => Self::PageDown,
395
396            "Copy" => Self::Copy,
397            "Cut" => Self::Cut,
398            "Paste" => Self::Paste,
399
400            " " | "Space" => Self::Space,
401            ":" | "Colon" => Self::Colon,
402            "," | "Comma" | "NumpadComma" => Self::Comma,
403            "-" | "−" | "Minus" | "NumpadSubtract" => Self::Minus,
404            "." | "Period" | "NumpadDecimal" => Self::Period,
405            "+" | "Plus" | "NumpadAdd" => Self::Plus,
406            "=" | "Equal" | "Equals" | "NumpadEqual" => Self::Equals,
407            ";" | "Semicolon" => Self::Semicolon,
408            "\\" | "Backslash" => Self::Backslash,
409            "/" | "Slash" | "NumpadDivide" => Self::Slash,
410            "|" | "Pipe" => Self::Pipe,
411            "?" | "Questionmark" => Self::Questionmark,
412            "!" | "Exclamationmark" => Self::Exclamationmark,
413            "[" | "OpenBracket" | "BracketLeft" => Self::OpenBracket,
414            "]" | "CloseBracket" | "BracketRight" => Self::CloseBracket,
415            "{" | "OpenCurlyBracket" => Self::OpenCurlyBracket,
416            "}" | "CloseCurlyBracket" => Self::CloseCurlyBracket,
417            "`" | "Backtick" | "Backquote" | "Grave" => Self::Backtick,
418            "'" | "Quote" => Self::Quote,
419
420            "0" | "Digit0" | "Numpad0" => Self::Num0,
421            "1" | "Digit1" | "Numpad1" => Self::Num1,
422            "2" | "Digit2" | "Numpad2" => Self::Num2,
423            "3" | "Digit3" | "Numpad3" => Self::Num3,
424            "4" | "Digit4" | "Numpad4" => Self::Num4,
425            "5" | "Digit5" | "Numpad5" => Self::Num5,
426            "6" | "Digit6" | "Numpad6" => Self::Num6,
427            "7" | "Digit7" | "Numpad7" => Self::Num7,
428            "8" | "Digit8" | "Numpad8" => Self::Num8,
429            "9" | "Digit9" | "Numpad9" => Self::Num9,
430
431            "a" | "A" | "KeyA" => Self::A,
432            "b" | "B" | "KeyB" => Self::B,
433            "c" | "C" | "KeyC" => Self::C,
434            "d" | "D" | "KeyD" => Self::D,
435            "e" | "E" | "KeyE" => Self::E,
436            "f" | "F" | "KeyF" => Self::F,
437            "g" | "G" | "KeyG" => Self::G,
438            "h" | "H" | "KeyH" => Self::H,
439            "i" | "I" | "KeyI" => Self::I,
440            "j" | "J" | "KeyJ" => Self::J,
441            "k" | "K" | "KeyK" => Self::K,
442            "l" | "L" | "KeyL" => Self::L,
443            "m" | "M" | "KeyM" => Self::M,
444            "n" | "N" | "KeyN" => Self::N,
445            "o" | "O" | "KeyO" => Self::O,
446            "p" | "P" | "KeyP" => Self::P,
447            "q" | "Q" | "KeyQ" => Self::Q,
448            "r" | "R" | "KeyR" => Self::R,
449            "s" | "S" | "KeyS" => Self::S,
450            "t" | "T" | "KeyT" => Self::T,
451            "u" | "U" | "KeyU" => Self::U,
452            "v" | "V" | "KeyV" => Self::V,
453            "w" | "W" | "KeyW" => Self::W,
454            "x" | "X" | "KeyX" => Self::X,
455            "y" | "Y" | "KeyY" => Self::Y,
456            "z" | "Z" | "KeyZ" => Self::Z,
457
458            "F1" => Self::F1,
459            "F2" => Self::F2,
460            "F3" => Self::F3,
461            "F4" => Self::F4,
462            "F5" => Self::F5,
463            "F6" => Self::F6,
464            "F7" => Self::F7,
465            "F8" => Self::F8,
466            "F9" => Self::F9,
467            "F10" => Self::F10,
468            "F11" => Self::F11,
469            "F12" => Self::F12,
470            "F13" => Self::F13,
471            "F14" => Self::F14,
472            "F15" => Self::F15,
473            "F16" => Self::F16,
474            "F17" => Self::F17,
475            "F18" => Self::F18,
476            "F19" => Self::F19,
477            "F20" => Self::F20,
478            "F21" => Self::F21,
479            "F22" => Self::F22,
480            "F23" => Self::F23,
481            "F24" => Self::F24,
482            "F25" => Self::F25,
483            "F26" => Self::F26,
484            "F27" => Self::F27,
485            "F28" => Self::F28,
486            "F29" => Self::F29,
487            "F30" => Self::F30,
488            "F31" => Self::F31,
489            "F32" => Self::F32,
490            "F33" => Self::F33,
491            "F34" => Self::F34,
492            "F35" => Self::F35,
493
494            "BrowserBack" => Self::BrowserBack,
495
496            "ShiftLeft" => Self::ShiftLeft,
497            "ShiftRight" => Self::ShiftRight,
498            "ControlLeft" => Self::ControlLeft,
499            "ControlRight" => Self::ControlRight,
500            "AltLeft" => Self::AltLeft,
501            "AltRight" => Self::AltRight,
502
503            "SuperLeft" | "MetaLeft" | "OSLeft" => Self::SuperLeft,
504            "SuperRight" | "MetaRight" | "OSRight" => Self::SuperRight,
505
506            "IntlBackslash" => Self::IntlBackslash,
507
508            _ => return None,
509        })
510    }
511
512    /// Emoji or name representing the key
513    pub fn symbol_or_name(self) -> &'static str {
514        // TODO(emilk): add support for more unicode symbols (see for instance https://wincent.com/wiki/Unicode_representations_of_modifier_keys).
515        // Before we do we must first make sure they are supported in `Fonts` though,
516        // so perhaps this functions needs to take a `supports_character: impl Fn(char) -> bool` or something.
517        match self {
518            Self::ArrowDown => "⏷",
519            Self::ArrowLeft => "⏴",
520            Self::ArrowRight => "⏵",
521            Self::ArrowUp => "⏶",
522
523            Self::Colon => ":",
524            Self::Comma => ",",
525            Self::Minus => crate::MINUS_CHAR_STR,
526            Self::Period => ".",
527            Self::Plus => "+",
528            Self::Equals => "=",
529            Self::Semicolon => ";",
530            Self::Backslash => "\\",
531            Self::Slash => "/",
532            Self::Pipe => "|",
533            Self::Questionmark => "?",
534            Self::Exclamationmark => "!",
535            Self::OpenBracket => "[",
536            Self::CloseBracket => "]",
537            Self::OpenCurlyBracket => "{",
538            Self::CloseCurlyBracket => "}",
539            Self::Backtick => "`",
540
541            _ => self.name(),
542        }
543    }
544
545    /// Human-readable English name.
546    pub fn name(self) -> &'static str {
547        match self {
548            Self::ArrowDown => "Down",
549            Self::ArrowLeft => "Left",
550            Self::ArrowRight => "Right",
551            Self::ArrowUp => "Up",
552
553            Self::Escape => "Escape",
554            Self::Tab => "Tab",
555            Self::Backspace => "Backspace",
556            Self::Enter => "Enter",
557
558            Self::Insert => "Insert",
559            Self::Delete => "Delete",
560            Self::Home => "Home",
561            Self::End => "End",
562            Self::PageUp => "PageUp",
563            Self::PageDown => "PageDown",
564
565            Self::Copy => "Copy",
566            Self::Cut => "Cut",
567            Self::Paste => "Paste",
568
569            Self::Space => "Space",
570            Self::Colon => "Colon",
571            Self::Comma => "Comma",
572            Self::Minus => "Minus",
573            Self::Period => "Period",
574            Self::Plus => "Plus",
575            Self::Equals => "Equals",
576            Self::Semicolon => "Semicolon",
577            Self::Backslash => "Backslash",
578            Self::Slash => "Slash",
579            Self::Pipe => "Pipe",
580            Self::Questionmark => "Questionmark",
581            Self::Exclamationmark => "Exclamationmark",
582            Self::OpenBracket => "OpenBracket",
583            Self::CloseBracket => "CloseBracket",
584            Self::OpenCurlyBracket => "OpenCurlyBracket",
585            Self::CloseCurlyBracket => "CloseCurlyBracket",
586            Self::Backtick => "Backtick",
587            Self::Quote => "Quote",
588
589            Self::Num0 => "0",
590            Self::Num1 => "1",
591            Self::Num2 => "2",
592            Self::Num3 => "3",
593            Self::Num4 => "4",
594            Self::Num5 => "5",
595            Self::Num6 => "6",
596            Self::Num7 => "7",
597            Self::Num8 => "8",
598            Self::Num9 => "9",
599
600            Self::A => "A",
601            Self::B => "B",
602            Self::C => "C",
603            Self::D => "D",
604            Self::E => "E",
605            Self::F => "F",
606            Self::G => "G",
607            Self::H => "H",
608            Self::I => "I",
609            Self::J => "J",
610            Self::K => "K",
611            Self::L => "L",
612            Self::M => "M",
613            Self::N => "N",
614            Self::O => "O",
615            Self::P => "P",
616            Self::Q => "Q",
617            Self::R => "R",
618            Self::S => "S",
619            Self::T => "T",
620            Self::U => "U",
621            Self::V => "V",
622            Self::W => "W",
623            Self::X => "X",
624            Self::Y => "Y",
625            Self::Z => "Z",
626            Self::F1 => "F1",
627            Self::F2 => "F2",
628            Self::F3 => "F3",
629            Self::F4 => "F4",
630            Self::F5 => "F5",
631            Self::F6 => "F6",
632            Self::F7 => "F7",
633            Self::F8 => "F8",
634            Self::F9 => "F9",
635            Self::F10 => "F10",
636            Self::F11 => "F11",
637            Self::F12 => "F12",
638            Self::F13 => "F13",
639            Self::F14 => "F14",
640            Self::F15 => "F15",
641            Self::F16 => "F16",
642            Self::F17 => "F17",
643            Self::F18 => "F18",
644            Self::F19 => "F19",
645            Self::F20 => "F20",
646            Self::F21 => "F21",
647            Self::F22 => "F22",
648            Self::F23 => "F23",
649            Self::F24 => "F24",
650            Self::F25 => "F25",
651            Self::F26 => "F26",
652            Self::F27 => "F27",
653            Self::F28 => "F28",
654            Self::F29 => "F29",
655            Self::F30 => "F30",
656            Self::F31 => "F31",
657            Self::F32 => "F32",
658            Self::F33 => "F33",
659            Self::F34 => "F34",
660            Self::F35 => "F35",
661
662            Self::BrowserBack => "BrowserBack",
663
664            Self::ShiftLeft => "ShiftLeft",
665            Self::ShiftRight => "ShiftRight",
666            Self::ControlLeft => "ControlLeft",
667            Self::ControlRight => "ControlRight",
668            Self::AltLeft => "AltLeft",
669            Self::AltRight => "AltRight",
670            Self::SuperLeft => "SuperLeft",
671            Self::SuperRight => "SuperRight",
672
673            Self::IntlBackslash => "IntlBackslash",
674        }
675    }
676}
677
678#[test]
679fn test_key_from_name() {
680    assert_eq!(
681        Key::ALL.len(),
682        Key::IntlBackslash as usize + 1,
683        "Some keys are missing in Key::ALL"
684    );
685
686    for &key in Key::ALL {
687        let name = key.name();
688        assert_eq!(
689            Key::from_name(name),
690            Some(key),
691            "Failed to roundtrip {key:?} from name {name:?}"
692        );
693
694        let symbol = key.symbol_or_name();
695        assert_eq!(
696            Key::from_name(symbol),
697            Some(key),
698            "Failed to roundtrip {key:?} from symbol {symbol:?}"
699        );
700    }
701}