1use std::fmt;
7
8pub use cranpose_foundation::Modifiers;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum KeyEventType {
17 KeyDown,
19 KeyUp,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum KeyCode {
29 A,
31 B,
32 C,
33 D,
34 E,
35 F,
36 G,
37 H,
38 I,
39 J,
40 K,
41 L,
42 M,
43 N,
44 O,
45 P,
46 Q,
47 R,
48 S,
49 T,
50 U,
51 V,
52 W,
53 X,
54 Y,
55 Z,
56
57 Digit0,
59 Digit1,
60 Digit2,
61 Digit3,
62 Digit4,
63 Digit5,
64 Digit6,
65 Digit7,
66 Digit8,
67 Digit9,
68
69 F1,
71 F2,
72 F3,
73 F4,
74 F5,
75 F6,
76 F7,
77 F8,
78 F9,
79 F10,
80 F11,
81 F12,
82
83 ArrowUp,
85 ArrowDown,
86 ArrowLeft,
87 ArrowRight,
88 Home,
89 End,
90 PageUp,
91 PageDown,
92
93 Backspace,
95 Delete,
96 Enter,
97 Tab,
98 Space,
99 Escape,
100
101 ShiftLeft,
103 ShiftRight,
104 ControlLeft,
105 ControlRight,
106 AltLeft,
107 AltRight,
108 MetaLeft,
109 MetaRight,
110
111 Minus,
113 Equal,
114 BracketLeft,
115 BracketRight,
116 Backslash,
117 Semicolon,
118 Quote,
119 Comma,
120 Period,
121 Slash,
122 Backquote,
123
124 Unknown,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
133pub struct KeyEvent {
134 pub key_code: KeyCode,
136 pub text: String,
139 pub modifiers: Modifiers,
141 pub event_type: KeyEventType,
143}
144
145impl KeyEvent {
146 pub fn new(
148 key_code: KeyCode,
149 text: impl Into<String>,
150 modifiers: Modifiers,
151 event_type: KeyEventType,
152 ) -> Self {
153 Self {
154 key_code,
155 text: text.into(),
156 modifiers,
157 event_type,
158 }
159 }
160
161 pub fn key_down(key_code: KeyCode, text: impl Into<String>) -> Self {
163 Self::new(key_code, text, Modifiers::NONE, KeyEventType::KeyDown)
164 }
165
166 pub fn key_down_with_modifiers(
168 key_code: KeyCode,
169 text: impl Into<String>,
170 modifiers: Modifiers,
171 ) -> Self {
172 Self::new(key_code, text, modifiers, KeyEventType::KeyDown)
173 }
174
175 pub fn is_key_down(&self) -> bool {
177 self.event_type == KeyEventType::KeyDown
178 }
179
180 pub fn has_text(&self) -> bool {
182 !self.text.is_empty()
183 }
184}
185
186impl fmt::Display for KeyEvent {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 write!(
189 f,
190 "KeyEvent({:?}, text=\"{}\", {:?})",
191 self.key_code, self.text, self.event_type
192 )
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199
200 #[test]
201 fn key_event_creation() {
202 let event = KeyEvent::key_down(KeyCode::A, "a");
203 assert_eq!(event.key_code, KeyCode::A);
204 assert_eq!(event.text, "a");
205 assert!(event.is_key_down());
206 assert!(event.has_text());
207 }
208
209 #[test]
210 fn key_event_with_modifiers() {
211 let modifiers = Modifiers {
212 shift: true,
213 ctrl: false,
214 alt: false,
215 meta: false,
216 };
217 let event = KeyEvent::key_down_with_modifiers(KeyCode::A, "A", modifiers);
218 assert_eq!(event.text, "A");
219 assert!(event.modifiers.shift);
220 }
221
222 #[test]
223 fn backspace_has_no_text() {
224 let event = KeyEvent::key_down(KeyCode::Backspace, "");
225 assert!(!event.has_text());
226 }
227}