ashlar_native/menu/
accelerator.rs1use ashlar_command::shortcut::{Chord, Mods};
6
7#[deprecated(note = "use ashlar_command::shortcut::Chord")]
10pub type Accelerator = Chord;
11
12#[deprecated(note = "use ashlar_command::shortcut::Mods")]
14pub type Modifiers = Mods;
15
16#[deprecated(note = "use ashlar_command::menu::menu_chord")]
18pub fn menu_accelerator(text: &str) -> Option<Chord> {
19 ashlar_command::menu::menu_chord(text)
20}
21
22#[cfg(any(target_os = "macos", target_os = "windows"))]
24pub fn to_muda(chord: &Chord) -> Option<muda::accelerator::Accelerator> {
25 use muda::accelerator::{CMD_OR_CTRL, Code, Modifiers as M};
26 let code: Code = crate::key_code::code_name(chord)?.parse().ok()?;
27 let mut mods = M::empty();
28 for (on, m) in [(chord.mods.command, CMD_OR_CTRL), (chord.mods.ctrl, M::CONTROL), (chord.mods.alt, M::ALT), (chord.mods.shift, M::SHIFT)] {
29 if on {
30 mods |= m;
31 }
32 }
33 Some(muda::accelerator::Accelerator::new(mods, code))
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 fn chord(text: &str) -> Chord {
41 Chord::parse(text).unwrap_or_else(|e| panic!("{e}"))
42 }
43
44 #[test]
45 fn chords_map_to_physical_key_codes() {
46 let cases = [
47 ("Mod+Shift+S", "KeyS"),
48 ("Mod+0", "Digit0"),
49 ("Mod++", "Equal"),
50 ("Mod+=", "Equal"),
51 ("Mod+Alt+;", "Semicolon"),
52 ("F5", "F5"),
53 ("Mod+Left", "ArrowLeft"),
54 ("Option+Return", "Enter"),
55 ("Mod+`", "Backquote"),
56 ("Mod+PageDown", "PageDown"),
57 ("⌘⇧[", "BracketLeft"),
58 ];
59 for (text, code) in cases {
60 assert_eq!(crate::key_code::code_name(&chord(text)).as_deref(), Some(code), "{text}");
61 }
62 assert_eq!(crate::key_code::code_name(&chord("Mod+é")), None);
63 }
64
65 #[cfg(any(target_os = "macos", target_os = "windows"))]
66 #[test]
67 fn chords_become_muda_accelerators() {
68 use muda::accelerator::{Accelerator as A, CMD_OR_CTRL, Code, Modifiers as M};
69 assert_eq!(to_muda(&chord("Mod+Shift+S")), Some(A::new(CMD_OR_CTRL | M::SHIFT, Code::KeyS)));
70 assert_eq!(to_muda(&chord("Ctrl+Alt+Delete")), Some(A::new(M::CONTROL | M::ALT, Code::Delete)));
71 assert_eq!(to_muda(&chord("F12")), Some(A::new(M::empty(), Code::F12)));
72 for text in ["Mod+F24", "Mod+Insert", "Mod+Space", "Mod+Tab", "Mod+Escape", "Mod+/", "Mod+'", "Mod+\\", "Mod+,", "Mod+."] {
74 assert!(to_muda(&chord(text)).is_some(), "{text}");
75 }
76 assert!(to_muda(&chord("Mod+é")).is_none());
77 }
78}