1use std::fmt;
7
8pub use cranpose_foundation::Modifiers;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum KeyEventType {
13 KeyDown,
15 KeyUp,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub enum KeyCode {
25 A,
26 B,
27 C,
28 D,
29 E,
30 F,
31 G,
32 H,
33 I,
34 J,
35 K,
36 L,
37 M,
38 N,
39 O,
40 P,
41 Q,
42 R,
43 S,
44 T,
45 U,
46 V,
47 W,
48 X,
49 Y,
50 Z,
51
52 Digit0,
53 Digit1,
54 Digit2,
55 Digit3,
56 Digit4,
57 Digit5,
58 Digit6,
59 Digit7,
60 Digit8,
61 Digit9,
62
63 F1,
64 F2,
65 F3,
66 F4,
67 F5,
68 F6,
69 F7,
70 F8,
71 F9,
72 F10,
73 F11,
74 F12,
75
76 ArrowUp,
77 ArrowDown,
78 ArrowLeft,
79 ArrowRight,
80 Home,
81 End,
82 PageUp,
83 PageDown,
84
85 Backspace,
86 Delete,
87 Enter,
88 Tab,
89 Space,
90 Escape,
91
92 ShiftLeft,
93 ShiftRight,
94 ControlLeft,
95 ControlRight,
96 AltLeft,
97 AltRight,
98 MetaLeft,
99 MetaRight,
100
101 Minus,
102 Equal,
103 BracketLeft,
104 BracketRight,
105 Backslash,
106 Semicolon,
107 Quote,
108 Comma,
109 Period,
110 Slash,
111 Backquote,
112
113 Unknown,
115}
116
117const DOM_KEY_CODES: [(&str, KeyCode); 82] = [
118 ("KeyA", KeyCode::A),
119 ("KeyB", KeyCode::B),
120 ("KeyC", KeyCode::C),
121 ("KeyD", KeyCode::D),
122 ("KeyE", KeyCode::E),
123 ("KeyF", KeyCode::F),
124 ("KeyG", KeyCode::G),
125 ("KeyH", KeyCode::H),
126 ("KeyI", KeyCode::I),
127 ("KeyJ", KeyCode::J),
128 ("KeyK", KeyCode::K),
129 ("KeyL", KeyCode::L),
130 ("KeyM", KeyCode::M),
131 ("KeyN", KeyCode::N),
132 ("KeyO", KeyCode::O),
133 ("KeyP", KeyCode::P),
134 ("KeyQ", KeyCode::Q),
135 ("KeyR", KeyCode::R),
136 ("KeyS", KeyCode::S),
137 ("KeyT", KeyCode::T),
138 ("KeyU", KeyCode::U),
139 ("KeyV", KeyCode::V),
140 ("KeyW", KeyCode::W),
141 ("KeyX", KeyCode::X),
142 ("KeyY", KeyCode::Y),
143 ("KeyZ", KeyCode::Z),
144 ("Digit0", KeyCode::Digit0),
145 ("Digit1", KeyCode::Digit1),
146 ("Digit2", KeyCode::Digit2),
147 ("Digit3", KeyCode::Digit3),
148 ("Digit4", KeyCode::Digit4),
149 ("Digit5", KeyCode::Digit5),
150 ("Digit6", KeyCode::Digit6),
151 ("Digit7", KeyCode::Digit7),
152 ("Digit8", KeyCode::Digit8),
153 ("Digit9", KeyCode::Digit9),
154 ("F1", KeyCode::F1),
155 ("F2", KeyCode::F2),
156 ("F3", KeyCode::F3),
157 ("F4", KeyCode::F4),
158 ("F5", KeyCode::F5),
159 ("F6", KeyCode::F6),
160 ("F7", KeyCode::F7),
161 ("F8", KeyCode::F8),
162 ("F9", KeyCode::F9),
163 ("F10", KeyCode::F10),
164 ("F11", KeyCode::F11),
165 ("F12", KeyCode::F12),
166 ("ArrowUp", KeyCode::ArrowUp),
167 ("ArrowDown", KeyCode::ArrowDown),
168 ("ArrowLeft", KeyCode::ArrowLeft),
169 ("ArrowRight", KeyCode::ArrowRight),
170 ("Home", KeyCode::Home),
171 ("End", KeyCode::End),
172 ("PageUp", KeyCode::PageUp),
173 ("PageDown", KeyCode::PageDown),
174 ("Backspace", KeyCode::Backspace),
175 ("Delete", KeyCode::Delete),
176 ("Enter", KeyCode::Enter),
177 ("NumpadEnter", KeyCode::Enter),
178 ("Tab", KeyCode::Tab),
179 ("Space", KeyCode::Space),
180 ("Escape", KeyCode::Escape),
181 ("ShiftLeft", KeyCode::ShiftLeft),
182 ("ShiftRight", KeyCode::ShiftRight),
183 ("ControlLeft", KeyCode::ControlLeft),
184 ("ControlRight", KeyCode::ControlRight),
185 ("AltLeft", KeyCode::AltLeft),
186 ("AltRight", KeyCode::AltRight),
187 ("MetaLeft", KeyCode::MetaLeft),
188 ("MetaRight", KeyCode::MetaRight),
189 ("Minus", KeyCode::Minus),
190 ("Equal", KeyCode::Equal),
191 ("BracketLeft", KeyCode::BracketLeft),
192 ("BracketRight", KeyCode::BracketRight),
193 ("Backslash", KeyCode::Backslash),
194 ("Semicolon", KeyCode::Semicolon),
195 ("Quote", KeyCode::Quote),
196 ("Comma", KeyCode::Comma),
197 ("Period", KeyCode::Period),
198 ("Slash", KeyCode::Slash),
199 ("Backquote", KeyCode::Backquote),
200];
201
202impl KeyCode {
203 pub fn from_dom_code(code: &str) -> Self {
207 DOM_KEY_CODES
208 .iter()
209 .find(|(name, _)| *name == code)
210 .map_or(Self::Unknown, |(_, key)| *key)
211 }
212}
213
214#[derive(Debug, Clone, PartialEq, Eq)]
219pub struct KeyEvent {
220 pub key_code: KeyCode,
222 pub text: String,
225 pub modifiers: Modifiers,
227 pub event_type: KeyEventType,
229}
230
231impl KeyEvent {
232 pub fn new(
234 key_code: KeyCode,
235 text: impl Into<String>,
236 modifiers: Modifiers,
237 event_type: KeyEventType,
238 ) -> Self {
239 Self {
240 key_code,
241 text: text.into(),
242 modifiers,
243 event_type,
244 }
245 }
246
247 pub fn key_down(key_code: KeyCode, text: impl Into<String>) -> Self {
249 Self::new(key_code, text, Modifiers::NONE, KeyEventType::KeyDown)
250 }
251
252 pub fn key_down_with_modifiers(
254 key_code: KeyCode,
255 text: impl Into<String>,
256 modifiers: Modifiers,
257 ) -> Self {
258 Self::new(key_code, text, modifiers, KeyEventType::KeyDown)
259 }
260
261 pub fn is_key_down(&self) -> bool {
263 self.event_type == KeyEventType::KeyDown
264 }
265
266 pub fn has_text(&self) -> bool {
268 !self.text.is_empty()
269 }
270}
271
272impl fmt::Display for KeyEvent {
273 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274 write!(
275 f,
276 "KeyEvent({:?}, text=\"{}\", {:?})",
277 self.key_code, self.text, self.event_type
278 )
279 }
280}
281
282#[cfg(test)]
283#[path = "tests/key_event_tests.rs"]
284mod tests;