1use alloc::string::{String, ToString};
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
9pub struct Modifiers(pub u32);
10
11impl Modifiers {
12 pub const NONE: Self = Self(0);
13 pub const SHIFT: Self = Self(1);
14 pub const CTRL: Self = Self(2);
15 pub const ALT: Self = Self(4);
17 pub const SUPER: Self = Self(8);
19
20 pub const fn contains(self, other: Self) -> bool {
21 self.0 & other.0 == other.0 && other.0 != 0
22 }
23
24 pub const fn shift(self) -> bool {
25 self.contains(Self::SHIFT)
26 }
27
28 pub const fn ctrl(self) -> bool {
29 self.contains(Self::CTRL)
30 }
31
32 pub const fn alt(self) -> bool {
33 self.contains(Self::ALT)
34 }
35
36 pub const fn super_key(self) -> bool {
37 self.contains(Self::SUPER)
38 }
39
40 pub const fn is_empty(self) -> bool {
41 self.0 == 0
42 }
43}
44
45impl core::ops::BitOr for Modifiers {
46 type Output = Self;
47
48 fn bitor(self, other: Self) -> Self {
49 Self(self.0 | other.0)
50 }
51}
52
53#[derive(Clone, Debug, PartialEq, Eq, Hash)]
56pub enum KeyCode {
57 Char(char),
59 Enter,
60 Tab,
61 BackTab,
63 Backspace,
64 Delete,
65 Insert,
66 Space,
67 Left,
68 Right,
69 Up,
70 Down,
71 Home,
72 End,
73 PageUp,
74 PageDown,
75 F(u8),
77 Other(String),
79}
80
81impl KeyCode {
82 pub fn parse(code: &str) -> Self {
84 let mut chars = code.chars();
85 if let (Some(character), None) = (chars.next(), chars.next()) {
86 return Self::Char(character);
87 }
88 match code {
89 "enter" => Self::Enter,
90 "tab" => Self::Tab,
91 "backtab" => Self::BackTab,
92 "backspace" => Self::Backspace,
93 "delete" => Self::Delete,
94 "insert" => Self::Insert,
95 "space" => Self::Space,
96 "left" => Self::Left,
97 "right" => Self::Right,
98 "up" => Self::Up,
99 "down" => Self::Down,
100 "home" => Self::Home,
101 "end" => Self::End,
102 "pageup" => Self::PageUp,
103 "pagedown" => Self::PageDown,
104 other => match other.strip_prefix('f').and_then(|n| n.parse::<u8>().ok()) {
105 Some(n @ 1..=12) => Self::F(n),
106 _ => Self::Other(other.to_string()),
107 },
108 }
109 }
110
111 pub fn name(&self) -> String {
113 match self {
114 Self::Char(character) => character.to_string(),
115 Self::Enter => "enter".into(),
116 Self::Tab => "tab".into(),
117 Self::BackTab => "backtab".into(),
118 Self::Backspace => "backspace".into(),
119 Self::Delete => "delete".into(),
120 Self::Insert => "insert".into(),
121 Self::Space => "space".into(),
122 Self::Left => "left".into(),
123 Self::Right => "right".into(),
124 Self::Up => "up".into(),
125 Self::Down => "down".into(),
126 Self::Home => "home".into(),
127 Self::End => "end".into(),
128 Self::PageUp => "pageup".into(),
129 Self::PageDown => "pagedown".into(),
130 Self::F(n) => alloc::format!("f{n}"),
131 Self::Other(name) => name.clone(),
132 }
133 }
134}
135
136#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
137pub enum KeyPhase {
138 #[default]
139 Press,
140 Repeat,
141 Release,
143}
144
145#[derive(Clone, Debug, PartialEq, Eq)]
147pub struct Key {
148 pub surface: String,
149 pub code: KeyCode,
150 pub text: Option<String>,
152 pub modifiers: Modifiers,
153 pub phase: KeyPhase,
154}
155
156impl Key {
157 pub fn press(surface: &str, code: KeyCode) -> Self {
159 let text = match &code {
160 KeyCode::Char(character) => Some(character.to_string()),
161 KeyCode::Space => Some(" ".into()),
162 _ => None,
163 };
164 Self {
165 surface: surface.into(),
166 code,
167 text,
168 modifiers: Modifiers::NONE,
169 phase: KeyPhase::Press,
170 }
171 }
172}
173
174#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
175pub enum PointerKind {
176 Down,
177 Up,
178 Move,
180 Drag,
182 Wheel,
184 Enter,
187 Leave,
190}
191
192#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
193pub enum Button {
194 None,
195 Left,
196 Middle,
197 Right,
198 WheelUp,
199 WheelDown,
200 WheelLeft,
201 WheelRight,
202 Other(u8),
204}
205
206impl Button {
207 pub fn from_wire(button: u8) -> Self {
208 match button {
209 0 => Self::None,
210 1 => Self::Left,
211 2 => Self::Middle,
212 3 => Self::Right,
213 4 => Self::WheelUp,
214 5 => Self::WheelDown,
215 6 => Self::WheelLeft,
216 7 => Self::WheelRight,
217 other => Self::Other(other),
218 }
219 }
220
221 pub fn wire(self) -> u8 {
222 match self {
223 Self::None => 0,
224 Self::Left => 1,
225 Self::Middle => 2,
226 Self::Right => 3,
227 Self::WheelUp => 4,
228 Self::WheelDown => 5,
229 Self::WheelLeft => 6,
230 Self::WheelRight => 7,
231 Self::Other(other) => other,
232 }
233 }
234}
235
236#[derive(Clone, Debug, PartialEq, Eq)]
238pub struct Pointer {
239 pub surface: String,
240 pub x: u32,
242 pub y: u32,
243 pub col: u32,
245 pub row: u32,
246 pub button: Button,
247 pub kind: PointerKind,
248 pub modifiers: Modifiers,
249}