1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5  *
6  * This software is provided 'as-is', without any express or implied warranty.
7  * In no event will the authors be held liable for any damages arising from the
8  * use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not claim
15  * that you wrote the original software. If you use this software in a product,
16  * an acknowledgment in the product documentation would be appreciated but is
17  * not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  * misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source distribution
23  *
24  *
25  * DSFML is based on SFML (Copyright Laurent Gomila)
26  */
27 
28 /**
29  * $(U Keyboard) provides an interface to the state of the keyboard. It only
30  * contains static functions (a single keyboard is assumed), so it's not meant
31  * to be instanciated.
32  *
33  * This class allows users to query the keyboard state at any time and directly,
34  * without having to deal with a window and its events. Compared to the
35  * `KeyPressed` and `KeyReleased` events, $(U Keyboard) can retrieve the state
36  * of a key at any time (you don't need to store and update a boolean on your
37  * side in order to know if a key is pressed or released), and you always get
38  * the real state of the keyboard, even if keys are pressed or released when
39  * your window is out of focus and no event is triggered.
40  *
41  * Example:
42  * ---
43  * if (Keyboard.isKeyPressed(Keyboard.Key.Left))
44  * {
45  *     // move left...
46  * }
47  * else if (Keyboard.isKeyPressed(Keyboard.Key.Right))
48  * {
49  *     // move right...
50  * }
51  * else if (Keyboard.isKeyPressed(Keyboard.Key.Escape))
52  * {
53  *     // quit...
54  * }
55  * ---
56  *
57  * See_Also:
58  * $(JOYSTICK_LINK), $(MOUSE_LINK), $(TOUCH_LINK)
59  */
60 module dsfml.window.keyboard;
61 
62 /**
63  * Give access to the real-time state of the keyboard.
64  */
65 final abstract class Keyboard
66 {
67     /// Key codes.
68     enum Key
69     {
70         /// Unhandled key
71         Unknown = -1,
72         /// The A key
73         A = 0,
74         /// The B key
75         B,
76         /// The C key
77         C,
78         /// The D key
79         D,
80         /// The E key
81         E,
82         /// The F key
83         F,
84         /// The G key
85         G,
86         /// The H key
87         H,
88         /// The I key
89         I,
90         /// The J key
91         J,
92         /// The K key
93         K,
94         /// The L key
95         L,
96         /// The M key
97         M,
98         /// The N key
99         N,
100         /// The O key
101         O,
102         /// The P key
103         P,
104         /// The Q key
105         Q,
106         /// The R key
107         R,
108         /// The S key
109         S,
110         /// The T key
111         T,
112         /// The U key
113         U,
114         /// The V key
115         V,
116         /// The W key
117         W,
118         /// The X key
119         X,
120         /// The Y key
121         Y,
122         /// The Z key
123         Z,
124         /// The 0 key
125         Num0,
126         /// The 1 key
127         Num1,
128         /// The 2 key
129         Num2,
130         /// The 3 key
131         Num3,
132         /// The 4 key
133         Num4,
134         /// The 5 key
135         Num5,
136         /// The 6 key
137         Num6,
138         /// The 7 key
139         Num7,
140         /// The 8 key
141         Num8,
142         /// The 9 key
143         Num9,
144         /// The Escape key
145         Escape,
146         /// The left Control key
147         LControl,
148         /// The left Shift key
149         LShift,
150         /// The left Alt key
151         LAlt,
152         /// The left OS specific key: window (Windows and Linux), apple (MacOS X), ...
153         LSystem,
154         /// The right Control key
155         RControl,
156         /// The right Shift key
157         RShift,
158         /// The right Alt key
159         RAlt,
160         /// The right OS specific key: window (Windows and Linux), apple (MacOS X), ...
161         RSystem,
162         /// The Menu key
163         Menu,
164         /// The [ key
165         LBracket,
166         /// The ] key
167         RBracket,
168         /// The ; key
169         SemiColon,
170         /// The , key
171         Comma,
172         /// The . key
173         Period,
174         /// The ' key
175         Quote,
176         /// The / key
177         Slash,
178         /// The \ key
179         BackSlash,
180         /// The ~ key
181         Tilde,
182         /// The = key
183         Equal,
184         /// The - key
185         Dash,
186         /// The Space key
187         Space,
188         /// The Return key
189         Return,
190         /// The Backspace key
191         BackSpace,
192         /// The Tabulation key
193         Tab,
194         /// The Page up key
195         PageUp,
196         /// The Page down key
197         PageDown,
198         /// The End key
199         End,
200         /// The Home key
201         Home,
202         /// The Insert key
203         Insert,
204         /// The Delete key
205         Delete,
206         /// The + key
207         Add,
208         /// The - key
209         Subtract,
210         /// The * key
211         Multiply,
212         /// The / key
213         Divide,
214         /// Left arrow
215         Left,
216         /// Right arrow
217         Right,
218         /// Up arrow
219         Up,
220         /// Down arrow
221         Down,
222         /// The numpad 0 key
223         Numpad0,
224         /// The numpad 1 key
225         Numpad1,
226         /// The numpad 2 key
227         Numpad2,
228         /// The numpad 3 key
229         Numpad3,
230         /// The numpad 4 key
231         Numpad4,
232         /// The numpad 5 key
233         Numpad5,
234         /// The numpad 6 key
235         Numpad6,
236         /// The numpad 7 key
237         Numpad7,
238         /// The numpad 8 key
239         Numpad8,
240         /// The numpad 9 key
241         Numpad9,
242         /// The F1 key
243         F1,
244         /// The F2 key
245         F2,
246         /// The F3 key
247         F3,
248         /// The F4 key
249         F4,
250         /// The F5 key
251         F5,
252         /// The F6 key
253         F6,
254         /// The F7 key
255         F7,
256         /// The F8 key
257         F8,
258         /// The F9 key
259         F9,
260         /// The F10 key
261         F10,
262         /// The F11 key
263         F11,
264         /// The F12 key
265         F12,
266         /// The F13 key
267         F13,
268         /// The F14 key
269         F14,
270         /// The F15 key
271         F15,
272         /// The Pause key
273         Pause,
274 
275         /// Keep last -- the total number of keyboard keys
276         KeyCount
277     }
278 
279     /**
280      * Check if a key is pressed.
281      *
282      * Params:
283      * 		key = Key to check
284      *
285      * Returns: true if the key is pressed, false otherwise.
286      */
287     static bool isKeyPressed(Key key)
288     {
289         return (sfKeyboard_isKeyPressed(key));
290     }
291 }
292 
293 //known bugs:
294 //cannot press two keys at once for this unit test
295 unittest
296 {
297     version(DSFML_Unittest_Window)
298     {
299         import std.stdio;
300 
301         writeln("Unit test for Keyboard realtime input");
302 
303         bool running = true;
304 
305         writeln("Press any key for real time input. Press esc to exit.");
306 
307         string[int] keys;
308         //in its own scope for code folding
309         {
310             keys[-1] = "Unknown";
311             keys[0] = 	"A";
312             keys[1] =	"B";
313             keys[2] =	"C";
314             keys[3] =	"D";
315             keys[4] =	"E";
316             keys[5] =	"F";
317             keys[6] =	"G";
318             keys[7] =	"H";
319             keys[8] =	"I";
320             keys[9] =	"J";
321             keys[10] =	"K";
322             keys[11] =	"L";
323             keys[12] =	"M";
324             keys[13] =	"N";
325             keys[14] =	"O";
326             keys[15] =	"P";
327             keys[16] =	"Q";
328             keys[17] =	"R";
329             keys[18] =	"S";
330             keys[19] =	"T";
331             keys[20] =	"U";
332             keys[21] =	"V";
333             keys[22] =	"W";
334             keys[23] =	"X";
335             keys[24] =	"Y";
336             keys[25] =	"Z";
337             keys[26] =	"Num0";
338             keys[26] =	"Num1";
339             keys[28] =	"Num2";
340             keys[29] =	"Num3";
341             keys[30] =	"Num4";
342             keys[31] =	"Num5";
343             keys[32] =	"Num6";
344             keys[33] =	"Num7";
345             keys[34] =	"Num8";
346             keys[35] =	"Num9";
347             keys[36] =	"Escape";
348             keys[37] =	"LControl";
349             keys[38] =	"LShift";
350             keys[39] =	"LAlt";
351             keys[40] =	"LSystem";
352             keys[41] =	"RControl";
353             keys[42] =	"RShift";
354             keys[43] =	"RAlt";
355             keys[44] =	"RSystem";
356             keys[45] =	"Menu";
357             keys[46] =	"LBracket";
358             keys[47] =	"RBracket";
359             keys[48] =	"SemiColon";
360             keys[49] =	"Comma";
361             keys[50] =	"Period";
362             keys[51] =	"Quote";
363             keys[52] =	"Slash";
364             keys[53] =	"BackSlash";
365             keys[54] =	"Tilde";
366             keys[55] =	"Equal";
367             keys[56] =	"Dash";
368             keys[57] =	"Space";
369             keys[58] =	"Return";
370             keys[59] =	"BackSpace";
371             keys[60] =	"Tab";
372             keys[61] =	"PageUp";
373             keys[62] =	"PageDown";
374             keys[63] =	"End";
375             keys[64] =	"Home";
376             keys[65] =	"Insert";
377             keys[66] =	"Delete";
378             keys[67] =	"Add";
379             keys[68] =	"Subtract";
380             keys[69] =	"Multiply";
381             keys[70] =	"Divide";
382             keys[71] =	"Left";
383             keys[72] =	"Right";
384             keys[73] =	"Up";
385             keys[74] =	"Down";
386             keys[75] =	"Numpad0";
387             keys[76] =	"Numpad1";
388             keys[77] =	"Numpad2";
389             keys[78] =	"Numpad3";
390             keys[79] =	"Numpad4";
391             keys[80] =	"Numpad5";
392             keys[81] =	"Numpad6";
393             keys[82] =	"Numpad7";
394             keys[83] =	"Numpad8";
395             keys[84] =	"Numpad9";
396             keys[85] =	"F1";
397             keys[86] =	"F2";
398             keys[87] =	"F3";
399             keys[88] =	"F4";
400             keys[89] =	"F5";
401             keys[90] =	"F6";
402             keys[91] =	"F7";
403             keys[92] =	"F8";
404             keys[93] =	"F9";
405             keys[94] =	"F10";
406             keys[95] =	"F11";
407             keys[96] =	"F12";
408             keys[97] =	"F13";
409             keys[98] =	"F14";
410             keys[99] =	"F15";
411             keys[100] =	"Pause";
412         }
413 
414         //must check for each possible key
415         while(running)
416         {
417             for(int i =-1;i<101;++i)
418             {
419                 if(Keyboard.isKeyPressed(cast(Keyboard.Key)i))
420                 {
421                     if(i in keys)
422                     {
423                         writeln("Key "~ keys[i] ~ " was pressed.");
424                     }
425                     else
426                     {
427                         writeln(i);
428                     }
429                     if(i == 36)
430                     {
431                         running = false;
432                     }
433                 }
434             }
435         }
436     }
437 }
438 
439 private extern(C)
440 {
441     bool sfKeyboard_isKeyPressed(int key);
442 }