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