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
117#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct KeyEvent {
123 pub key_code: KeyCode,
125 pub text: String,
128 pub modifiers: Modifiers,
130 pub event_type: KeyEventType,
132}
133
134impl KeyEvent {
135 pub fn new(
137 key_code: KeyCode,
138 text: impl Into<String>,
139 modifiers: Modifiers,
140 event_type: KeyEventType,
141 ) -> Self {
142 Self {
143 key_code,
144 text: text.into(),
145 modifiers,
146 event_type,
147 }
148 }
149
150 pub fn key_down(key_code: KeyCode, text: impl Into<String>) -> Self {
152 Self::new(key_code, text, Modifiers::NONE, KeyEventType::KeyDown)
153 }
154
155 pub fn key_down_with_modifiers(
157 key_code: KeyCode,
158 text: impl Into<String>,
159 modifiers: Modifiers,
160 ) -> Self {
161 Self::new(key_code, text, modifiers, KeyEventType::KeyDown)
162 }
163
164 pub fn is_key_down(&self) -> bool {
166 self.event_type == KeyEventType::KeyDown
167 }
168
169 pub fn has_text(&self) -> bool {
171 !self.text.is_empty()
172 }
173}
174
175impl fmt::Display for KeyEvent {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(
178 f,
179 "KeyEvent({:?}, text=\"{}\", {:?})",
180 self.key_code, self.text, self.event_type
181 )
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188
189 #[test]
190 fn key_event_creation() {
191 let event = KeyEvent::key_down(KeyCode::A, "a");
192 assert_eq!(event.key_code, KeyCode::A);
193 assert_eq!(event.text, "a");
194 assert!(event.is_key_down());
195 assert!(event.has_text());
196 }
197
198 #[test]
199 fn key_event_with_modifiers() {
200 let modifiers = Modifiers {
201 shift: true,
202 ctrl: false,
203 alt: false,
204 meta: false,
205 };
206 let event = KeyEvent::key_down_with_modifiers(KeyCode::A, "A", modifiers);
207 assert_eq!(event.text, "A");
208 assert!(event.modifiers.shift);
209 }
210
211 #[test]
212 fn backspace_has_no_text() {
213 let event = KeyEvent::key_down(KeyCode::Backspace, "");
214 assert!(!event.has_text());
215 }
216}