1use std::{fmt, io, time::Duration};
4
5use crate::{Position, TerminalSize};
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
10pub struct KeyboardEnhancementFlags(u8);
11
12impl KeyboardEnhancementFlags {
13 pub const DISAMBIGUATE_ESCAPE_CODES: Self = Self(1 << 0);
14 pub const REPORT_EVENT_TYPES: Self = Self(1 << 1);
15 pub const REPORT_ALTERNATE_KEYS: Self = Self(1 << 2);
16 pub const REPORT_ALL_KEYS_AS_ESCAPE_CODES: Self = Self(1 << 3);
17
18 pub const fn empty() -> Self {
19 Self(0)
20 }
21
22 pub const fn union(self, other: Self) -> Self {
23 Self(self.0 | other.0)
24 }
25
26 pub const fn contains(self, other: Self) -> bool {
27 self.0 & other.0 == other.0
28 }
29
30 pub const fn bits(self) -> u8 {
32 self.0
33 }
34}
35
36impl std::ops::BitOr for KeyboardEnhancementFlags {
37 type Output = Self;
38
39 fn bitor(self, rhs: Self) -> Self::Output {
40 self.union(rhs)
41 }
42}
43
44#[derive(Clone, Debug, PartialEq, Eq)]
46#[non_exhaustive]
47pub enum Event {
48 Key(KeyEvent),
49 Paste(String),
51 Focus(FocusChange),
52 Mouse(MouseEvent),
53 Resize(TerminalSize),
55}
56
57#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
59#[non_exhaustive]
60pub struct KeyEvent {
61 pub code: KeyCode,
62 pub modifiers: Modifiers,
63 pub kind: KeyKind,
64 pub state: KeyEventState,
65}
66
67impl KeyEvent {
68 pub const fn new(code: KeyCode) -> Self {
70 Self {
71 code,
72 modifiers: Modifiers::NONE,
73 kind: KeyKind::Press,
74 state: KeyEventState::NONE,
75 }
76 }
77
78 pub const fn with_modifiers(mut self, modifiers: Modifiers) -> Self {
79 self.modifiers = modifiers;
80 self
81 }
82
83 pub const fn with_kind(mut self, kind: KeyKind) -> Self {
84 self.kind = kind;
85 self
86 }
87
88 pub const fn with_state(mut self, state: KeyEventState) -> Self {
89 self.state = state;
90 self
91 }
92}
93
94#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
96pub struct KeyEventState(u8);
97
98impl KeyEventState {
99 pub const NONE: Self = Self(0);
100 pub const KEYPAD: Self = Self(1 << 0);
101 pub const CAPS_LOCK: Self = Self(1 << 1);
102 pub const NUM_LOCK: Self = Self(1 << 2);
103
104 pub const fn union(self, other: Self) -> Self {
105 Self(self.0 | other.0)
106 }
107
108 pub const fn contains(self, other: Self) -> bool {
109 self.0 & other.0 == other.0
110 }
111}
112
113impl std::ops::BitOr for KeyEventState {
114 type Output = Self;
115
116 fn bitor(self, rhs: Self) -> Self::Output {
117 self.union(rhs)
118 }
119}
120
121#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
123pub enum KeyKind {
124 #[default]
125 Press,
126 Repeat,
127 Release,
128}
129
130#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
132#[non_exhaustive]
133pub enum KeyCode {
134 Char(char),
135 Enter,
136 Tab,
137 BackTab,
138 Backspace,
139 Delete,
140 Escape,
141 Insert,
142 Home,
143 End,
144 PageUp,
145 PageDown,
146 Up,
147 Down,
148 Left,
149 Right,
150 Function(u8),
151 Null,
152 CapsLock,
153 ScrollLock,
154 NumLock,
155 PrintScreen,
156 Pause,
157 Menu,
158 KeypadBegin,
159 Media(MediaKeyCode),
160 Modifier(ModifierKeyCode),
161}
162
163#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
164pub enum MediaKeyCode {
165 Play,
166 Pause,
167 PlayPause,
168 Reverse,
169 Stop,
170 FastForward,
171 Rewind,
172 TrackNext,
173 TrackPrevious,
174 Record,
175 LowerVolume,
176 RaiseVolume,
177 MuteVolume,
178}
179
180#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
181pub enum ModifierKeyCode {
182 LeftShift,
183 LeftControl,
184 LeftAlt,
185 LeftSuper,
186 LeftHyper,
187 LeftMeta,
188 RightShift,
189 RightControl,
190 RightAlt,
191 RightSuper,
192 RightHyper,
193 RightMeta,
194 IsoLevel3Shift,
195 IsoLevel5Shift,
196}
197
198#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
200pub struct Modifiers(u8);
201
202impl Modifiers {
203 pub const NONE: Self = Self(0);
204 pub const SHIFT: Self = Self(1 << 0);
205 pub const CONTROL: Self = Self(1 << 1);
206 pub const ALT: Self = Self(1 << 2);
207 pub const SUPER: Self = Self(1 << 3);
208 pub const HYPER: Self = Self(1 << 4);
209 pub const META: Self = Self(1 << 5);
210
211 pub const fn union(self, other: Self) -> Self {
212 Self(self.0 | other.0)
213 }
214
215 pub const fn contains(self, other: Self) -> bool {
216 self.0 & other.0 == other.0
217 }
218}
219
220impl std::ops::BitOr for Modifiers {
221 type Output = Self;
222
223 fn bitor(self, rhs: Self) -> Self::Output {
224 self.union(rhs)
225 }
226}
227
228impl fmt::Debug for Modifiers {
229 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
230 let mut first = true;
231 formatter.write_str("Modifiers(")?;
232 for (name, held) in [
233 ("shift", self.contains(Self::SHIFT)),
234 ("control", self.contains(Self::CONTROL)),
235 ("alt", self.contains(Self::ALT)),
236 ("super", self.contains(Self::SUPER)),
237 ("hyper", self.contains(Self::HYPER)),
238 ("meta", self.contains(Self::META)),
239 ] {
240 if held {
241 if !first {
242 formatter.write_str("+")?;
243 }
244 formatter.write_str(name)?;
245 first = false;
246 }
247 }
248 if first {
249 formatter.write_str("none")?;
250 }
251 formatter.write_str(")")
252 }
253}
254
255#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
256pub enum FocusChange {
257 Gained,
258 Lost,
259}
260
261#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
263pub struct MouseEvent {
264 pub kind: MouseKind,
265 pub position: Position,
266 pub modifiers: Modifiers,
267}
268
269#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
271#[non_exhaustive]
272pub enum MouseKind {
273 Down(MouseButton),
274 Up(MouseButton),
275 Drag(MouseButton),
276 Moved,
277 ScrollDown,
278 ScrollUp,
279 ScrollLeft,
280 ScrollRight,
281}
282
283#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
284pub enum MouseButton {
285 Left,
286 Right,
287 Middle,
288}
289
290pub trait EventSource {
292 fn read_event(&mut self) -> io::Result<Event>;
294
295 fn poll_event(&mut self) -> io::Result<Option<Event>>;
297
298 fn poll_event_timeout(&mut self, timeout: Duration) -> io::Result<Option<Event>>;
300}
301
302impl<T: EventSource + ?Sized> EventSource for &mut T {
303 fn read_event(&mut self) -> io::Result<Event> {
304 T::read_event(self)
305 }
306
307 fn poll_event(&mut self) -> io::Result<Option<Event>> {
308 T::poll_event(self)
309 }
310
311 fn poll_event_timeout(&mut self, timeout: Duration) -> io::Result<Option<Event>> {
312 T::poll_event_timeout(self, timeout)
313 }
314}