zui_core/key.rs
1use std::{io::Error, sync::mpsc::Receiver, thread, time::Duration};
2
3// Key Enum definitions
4// A key (Shamefully Copied from Termion (How do I give credit!?))
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub enum Key {
7 /// Backspace.
8 Backspace,
9 /// Enter.
10 Enter,
11 /// Tab.
12 Tab,
13 /// Left arrow.
14 Left,
15 /// Right arrow.
16 Right,
17 /// Up arrow.
18 Up,
19 /// Down arrow.
20 Down,
21 /// Home key.
22 Home,
23 /// End key.
24 End,
25 /// Page Up key.
26 PageUp,
27 /// Page Down key.
28 PageDown,
29 /// Backward Tab key.
30 BackTab,
31 /// Delete key.
32 Delete,
33 /// Insert key.
34 Insert,
35 /// Function keys.
36 ///
37 /// Only function keys 1 through 12 are supported.
38 F(u8),
39 /// Normal character.
40 Char(char),
41 // Number
42 Num(u8),
43 /// Ctrl modified character.
44 /// Note that certain keys may not be modifiable with `ctrl`, due to limitations of terminals.
45 Ctrl(char),
46 // Alt modified character
47 Alt(char),
48 /// Null byte.
49 Null,
50 /// Esc key.
51 Esc,
52}
53
54pub struct KeyIterator {
55 bytes: Receiver<Result<u8, Error>>,
56}
57
58impl KeyIterator {
59 pub fn from(rx: Receiver<Result<u8, Error>>) -> KeyIterator {
60 KeyIterator { bytes: rx }
61 }
62}
63
64impl Iterator for KeyIterator {
65 type Item = Key;
66
67 fn next(&mut self) -> Option<Key> {
68 from_byte(&mut self.bytes)
69 }
70}
71
72fn from_byte(i: &mut Receiver<Result<u8, Error>>) -> Option<Key> {
73 let c = i.recv();
74 match c {
75 Ok(c) => {
76 let c = c.unwrap();
77 if c.is_ascii() {
78 match c {
79 // Ctrl-Characters
80 1..=8 | 10..=12 | 14..=26 => Some(Key::Ctrl((c + 96) as char)),
81
82 13 => Some(Key::Enter),
83 9 => Some(Key::Tab),
84 // Escape Sequences... AKA Hard Part
85 27 => {
86 //TODO: Fix this delay of the main thread (maybe relegate basic processing to spawn)
87 thread::sleep(Duration::from_micros(100));
88 match i.try_recv() {
89 Ok(x) => {
90 match x {
91 // F1-F4
92 Ok(79) => match i.try_recv().unwrap() {
93 Ok(r) => match r as char {
94 'P' => Some(Key::F(1)),
95 'Q' => Some(Key::F(2)),
96 'R' => Some(Key::F(3)),
97 'S' => Some(Key::F(4)),
98 _ => Some(Key::Char(r as char)),
99 },
100 Err(_e) => Some(Key::Null),
101 },
102 Ok(91) => match i.try_recv().unwrap() {
103 Ok(r) => match r {
104 65 => Some(Key::Up),
105 66 => Some(Key::Down),
106 67 => Some(Key::Right),
107 68 => Some(Key::Left),
108 _ => Some(Key::Char(r as char)),
109 },
110 Err(_e) => Some(Key::Null),
111 },
112 Ok(97..=122) => Some(Key::Alt(x.unwrap() as char)),
113 _ => Some(Key::Null),
114 }
115 }
116 Err(_e) => Some(Key::Esc),
117 }
118 }
119
120 // Numbers
121 48..=57 => Some(Key::Num(c - 48)),
122
123 // Alphabet
124 127 => Some(Key::Backspace),
125
126 97..=122 => Some(Key::Char(c as char)),
127 // Key not recognized, but user can parse it
128 _ => Some(Key::Char(c as char)),
129 }
130 } else {
131 println!("{}", c);
132 None
133 }
134 }
135 Err(_e) => Some(Key::Null),
136 }
137}