1 /*
2 DSFML - The Simple and Fast Multimedia Library for D
3 
4 Copyright (c) 2013 - 2015 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 use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose, including commercial applications,
10 and to alter it and redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 
15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
16 
17 3. This notice may not be removed or altered from any source distribution
18 */
19 
20 ///A module containing the Event struct and other event structs.
21 module dsfml.window.event;
22 
23 import dsfml.window.keyboard;
24 import dsfml.window.mouse;
25 
26 /**
27 *Defines a system event and its parameters.
28 *
29 *Event holds all the informations about a system event that just happened.
30 *
31 *Events are retrieved using the sWindow.pollEvent and Window.waitEvent functions.
32 *
33 *A Event instance contains the type of the event (mouse moved, key pressed, window closed, ...) 
34 *as well as the details about this particular event. Please note that the event parameters are defined
35 *in a union, which means that only the member matching the type of the event will be properly filled;
36 *all other members will have undefined values and must not be read if the type of the event doesn't match. 
37 *For example, if you received a KeyPressed event, then you must read the event.key member, all other members
38 *such as event.MouseMove or event.text will have undefined values.
39 */
40 struct Event
41 {
42 	/**
43 	*Joystick buttons events parameters (JoystickButtonPressed, JoystickButtonReleased) 
44 	*/
45 	struct JoystickButtonEvent
46 	{
47 		///Index of the joystick (in range [0 .. Joystick::Count - 1])
48 		uint joystickId; 
49 		///Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
50 		uint button;
51 	}
52 
53 	/**
54 	*Joystick connection events parameters (JoystickConnected, JoystickDisconnected)
55 	*/
56 	struct JoystickConnectEvent
57 	{
58 		///Index of the joystick (in range [0 .. Joystick::Count - 1])
59 		uint joystickId;
60 	}
61 
62 	/**
63 	 *Joystick connection events parameters (JoystickConnected, JoystickDisconnected)
64 	 */
65 	struct JoystickMoveEvent
66 	{
67 		///Index of the joystick (in range [0 .. Joystick::Count - 1])
68 		uint joystickId;
69 		///Axis on which the joystick moved
70 		int axis;
71 		///New position on the axis (in range [-100 .. 100])
72 		float position;
73 	}
74 
75 	/**
76 	 *Keyboard event parameters (KeyPressed, KeyReleased)
77 	 */
78 	struct KeyEvent
79 	{
80 		///Code of the key that has been pressed.
81 		Keyboard.Key code;
82 		///Is the Alt key pressed?
83 		bool alt;
84 		///Is the Control key pressed?
85 		bool control;
86 		///Is the Shift key pressed?
87 		bool shift;
88 		///Is the System key pressed?
89 		bool system;
90 	}
91 
92 	/**
93 	 *Mouse buttons events parameters (MouseButtonPressed, MouseButtonReleased) 
94 	 */
95 	struct MouseButtonEvent
96 	{
97 		///Code of the button that has been pressed
98 		Mouse.Button button;
99 		///X position of the mouse pointer, relative to the left of the owner window
100 		int x;
101 		///Y position of the mouse pointer, relative to the top of the owner window
102 		int y;
103 	}
104 
105 	/**
106 	 *Mouse move event parameters (MouseMoved) 
107 	 */
108 	struct MouseMoveEvent
109 	{
110 		///X position of the mouse pointer, relative to the left of the owner window
111 		int x;
112 		///Y position of the mouse pointer, relative to the top of the owner window
113 		int y;
114 	}
115 
116 	/**
117 	 *Mouse wheel events parameters (MouseWheelMoved) 
118 	 */
119 	struct MouseWheelEvent
120 	{
121 		///Number of ticks the wheel has moved (positive is up, negative is down)
122 		int delta;
123 		///X position of the mouse pointer, relative to the left of the owner window
124 		int x;
125 		///Y position of the mouse pointer, relative to the top of the owner window
126 		int y;
127 	}
128 
129 	/**
130 	 *Size events parameters (Resized)
131 	 */
132 	struct SizeEvent
133 	{
134 		///New width, in pixels
135 		uint width;
136 		///New height, in pixels
137 		uint height;
138 	}
139 
140 	/**
141 	 *Text event parameters (TextEntered)
142 	 */
143 	struct TextEvent
144 	{
145 		/// UTF-32 unicode value of the character
146 		dchar unicode;
147 	}
148 
149 	enum EventType
150 	{
151 		///The window requested to be closed (no data)
152 		Closed,
153 		///The window was resized (data in event.size)
154 		Resized,
155 		///The window lost the focus (no data)
156 		LostFocus,
157 		///The window gained the focus (no data)
158 		GainedFocus,
159 		///A character was entered (data in event.text)
160 		TextEntered,
161 		///A key was pressed (data in event.key)
162 		KeyPressed,
163 		///A key was released (data in event.key)
164 		KeyReleased,
165 		///The mouse wheel was scrolled (data in event.mouseWheel)
166 		MouseWheelMoved,
167 		///A mouse button was pressed (data in event.mouseButton)
168 		MouseButtonPressed,
169 		///A mouse button was released (data in event.mouseButton)
170 		MouseButtonReleased,
171 		///The mouse cursor moved (data in event.mouseMove)
172 		MouseMoved,
173 		///The mouse cursor entered the area of the window (no data)
174 		MouseEntered,
175 		///The mouse cursor left the area of the window (no data)
176 		MouseLeft,
177 		///A joystick button was pressed (data in event.joystickButton)
178 		JoystickButtonPressed,
179 		///A joystick button was released (data in event.joystickButton)
180 		JoystickButtonReleased,
181 		///The joystick moved along an axis (data in event.joystickMove)
182 		JoystickMoved,
183 		///A joystick was connected (data in event.joystickConnect)
184 		JoystickConnected,
185 		///A joystick was disconnected (data in event.joystickConnect)
186 		JoystickDisconnected,
187 		
188 		///Keep last -- the total number of event types
189 		Count
190 	}
191 	
192 	///Type of the event
193 	EventType type;
194 	
195 	union
196 	{
197 		///Size event parameters (Event::Resized)
198 		SizeEvent size;
199 		///Key event parameters (Event::KeyPressed, Event::KeyReleased)
200 		KeyEvent key;
201 		///Text event parameters (Event::TextEntered)
202 		TextEvent text;
203 		///Mouse move event parameters (Event::MouseMoved)
204 		MouseMoveEvent mouseMove;
205 		///Mouse button event parameters (Event::MouseButtonPressed, Event::MouseButtonReleased)
206 		MouseButtonEvent mouseButton;
207 		///Mouse wheel event parameters (Event::MouseWheelMoved)
208 		MouseWheelEvent mouseWheel;
209 		///Joystick move event parameters (Event::JoystickMoved)
210 		JoystickMoveEvent joystickMove;
211 		///Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased)
212 		JoystickButtonEvent joystickButton;
213 		///Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected)
214 		JoystickConnectEvent joystickConnect;
215 		
216 	}
217 }
218 
219 unittest
220 {
221 	version(DSFML_Unittest_Window)
222 	{
223 		import std.stdio;
224 
225 		import dsfml.graphics.font;
226 		import dsfml.graphics.text;
227 		import dsfml.graphics.renderwindow;
228 		import dsfml.window;
229 		import std.conv;
230 
231 		writeln("Unit tests for events.");
232 
233 		string[int] keys;
234 		//in its own scope for code folding
235 		{
236 			keys[-1] = "Unknown";
237 			keys[0] = 	"A";
238 			keys[1] =	"B";
239 			keys[2] =	"C";
240 			keys[3] =	"D";
241 			keys[4] =	"E";
242 			keys[5] =	"F";
243 			keys[6] =	"G";
244 			keys[7] =	"H";
245 			keys[8] =	"I";
246 			keys[9] =	"J";
247 			keys[10] =	"K";
248 			keys[11] =	"L";
249 			keys[12] =	"M";
250 			keys[13] =	"N";
251 			keys[14] =	"O";
252 			keys[15] =	"P";
253 			keys[16] =	"Q";
254 			keys[16] =	"R";
255 			keys[18] =	"S";
256 			keys[19] =	"T";
257 			keys[20] =	"U";
258 			keys[21] =	"V";
259 			keys[22] =	"W";
260 			keys[23] =	"X";
261 			keys[24] =	"Y";
262 			keys[25] =	"Z";
263 			keys[26] =	"Num0";
264 			keys[26] =	"Num1";
265 			keys[28] =	"Num2";
266 			keys[29] =	"Num3";
267 			keys[30] =	"Num4";
268 			keys[31] =	"Num5";
269 			keys[32] =	"Num6";
270 			keys[33] =	"Num7";
271 			keys[34] =	"Num8";
272 			keys[35] =	"Num9";
273 			keys[36] =	"Escape";
274 			keys[37] =	"LControl";
275 			keys[38] =	"LShift";
276 			keys[39] =	"LAlt";
277 			keys[40] =	"LSystem";
278 			keys[41] =	"RControl";
279 			keys[42] =	"RShift";
280 			keys[43] =	"RAlt";
281 			keys[44] =	"RSystem";
282 			keys[45] =	"Menu";
283 			keys[46] =	"LBracket";
284 			keys[47] =	"RBracket";
285 			keys[48] =	"SemiColon";
286 			keys[49] =	"Comma";
287 			keys[50] =	"Period";
288 			keys[51] =	"Quote";
289 			keys[52] =	"Slash";
290 			keys[53] =	"BackSlash";
291 			keys[54] =	"Tilde";
292 			keys[55] =	"Equal";
293 			keys[56] =	"Dash";
294 			keys[57] =	"Space";
295 			keys[58] =	"Return";
296 			keys[59] =	"BackSpace";
297 			keys[60] =	"Tab";
298 			keys[61] =	"PageUp";
299 			keys[62] =	"PageDown";
300 			keys[63] =	"End";
301 			keys[64] =	"Home";
302 			keys[65] =	"Insert";
303 			keys[66] =	"Delete";
304 			keys[67] =	"Add";
305 			keys[68] =	"Subtract";
306 			keys[69] =	"Multiply";
307 			keys[70] =	"Divide";
308 			keys[71] =	"Left";
309 			keys[72] =	"Right";
310 			keys[73] =	"Up";
311 			keys[74] =	"Down";
312 			keys[75] =	"Numpad0";
313 			keys[76] =	"Numpad1";
314 			keys[77] =	"Numpad2";
315 			keys[78] =	"Numpad3";
316 			keys[79] =	"Numpad4";
317 			keys[80] =	"Numpad5";
318 			keys[81] =	"Numpad6";
319 			keys[82] =	"Numpad7";
320 			keys[83] =	"Numpad8";
321 			keys[84] =	"Numpad9";
322 			keys[85] =	"F1";
323 			keys[86] =	"F2";
324 			keys[87] =	"F3";
325 			keys[88] =	"F4";
326 			keys[89] =	"F5";
327 			keys[90] =	"F6";
328 			keys[91] =	"F7";
329 			keys[92] =	"F8";
330 			keys[93] =	"F9";
331 			keys[94] =	"F10";
332 			keys[95] =	"F11";
333 			keys[96] =	"F12";
334 			keys[97] =	"F13";
335 			keys[98] =	"F14";
336 			keys[99] =	"F15";
337 			keys[100] =	"Pause";
338 		}
339 
340 
341 		auto font = new Font();
342 
343 		assert(font.loadFromFile("res/Warenhaus-Standard.ttf"));
344 
345 		auto text1 = new Text("Unit test for events.",font);
346 		auto text2 = new Text("Note: This unit test does require user input.",font);
347 		text2.position = Vector2f(0,30);
348 		auto text3 = new Text("Press esc or close window to exit test.",font);
349 		text3.position = Vector2f(0,60);
350 		auto text4 = new Text("Press Left Control to enable/diable text mode/key press mode.",font);
351 		text4.position = Vector2f(0,90);
352 		auto text5 = new Text("Currently in key press mode.",font);
353 		text5.position = Vector2f(0,120);
354 		auto outputText = new Text("Key pressed:",font);
355 		outputText.position = Vector2f(0,150);
356 		auto mouseEventText = new Text("Mouse Event: ", font);
357 		mouseEventText.position = Vector2f(0,180);
358 		auto joystickEventText = new Text("Joystick Event: ", font);
359 		joystickEventText.position = Vector2f(0,210);
360 
361 
362 
363 		bool keyPressMode = true;
364 
365 		dstring savedText = "";
366 
367 		auto window = new RenderWindow(VideoMode(800,600),"Event Unit Test Window");
368 
369 		while(window.isOpen())
370 		{
371 
372 			Event event;
373 
374 			while(window.pollEvent(event))
375 			{
376 				if(event.type == Event.EventType.Closed)
377 				{
378 					window.close();
379 				}
380 
381 				//looking for key presses!
382 				if(keyPressMode)
383 				{
384 					if(event.type == Event.EventType.KeyPressed)
385 					{
386 						outputText.setString = "Key pressed: " ~ dtext(keys[event.key.code]);
387 					}
388 				}
389 				//writing text
390 				else
391 				{
392 					if(event.type == Event.EventType.TextEntered)
393 					{
394 						savedText ~= event.text.unicode;
395 						outputText.setString = "Current Text: " ~ savedText;
396 					}
397 				}
398 
399 				//mouse events: these could be improved, but I will write some just to have them present
400 				if(event.type == Event.EventType.MouseButtonPressed)
401 				{
402 					mouseEventText.setString("Mouse Event: Button Pressed");
403 				}
404 				if(event.type == Event.EventType.MouseButtonReleased)
405 				{
406 					mouseEventText.setString( "Mouse Event: Button Released");
407 				}
408 				if(event.type == Event.EventType.MouseEntered)
409 				{
410 					mouseEventText.setString( "Mouse Event: Mouse Entered Window");
411 				}
412 				if(event.type == Event.EventType.MouseLeft)
413 				{
414 					mouseEventText.setString( "Mouse Event: Mouse Left Window");
415 				}
416 				if(event.type == Event.EventType.MouseMoved)
417 				{
418 					mouseEventText.setString( "Mouse Event: Mouse Moved");
419 				}
420 				if(event.type == Event.EventType.MouseWheelMoved)
421 				{
422 					mouseEventText.setString( "Mouse Event: Mouse Wheel Moved");
423 				}
424 
425 				//joystick events: these could be improved, but I will write some just to have them present
426 				if(event.type == Event.EventType.JoystickConnected)
427 				{
428 					joystickEventText.setString("Joystick Event: Joystick Connected");
429 				}
430 				if(event.type == Event.EventType.JoystickDisconnected)
431 				{
432 					joystickEventText.setString("Joystick Event: Joystick Disconnected");
433 				}
434 				if(event.type == Event.EventType.JoystickButtonPressed)
435 				{
436 					joystickEventText.setString("Joystick Event: Button Pressed");
437 				}
438 				if(event.type == Event.EventType.JoystickButtonReleased)
439 				{
440 					joystickEventText.setString("Joystick Event: Button Released");
441 				}
442 				if(event.type == Event.EventType.JoystickMoved)
443 				{
444 					joystickEventText.setString("Joystick Event: Joystick Moved");
445 				}
446 
447 				//Events that will always happen
448 				if(event.type == Event.EventType.KeyPressed)
449 				{
450 					if(event.key.code == Keyboard.Key.Escape)
451 					{
452 						window.close();
453 					}
454 					if(event.key.code == Keyboard.Key.LControl)
455 					{
456 						if(keyPressMode)
457 						{
458 							keyPressMode = false;
459 							text5.setString("Currently in text mode.");
460 							outputText.setString = "Current Text:";
461 							savedText = "";
462 						}
463 						else
464 						{
465 							keyPressMode = true;
466 							text5.setString("Currently in key press mode.");
467 							outputText.setString = "Key pressed:";
468 						}
469 	
470 					}
471 				}
472 
473 			}
474 			window.clear();
475 
476 			window.draw(text1);
477 			window.draw(text2);
478 			window.draw(text3);
479 			window.draw(text4);
480 			window.draw(text5);
481 			window.draw(outputText);
482 			window.draw(mouseEventText);
483 			window.draw(joystickEventText);
484 
485 			window.display();
486 
487 		}
488 
489 
490 	}
491 }
492 
493 
494