1 /*
2  *******************************************************************************************
3  * Dgame (a D game framework) - Copyright (c) Randy Schütt
4  * 
5  * This software is provided 'as-is', without any express or implied warranty.
6  * In no event will the authors be held liable for any damages arising from
7  * the use of this software.
8  * 
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  * 
13  * 1. The origin of this software must not be misrepresented; you must not claim
14  *    that you wrote the original software. If you use this software in a product,
15  *    an acknowledgment in the product documentation would be appreciated but is
16  *    not required.
17  * 
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  *    misrepresented as being the original software.
20  * 
21  * 3. This notice may not be removed or altered from any source distribution.
22  *******************************************************************************************
23  */
24 module Dgame.System.Keyboard;
25 
26 private {
27 	import derelict.sdl2.types;
28 	import derelict.sdl2.functions;
29 	
30 	import Dgame.Math.Rect;
31 }
32 
33 /**
34  * Represent the Keyboard
35  */
36 final abstract class Keyboard {
37 private:
38 	static ubyte* _Keys;
39 	
40 public:
41 	static this() {
42 		_Keys = SDL_GetKeyboardState(null);
43 	}
44 	
45 	/**
46 	 * Returns the pointer to the Keyboard state.
47 	 * With that you can check if some key is pressed without using a event queue.
48 	 * A value of 1 means that the key is pressed and a value of 0 means that it is not.
49 	 * The pointer will be valid for the whole lifetime of the application and should not be freed by the caller.
50 	 * 
51 	 * Note: This function gives you the current state after all events have been processed, 
52 	 * so if a key or button has been pressed and released before you process events, 
53 	 * then the pressed state will never show up in the update calls.
54 	 * Note: This function doesn't take into account whether shift has been pressed or not.
55 	 * 
56 	 * Examples:
57 	 * ---
58 	 * ubyte* keyStates = Keyboard.getState();
59 	 * if (keyStates[Keyboard.ScanCode.Escape])
60 	 *     writeln("escape is pressed.");
61 	 * ---
62 	 */
63 	static ubyte* getState() in {
64 		assert(_Keys !is null, "You have to call Keyboard.update first.");
65 	} body {
66 		return _Keys;
67 	}
68 	
69 	/**
70 	 * Use this function to start accepting Unicode text input events
71 	 */
72 	static void startTextInput() {
73 		SDL_StartTextInput();
74 	}
75 	
76 	/**
77 	 * Use this function to stop receiving any text input events.
78 	 */
79 	static void stopTextInput() {
80 		SDL_StopTextInput();
81 	}
82 	
83 	/**
84 	 * Use this function to set the rectangle used to type Unicode text inputs.
85 	 */
86 	static void setTextInputRect(ref ShortRect rect) {
87 		SDL_Rect input = void;
88 		rect.transferTo(&input);
89 
90 		SDL_SetTextInputRect(&input);
91 	}
92 	
93 	/**
94 	 * Rvalue version
95 	 */
96 	static void setTextInputRect(ShortRect rect) {
97 		Keyboard.setTextInputRect(rect);
98 	}
99 	
100 	/**
101 	 * Returns if the given Keyboard.Code is pressed.
102 	 * 
103 	 * Examples:
104 	 * ---
105 	 * if (Keyboard.isPressed(Keyboard.Code.Escape))
106 	 *     writeln("escape is pressed.");
107 	 * ---
108 	 */
109 	static bool isPressed(Code code) {
110 		int scancode = SDL_GetScancodeFromKey(code);
111 		
112 		return _Keys[scancode] == 1;
113 	}
114 	
115 	/**
116 	 * Returns if the given Keyboard.ScanCode is pressed.
117 	 * 
118 	 * Examples:
119 	 * ---
120 	 * if (Keyboard.isPressed(Keyboard.ScanCode.Escape))
121 	 *     writeln("escape is pressed.");
122 	 * ---
123 	 */
124 	static bool isPressed(ScanCode scancode) {
125 		return _Keys[scancode] == 1;
126 	}
127 	
128 	/**
129 	 * Returns the current Keyboard modifier.
130 	 *
131 	 * See: Mod enum
132 	 */
133 	static Mod getModifier() {
134 		return cast(Mod) SDL_GetModState();
135 	}
136 	
137 	/**
138 	 * Set the current Keyboard modifier.
139 	 *
140 	 * See: Mod enum
141 	 */
142 	static void setModifier(Mod mod) {
143 		SDL_SetModState(mod);
144 	}
145 	
146 	/**
147 	 * Returns if screen keyboard is supported.
148 	 */
149 	static bool hasScreenSupport() {
150 		return SDL_HasScreenKeyboardSupport() == SDL_TRUE;
151 	}
152 	
153 	/**
154 	 * Supported Keyboard States
155 	 */
156 	enum State {
157 		Pressed  = SDL_PRESSED, /** Key is pressed. */
158 		Released = SDL_RELEASED /** Key is released. */
159 	}
160 	
161 	/**
162 	 * All supported Keyboard modifiers.
163 	 */
164 	enum Mod {
165 		None 	= KMOD_NONE,	/** 0 (no modifier is applicable) */
166 		LShift 	= KMOD_LSHIFT,	/** the left Shift key is down */
167 		RShift 	= KMOD_RSHIFT,	/** the right Shift key is down */
168 		LCtrl 	= KMOD_LCTRL,	/** the left Ctrl (Control) key is down */
169 		RCtrl 	= KMOD_RCTRL,	/** the right Ctrl (Control) key is down */
170 		LAlt 	= KMOD_LALT,	/** the left Alt key is down */
171 		RAlt 	= KMOD_RALT,	/** the right Alt key is down */
172 		LGui 	= KMOD_LGUI,	/** the left GUI key (often the Windows key) is down */
173 		RGui 	= KMOD_RGUI,	/** the right GUI key (often the Windows key) is down */
174 		Num 	= KMOD_NUM,		/** the Num Lock key (may be located on an extended keypad) is down */
175 		Caps 	= KMOD_CAPS,	/** the Caps Lock key is down */
176 		Mode 	= KMOD_MODE,	/** the AltGr key is down */
177 		
178 		Ctrl 	= KMOD_CTRL, 	/** (Mod.LCtrl|Mod.RCtrl) */
179 		Shift 	= KMOD_SHIFT, 	/** (Mod.LShift|Mod.RShift) */
180 		Alt 	= KMOD_ALT, 	/** (Mod.LAlt|Mod.RAlt) */
181 		Gui 	= KMOD_GUI, 	/** (Mod.LGui|Mod.RGui) */
182 	}
183 	
184 	/**
185 	 * Supported Keyboard Codes.
186 	 * This are all possible keys.
187 	 */
188 	enum Code {
189 		Unknown = SDLK_UNKNOWN, /** */
190 		
191 		Return = SDLK_RETURN, /** */
192 		Escape = SDLK_ESCAPE, /** */
193 		Backspace = SDLK_BACKSPACE, /** */
194 		Tab = SDLK_TAB, /** */
195 		Space = SDLK_SPACE, /** */
196 		Exclaim = SDLK_EXCLAIM, /** */
197 		Quotedbl = SDLK_QUOTEDBL, /** */
198 		Hash = SDLK_HASH, /** */
199 		Percent = SDLK_PERCENT, /** */
200 		Dollar = SDLK_DOLLAR, /** */
201 		Ampersand = SDLK_AMPERSAND, /** */
202 		Quote = SDLK_QUOTE, /** */
203 		Leftparen = SDLK_LEFTPAREN, /** */
204 		Rightparen = SDLK_RIGHTPAREN, /** */
205 		Asterisk = SDLK_ASTERISK, /** */
206 		Plus = SDLK_PLUS, /** */
207 		Comma = SDLK_COMMA, /** */
208 		Minus = SDLK_MINUS, /** */
209 		Period = SDLK_PERIOD, /** */
210 		Slash = SDLK_SLASH, /** */
211 		
212 		Esc = Escape, /** Shortcut */
213 		
214 		Num0 = SDLK_0, /** */
215 		Num1 = SDLK_1, /** */
216 		Num2 = SDLK_2, /** */
217 		Num3 = SDLK_3, /** */
218 		Num4 = SDLK_4, /** */
219 		Num5 = SDLK_5, /** */
220 		Num6 = SDLK_6, /** */
221 		Num7 = SDLK_7, /** */
222 		Num8 = SDLK_8, /** */
223 		Num9 = SDLK_9, /** */
224 		
225 		Colon = SDLK_COLON, /** */
226 		Semicolon = SDLK_SEMICOLON, /** */
227 		Less = SDLK_LESS, /** */
228 		Equals = SDLK_EQUALS, /** */
229 		Greater = SDLK_GREATER, /** */
230 		Question = SDLK_QUESTION, /** */
231 		At = SDLK_AT, /** */
232 		
233 		Leftbracket = SDLK_LEFTBRACKET, /** */
234 		Backslash = SDLK_BACKSLASH, /** */
235 		Rightbracket = SDLK_RIGHTBRACKET, /** */
236 		Caret = SDLK_CARET, /** */
237 		Underscore = SDLK_UNDERSCORE, /** */
238 		Backquote = SDLK_BACKQUOTE, /** */
239 		
240 		A = SDLK_a, /** */
241 		B = SDLK_b, /** */
242 		C = SDLK_c, /** */
243 		D = SDLK_d, /** */
244 		E = SDLK_e, /** */
245 		F = SDLK_f, /** */
246 		G = SDLK_g, /** */
247 		H = SDLK_h, /** */
248 		I = SDLK_i, /** */
249 		J = SDLK_j, /** */
250 		K = SDLK_k, /** */
251 		L = SDLK_l, /** */
252 		M = SDLK_m, /** */
253 		N = SDLK_n, /** */
254 		O = SDLK_o, /** */
255 		P = SDLK_p, /** */
256 		Q = SDLK_q, /** */
257 		R = SDLK_r, /** */
258 		S = SDLK_s, /** */
259 		T = SDLK_t, /** */
260 		U = SDLK_u, /** */
261 		V = SDLK_v, /** */
262 		W = SDLK_w, /** */
263 		X = SDLK_x, /** */
264 		Y = SDLK_y, /** */
265 		Z = SDLK_z, /** */
266 		
267 		Capslock = SDLK_CAPSLOCK, /** */
268 		
269 		F1 = SDLK_F1, /** */
270 		F2 = SDLK_F2, /** */
271 		F3 = SDLK_F3, /** */
272 		F4 = SDLK_F4, /** */
273 		F5 = SDLK_F5, /** */
274 		F6 = SDLK_F6, /** */
275 		F7 = SDLK_F7, /** */
276 		F8 = SDLK_F8, /** */
277 		F9 = SDLK_F9, /** */
278 		F10 = SDLK_F10, /** */
279 		F11 = SDLK_F11, /** */
280 		F12 = SDLK_F12, /** */
281 		
282 		Printscreen = SDLK_PRINTSCREEN, /** */
283 		Scrolllock = SDLK_SCROLLLOCK, /** */
284 		Pause = SDLK_PAUSE, /** */
285 		Insert = SDLK_INSERT, /** */
286 		Home = SDLK_HOME, /** */
287 		PageUp = SDLK_PAGEUP, /** */
288 		Delete = SDLK_DELETE, /** */
289 		End = SDLK_END, /** */
290 		PageDown = SDLK_PAGEDOWN, /** */
291 		Right = SDLK_RIGHT, /** */
292 		Left = SDLK_LEFT, /** */
293 		Down = SDLK_DOWN, /** */
294 		Up = SDLK_UP, /** */
295 		
296 		NumLockClear = SDLK_NUMLOCKCLEAR, /** */
297 		KP_Divide = SDLK_KP_DIVIDE, /** */
298 		KP_Multiply = SDLK_KP_MULTIPLY, /** */
299 		KP_Minus = SDLK_KP_MINUS, /** */
300 		KP_Plus = SDLK_KP_PLUS, /** */
301 		KP_Enter = SDLK_KP_ENTER, /** */
302 		KP_1 = SDLK_KP_1, /** */
303 		KP_2 = SDLK_KP_2, /** */
304 		KP_3 = SDLK_KP_3, /** */
305 		KP_4 = SDLK_KP_4, /** */
306 		KP_5 = SDLK_KP_5, /** */
307 		KP_6 = SDLK_KP_6, /** */
308 		KP_7 = SDLK_KP_7, /** */
309 		KP_8 = SDLK_KP_8, /** */
310 		KP_9 = SDLK_KP_9, /** */
311 		KP_0 = SDLK_KP_0, /** */
312 		
313 		F13 = SDLK_F13, /** */
314 		F14 = SDLK_F14, /** */
315 		F15 = SDLK_F15, /** */
316 		F16 = SDLK_F16, /** */
317 		F17 = SDLK_F17, /** */
318 		F18 = SDLK_F18, /** */
319 		F19 = SDLK_F19, /** */
320 		F20 = SDLK_F20, /** */
321 		F21 = SDLK_F21, /** */
322 		F22 = SDLK_F22, /** */
323 		F23 = SDLK_F23, /** */
324 		F24 = SDLK_F24, /** */
325 		
326 		LCtrl = SDLK_LCTRL, /** */
327 		LShift = SDLK_LSHIFT, /** */
328 		LAlt = SDLK_LALT, /** */
329 		LGui = SDLK_LGUI, /** */
330 		RCtrl = SDLK_RCTRL, /** */
331 		RShift = SDLK_RSHIFT, /** */
332 		RAlt = SDLK_RALT, /** */
333 		RGui = SDLK_RGUI /** */
334 	}
335 	
336 	/**
337 	 * Supported Keyboard ScanCodes.
338 	 * This are all possible keys.
339 	 */
340 	enum ScanCode {
341 		Unknown = SDL_SCANCODE_UNKNOWN, /** */
342 		
343 		Return = SDL_SCANCODE_RETURN, /** */
344 		Escape = SDL_SCANCODE_ESCAPE, /** */
345 		Backspace = SDL_SCANCODE_BACKSPACE, /** */
346 		Tab = SDL_SCANCODE_TAB, /** */
347 		Space = SDL_SCANCODE_SPACE, /** */
348 		Comma = SDL_SCANCODE_COMMA, /** */
349 		Minus = SDL_SCANCODE_MINUS, /** */
350 		Period = SDL_SCANCODE_PERIOD, /** */
351 		Slash = SDL_SCANCODE_SLASH, /** */
352 		
353 		Esc = Escape, /** Shortcut */
354 		
355 		Num0 = SDL_SCANCODE_0, /** */
356 		Num1 = SDL_SCANCODE_1, /** */
357 		Num2 = SDL_SCANCODE_2, /** */
358 		Num3 = SDL_SCANCODE_3, /** */
359 		Num4 = SDL_SCANCODE_4, /** */
360 		Num5 = SDL_SCANCODE_5, /** */
361 		Num6 = SDL_SCANCODE_6, /** */
362 		Num7 = SDL_SCANCODE_7, /** */
363 		Num8 = SDL_SCANCODE_8, /** */
364 		Num9 = SDL_SCANCODE_9, /** */
365 		
366 		Semicolon = SDL_SCANCODE_SEMICOLON, /** */
367 		Equals = SDL_SCANCODE_EQUALS, /** */
368 		
369 		Leftbracket = SDL_SCANCODE_LEFTBRACKET, /** */
370 		Backslash = SDL_SCANCODE_BACKSLASH, /** */
371 		Rightbracket = SDL_SCANCODE_RIGHTBRACKET, /** */
372 		
373 		A = SDL_SCANCODE_A, /** */
374 		B = SDL_SCANCODE_B, /** */
375 		C = SDL_SCANCODE_C, /** */
376 		D = SDL_SCANCODE_D, /** */
377 		E = SDL_SCANCODE_E, /** */
378 		F = SDL_SCANCODE_F, /** */
379 		G = SDL_SCANCODE_G, /** */
380 		H = SDL_SCANCODE_H, /** */
381 		I = SDL_SCANCODE_I, /** */
382 		J = SDL_SCANCODE_J, /** */
383 		K = SDL_SCANCODE_K, /** */
384 		L = SDL_SCANCODE_L, /** */
385 		M = SDL_SCANCODE_M, /** */
386 		N = SDL_SCANCODE_N, /** */
387 		O = SDL_SCANCODE_O, /** */
388 		P = SDL_SCANCODE_P, /** */
389 		Q = SDL_SCANCODE_Q, /** */
390 		R = SDL_SCANCODE_R, /** */
391 		S = SDL_SCANCODE_S, /** */
392 		T = SDL_SCANCODE_T, /** */
393 		U = SDL_SCANCODE_U, /** */
394 		V = SDL_SCANCODE_V, /** */
395 		W = SDL_SCANCODE_W, /** */
396 		X = SDL_SCANCODE_X, /** */
397 		Y = SDL_SCANCODE_Y, /** */
398 		Z = SDL_SCANCODE_Z, /** */
399 		
400 		Capslock = SDL_SCANCODE_CAPSLOCK, /** */
401 		
402 		F1 = SDL_SCANCODE_F1, /** */
403 		F2 = SDL_SCANCODE_F2, /** */
404 		F3 = SDL_SCANCODE_F3, /** */
405 		F4 = SDL_SCANCODE_F4, /** */
406 		F5 = SDL_SCANCODE_F5, /** */
407 		F6 = SDL_SCANCODE_F6, /** */
408 		F7 = SDL_SCANCODE_F7, /** */
409 		F8 = SDL_SCANCODE_F8, /** */
410 		F9 = SDL_SCANCODE_F9, /** */
411 		F10 = SDL_SCANCODE_F10, /** */
412 		F11 = SDL_SCANCODE_F11, /** */
413 		F12 = SDL_SCANCODE_F12, /** */
414 		
415 		Printscreen = SDL_SCANCODE_PRINTSCREEN, /** */
416 		Scrolllock = SDL_SCANCODE_SCROLLLOCK, /** */
417 		Pause = SDL_SCANCODE_PAUSE, /** */
418 		Insert = SDL_SCANCODE_INSERT, /** */
419 		Home = SDL_SCANCODE_HOME, /** */
420 		PageUp = SDL_SCANCODE_PAGEUP, /** */
421 		Delete = SDL_SCANCODE_DELETE, /** */
422 		End = SDL_SCANCODE_END, /** */
423 		PageDown = SDL_SCANCODE_PAGEDOWN, /** */
424 		Right = SDL_SCANCODE_RIGHT, /** */
425 		Left = SDL_SCANCODE_LEFT, /** */
426 		Down = SDL_SCANCODE_DOWN, /** */
427 		Up = SDL_SCANCODE_UP, /** */
428 		
429 		NumLockClear = SDL_SCANCODE_NUMLOCKCLEAR, /** */
430 		KP_Divide = SDL_SCANCODE_KP_DIVIDE, /** */
431 		KP_Multiply = SDL_SCANCODE_KP_MULTIPLY, /** */
432 		KP_Minus = SDL_SCANCODE_KP_MINUS, /** */
433 		KP_Plus = SDL_SCANCODE_KP_PLUS, /** */
434 		KP_Enter = SDL_SCANCODE_KP_ENTER, /** */
435 		KP_1 = SDL_SCANCODE_KP_1, /** */
436 		KP_2 = SDL_SCANCODE_KP_2, /** */
437 		KP_3 = SDL_SCANCODE_KP_3, /** */
438 		KP_4 = SDL_SCANCODE_KP_4, /** */
439 		KP_5 = SDL_SCANCODE_KP_5, /** */
440 		KP_6 = SDL_SCANCODE_KP_6, /** */
441 		KP_7 = SDL_SCANCODE_KP_7, /** */
442 		KP_8 = SDL_SCANCODE_KP_8, /** */
443 		KP_9 = SDL_SCANCODE_KP_9, /** */
444 		KP_0 = SDL_SCANCODE_KP_0, /** */
445 		
446 		F13 = SDL_SCANCODE_F13, /** */
447 		F14 = SDL_SCANCODE_F14, /** */
448 		F15 = SDL_SCANCODE_F15, /** */
449 		F16 = SDL_SCANCODE_F16, /** */
450 		F17 = SDL_SCANCODE_F17, /** */
451 		F18 = SDL_SCANCODE_F18, /** */
452 		F19 = SDL_SCANCODE_F19, /** */
453 		F20 = SDL_SCANCODE_F20, /** */
454 		F21 = SDL_SCANCODE_F21, /** */
455 		F22 = SDL_SCANCODE_F22, /** */
456 		F23 = SDL_SCANCODE_F23, /** */
457 		F24 = SDL_SCANCODE_F24, /** */
458 		
459 		LCtrl = SDL_SCANCODE_LCTRL, /** */
460 		LShift = SDL_SCANCODE_LSHIFT, /** */
461 		LAlt = SDL_SCANCODE_LALT, /** */
462 		LGui = SDL_SCANCODE_LGUI, /** */
463 		RCtrl = SDL_SCANCODE_RCTRL, /** */
464 		RShift = SDL_SCANCODE_RSHIFT, /** */
465 		RAlt = SDL_SCANCODE_RALT, /** */
466 		RGui = SDL_SCANCODE_RGUI /** */
467 	}
468 }