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