1 #ifndef CPPURSES_SYSTEM_EVENTS_KEY_HPP
2 #define CPPURSES_SYSTEM_EVENTS_KEY_HPP
3 #include <cstddef>
4 #include <functional>
5 #include <type_traits>
6 
7 #include <cppurses/system/events/input_event.hpp>
8 
9 namespace cppurses {
10 class Widget;
11 
12 /// Provides qualifying name for Key Event related classes.
13 struct Key {
14     enum Code : short;
15 
16     /// Holds data from a Key Input Event.
17     struct State {
18         /// The keycode of the input.
19         Code key;
20 
21         /// The symbol representing the keycode of the input.
22         /** Is '\0' if keycode is not printable. */
23         char symbol;
24     };
25 
26     /// Key Event Base Class.
27     struct Event : Input_event {
28         Event(Input_event::Type type, Widget& receiver, Code key);
29 
30        protected:
31         const Code key_;
32     };
33 
34     /// Key Press Event.
35     struct Press : Key::Event {
36         Press(Widget& receiver, Code key);
37         bool send() const override;
38         bool filter_send(Widget& filter) const override;
39     };
40 
41     // Key Release Event.
42     struct Release : Key::Event {
43         Release(Widget& receiver, Code key);
44         bool send() const override;
45         bool filter_send(Widget& filter) const override;
46     };
47 
48     /// Enum for key codes from the keyboard with descriptive names.
49     /** Names taken from ncurses. */
50     enum Code : short {
51         // Control Characters
52         Null = 0,    // Ctrl + Space, or Ctrl + 2, OR Ctrl + @
53         Ctrl_a,      // Start of heading
54         Ctrl_b,      // Start of text
55         Ctrl_c,      // End of text
56         Ctrl_d,      // End of transmission
57         Ctrl_e,      // Enquiry
58         Ctrl_f,      // Acknowledge
59         Ctrl_g,      // Bell
60         Backspace_,  // Not used? ascii value 8 check with keypad
61         Tab,         // Ctrl + I
62         Enter,   // Ctrl + J, or Ctrl + M, AKA Line Feed, AKA Carriage Return
63         Ctrl_k,  // Vertical Tab
64         Ctrl_l,  // Form Feed
65         Carriage_return_,     // old, not on modern keyboards
66         Ctrl_n,               // Shift Out
67         Ctrl_o,               // Shift In
68         Ctrl_p,               // Data Link Escape
69         Ctrl_q,               // Device Control One
70         Ctrl_r,               // Device Control Two
71         Ctrl_s,               // Device Control Three
72         Ctrl_t,               // Device Control Four
73         Ctrl_u,               // Negative Acknowledge
74         Ctrl_v,               // Synchronous Idle
75         Ctrl_w,               // End of Transmission Block
76         Ctrl_x,               // Cancel
77         Ctrl_y,               // End of Medium
78         Ctrl_z,               // Substitute
79         Escape,               // Ctrl + [, or Ctrl + 3
80         Ctrl_backslash,       // Ctrl + 4, File Separator
81         Ctrl_closed_bracket,  // Ctrl + 5, Group Separator
82         Ctrl_caret,           // Ctrl + 6, Record Separator
83         Ctrl_underscore,      // Ctrl + 7, Unit Separator
84         Backspace = 127,      // Ctrl + 8
85 
86         // Printable Characters
87         Space = 32,
88         Exclamation_mark,
89         Double_quotation,
90         Hash,
91         Dollar,
92         Percent,
93         Ampersand,
94         Apostrophe,
95         Left_parenthesis,
96         Right_parenthesis,
97         Asterisk,
98         Plus,
99         Comma,
100         Minus,
101         Period,
102         Forward_slash,
103         Zero,
104         One,
105         Two,
106         Three,
107         Four,
108         Five,
109         Six,
110         Seven,
111         Eight,
112         Nine,
113         Colon,
114         Semicolon,
115         Less_than,
116         Equals,
117         Greater_than,
118         Question_mark,
119         At_sign,
120         A,
121         B,
122         C,
123         D,
124         E,
125         F,
126         G,
127         H,
128         I,
129         J,
130         K,
131         L,
132         M,
133         N,
134         O,
135         P,
136         Q,
137         R,
138         S,
139         T,
140         U,
141         V,
142         W,
143         X,
144         Y,
145         Z,
146         Left_bracket,
147         Backslash,
148         Right_bracket,
149         Caret,
150         Underscore,
151         Accent,
152         a,
153         b,
154         c,
155         d,
156         e,
157         f,
158         g,
159         h,
160         i,
161         j,
162         k,
163         l,
164         m,
165         n,
166         o,
167         p,
168         q,
169         r,
170         s,
171         t,
172         u,
173         v,
174         w,
175         x,
176         y,
177         z,
178         Left_curly_bracket,
179         Vertical_bar,
180         Right_curly_bracket,
181         Tilde,
182 
183         // Curses Specialty Characters
184         Arrow_down = 258,
185         Arrow_up,
186         Arrow_left,
187         Arrow_right,
188         Home,
189         Backspace_2, // numpad backspace and backspace on some laptops
190 
191         // Function keys, up to 63.
192         // Add fn number to enum for more. ex) F15 key = Key::Function + 15;
193         Function = 264,
194         Function1,
195         Function2,
196         Function3,
197         Function4,
198         Function5,
199         Function6,
200         Function7,
201         Function8,
202         Function9,
203         Function10,
204         Function11,
205         Function12,
206 
207         Delete_line = 328,
208         Insert_line,
209         Delete_character,
210         Insert_character,
211         EIC,  // sent by rmir or smir in insert mode
212         Clear_screen,
213         Clear_to_end_of_screen,
214         Clear_to_end_of_line,
215         Scroll_forward,
216         Scroll_backward,
217         Next_page,
218         Previous_page,
219         Set_tab,
220         Clear_tab,
221         Clear_all_tabs,
222         Possibly_keypad_enter_,  // int 343
223 
224         Print = 346,
225         Home_down,
226         Keypad_7,
227         Keypad_9,
228         Keypad_5,
229         Keypad_1,
230         Keypad_3,
231         Back_tab,
232         Begin,
233         Cancel_dup_,
234         Close,
235         Command,
236         Copy,
237         Create,
238         End,
239         Exit,
240         Find,
241         Help,
242         Mark,
243         Message,
244         Move,
245         Next,
246         Open,
247         Options,
248         Previous,
249         Redo,
250         Reference,
251         Refresh,
252         Replace,
253         Restart,
254         Resume,
255         Save,
256         Shift_begin,
257         Shift_cancel,
258         Shift_command,
259         Shift_copy,
260         Shift_create,
261         Shift_delete_character,
262         Shift_delete_line,
263         Select,
264         Shift_end,
265         Shift_clear_to_end_of_line,
266         Shift_exit,
267         Shift_find,
268         Shift_help,
269         Shift_home,
270         Shift_insert_character,
271         Shift_left_arrow,
272         Shift_message,
273         Shift_move,
274         Shift_next,
275         Shift_options,
276         Shift_previous,
277         Shift_print,
278         Shift_redo,
279         Shift_replace,
280         Shift_right_arrow,
281         Shift_resume,
282         Shift_save,
283         Shift_suspend,
284         Shift_undo,
285         Suspend,
286         Undo
287     };
288 };
289 
290 /// Translate a keycode \p key into its char representation.
291 /** Return '\0' if \p key does not have a printable representation. */
292 char key_to_char(Key::Code key);
293 
294 }  // namespace cppurses
295 
296 // Required for gcc < 6.1 && sometimes clang 7?
297 namespace std {
298 template <>
299 struct hash<cppurses::Key::Code> {
300     using argument_type = cppurses::Key::Code;
301     using result_type = std::size_t;
302     using underlying_t = std::underlying_type_t<argument_type>;
operator ()std::hash303     result_type operator()(const argument_type& key) const noexcept {
304         return std::hash<underlying_t>{}(static_cast<underlying_t>(key));
305     }
306 };
307 }  // namespace std
308 #endif  // CPPURSES_SYSTEM_EVENTS_KEY_HPP
309