ferroui_base/input/platform/
key_gesture_format_info.rs1use crate::input::Key;
2use crate::{FerroLocator, LocatorExtensions};
3use std::collections::HashMap;
4use std::rc::Rc;
5
6#[derive(Clone, Debug, PartialEq)]
12pub struct KeyGestureFormatInfo {
13 platform_key_overrides: Option<HashMap<Key, String>>,
14 meta: String,
15 ctrl: String,
16 alt: String,
17 shift: String,
18}
19
20impl Default for KeyGestureFormatInfo {
21 fn default() -> Self {
22 Self::new(None, "Cmd", "Ctrl", "Alt", "Shift")
23 }
24}
25
26impl KeyGestureFormatInfo {
27 pub fn new(
33 platform_key_overrides: Option<HashMap<Key, String>>,
34 meta: &str,
35 ctrl: &str,
36 alt: &str,
37 shift: &str,
38 ) -> Self {
39 Self {
40 platform_key_overrides,
41 meta: meta.to_string(),
42 ctrl: ctrl.to_string(),
43 alt: alt.to_string(),
44 shift: shift.to_string(),
45 }
46 }
47
48 pub fn invariant() -> Rc<KeyGestureFormatInfo> {
50 crate::ferro_thread_local! {
51 static INVARIANT: Rc<KeyGestureFormatInfo> = Rc::new(KeyGestureFormatInfo::default());
52 }
53 INVARIANT.with(Rc::clone)
54 }
55
56 pub fn meta(&self) -> &str {
58 &self.meta
59 }
60
61 pub fn ctrl(&self) -> &str {
63 &self.ctrl
64 }
65
66 pub fn alt(&self) -> &str {
68 &self.alt
69 }
70
71 pub fn shift(&self) -> &str {
73 &self.shift
74 }
75
76 pub fn get_instance(format_provider: Option<Rc<KeyGestureFormatInfo>>) -> Rc<KeyGestureFormatInfo> {
79 format_provider
80 .or_else(|| FerroLocator::current().get_service::<KeyGestureFormatInfo>())
81 .unwrap_or_else(Self::invariant)
82 }
83
84 fn common_key_override(key: Key) -> Option<&'static str> {
87 Some(match key {
88 Key::Add => "+",
89 Key::D0 => "0",
90 Key::D1 => "1",
91 Key::D2 => "2",
92 Key::D3 => "3",
93 Key::D4 => "4",
94 Key::D5 => "5",
95 Key::D6 => "6",
96 Key::D7 => "7",
97 Key::D8 => "8",
98 Key::D9 => "9",
99 Key::Decimal => ".",
100 Key::Divide => "/",
101 Key::Multiply => "*",
102 Key::OemBackslash => "\\",
103 Key::OemCloseBrackets => "]",
104 Key::OemComma => ",",
105 Key::OemMinus => "-",
106 Key::OemOpenBrackets => "[",
107 Key::OemPeriod => ".",
108 Key::OemPipe => "|",
109 Key::OemPlus => "+",
110 Key::OemQuestion => "/",
111 Key::OemQuotes => "\"",
112 Key::OemSemicolon => ";",
113 Key::OemTilde => "`",
114 Key::Separator => "/",
115 Key::Subtract => "-",
116 Key::Back => "Backspace",
117 Key::Down => "Down Arrow",
118 Key::Left => "Left Arrow",
119 Key::Right => "Right Arrow",
120 Key::Up => "Up Arrow",
121 _ => return None,
122 })
123 }
124
125 pub fn format_key(&self, key: Key) -> String {
129 let Some(overrides) = &self.platform_key_overrides else { return key.name().to_string() };
132
133 match overrides.get(&key) {
134 Some(result) => result.clone(),
135 None => Self::common_key_override(key).unwrap_or(key.name()).to_string(),
136 }
137 }
138}