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.Window.Event; 25 26 private: 27 28 import derelict.sdl2.sdl; 29 30 import Dgame.System.Mouse; 31 import Dgame.System.Keyboard; 32 import Dgame.System.Joystick; 33 import Dgame.System.GameController; 34 35 public: 36 37 /** 38 * The Window move Event structure. 39 */ 40 struct WindowMoveEvent { 41 /** 42 * The new x position 43 */ 44 int x; 45 /** 46 * The new y position 47 */ 48 int y; 49 } 50 51 /** 52 * The Window size Event structure. 53 */ 54 struct WindowSizeEvent { 55 /** 56 * The new width 57 */ 58 int width; 59 /** 60 * The new height 61 */ 62 int height; 63 } 64 65 /** 66 * The Window Event structure. 67 */ 68 struct WindowEvent { 69 /** 70 * All supported Window Event Types 71 */ 72 enum Type { 73 Shown = SDL_WINDOWEVENT_SHOWN, /// Window has been shown 74 Hidden = SDL_WINDOWEVENT_HIDDEN, /// Window has been hidden 75 Exposed = SDL_WINDOWEVENT_EXPOSED, /// Window has been exposed and should be redrawn 76 Moved = SDL_WINDOWEVENT_MOVED, /// Window has been moved 77 Resized = SDL_WINDOWEVENT_RESIZED, /// Window has been resized 78 SizeChanged = SDL_WINDOWEVENT_SIZE_CHANGED, /// Window size has changed; this event is followed by Type.Resized 79 Minimized = SDL_WINDOWEVENT_MINIMIZED, /// Window has been minimized 80 Maximized = SDL_WINDOWEVENT_MAXIMIZED, /// Window has been maximized 81 Restored = SDL_WINDOWEVENT_RESTORED, /// Window has been restored to normal size and position 82 Enter = SDL_WINDOWEVENT_ENTER, /// Window has gained mouse focus 83 Leave = SDL_WINDOWEVENT_LEAVE, /// Window has lost mouse focus 84 FocusGained = SDL_WINDOWEVENT_FOCUS_GAINED, /// Window has gained keyboard focus 85 FocusLost = SDL_WINDOWEVENT_FOCUS_LOST, /// Window has lost keyboard focus 86 Close = SDL_WINDOWEVENT_CLOSE /// The window manager requests that the window be closed 87 } 88 89 /** 90 * The Type of the Window Event 91 */ 92 Type event; 93 94 union { 95 WindowSizeEvent size; /// Size Event 96 WindowMoveEvent motion; /// Motion Event 97 } 98 } 99 100 /** 101 * The Keyboard Event structure. 102 */ 103 struct KeyboardEvent { 104 /** 105 * true, if the key is pressed 106 */ 107 bool isPressed; 108 /** 109 * The Key which is released or pressed. 110 */ 111 Keyboard.Key key; 112 /** 113 * The Key modifier. 114 */ 115 Keyboard.Mod mod; 116 /** 117 * true, if this is a key repeat. 118 */ 119 bool isRepeat; 120 /** 121 * An alias 122 */ 123 deprecated("Use 'key' instead") 124 alias code = key; 125 } 126 127 /** 128 * The Mouse button Event structure. 129 */ 130 struct MouseButtonEvent { 131 /** 132 * The mouse button which is pressed or released. 133 */ 134 Mouse.Button button; 135 /** 136 * true, if the button is pressed 137 */ 138 bool isPressed; 139 /** 140 * 1 for single-click, 2 for double-click, etc. 141 */ 142 ubyte clicks; 143 /** 144 * Current x position. 145 */ 146 int x; 147 /** 148 * Current y position. 149 */ 150 int y; 151 } 152 153 /** 154 * The Mouse motion Event structure. 155 */ 156 struct MouseMotionEvent { 157 /** 158 * true, if the button is pressed 159 */ 160 bool isPressed; 161 /** 162 * Current x position. 163 */ 164 int x; 165 /** 166 * Current y position. 167 */ 168 int y; 169 /** 170 * Relative motion in the x direction. 171 */ 172 int rel_x; 173 /** 174 * Relative motion in the y direction. 175 */ 176 int rel_y; 177 } 178 179 /** 180 * The Mouse wheel Event structure. 181 */ 182 struct MouseWheelEvent { 183 /** 184 * The amount scrolled horizontally, positive to the right and negative to the left 185 */ 186 int x; 187 /** 188 * The amount scrolled vertically, positive away from the user and negative toward the user 189 */ 190 int y; 191 192 static if (SDL_VERSION_ATLEAST(2, 0, 4)) { 193 /** 194 * If true, the values in x and y will be opposite. Multiply by -1 to change them back. 195 */ 196 bool isFlipped; 197 } 198 } 199 200 /** 201 * The Joystick axis motion Event structure 202 */ 203 struct JoystickAxisEvent { 204 /** 205 * The instance id of the joystick which reported the event 206 */ 207 int which; 208 /** 209 * The index of the axis that changed 210 * Typically 0 is the x axis, 1 is the y axis etc. 211 */ 212 ubyte axis; 213 /** 214 * The current position of the axis (range: -32768 to 32767) 215 */ 216 short value; 217 } 218 219 /** 220 * The Joystick button Event structure 221 */ 222 struct JoystickButtonEvent { 223 /** 224 * The instance id of the joystick which reported the event 225 */ 226 int which; 227 /** 228 * The index of the button which is pressed or released 229 */ 230 ubyte button; 231 /** 232 * true, if the button is pressed 233 */ 234 bool isPressed; 235 } 236 237 /** 238 * The Joystick hat Event structure 239 */ 240 struct JoystickHatEvent { 241 /** 242 * The instance id of the joystick which reported the event 243 */ 244 int which; 245 /** 246 * The index of the hat that changed 247 */ 248 ubyte hat; 249 /** 250 * The new position of the hat 251 * 252 * See Joystick.Hat enum 253 */ 254 Joystick.Hat value; 255 } 256 257 /** 258 * The Joystick device Event structure 259 */ 260 struct JoystickDeviceEvent { 261 /** 262 * The instance id of the joystick which reported the event 263 */ 264 int which; 265 } 266 267 /** 268 * The Game Controller axis Event structure 269 */ 270 struct ControllerAxisEvent { 271 /** 272 * The instance id of the joystick which reported the event 273 */ 274 int which; 275 /** 276 * The index of the axis that changed 277 * Typically 0 is the x axis, 1 is the y axis etc. 278 */ 279 GameController.Axis axis; 280 /** 281 * The current position of the axis (range: -32768 to 32767) 282 */ 283 short value; 284 } 285 286 /** 287 * The Game Controller button Event structure 288 */ 289 struct ControllerButtonEvent { 290 /** 291 * The instance id of the joystick which reported the event 292 */ 293 int which; 294 /** 295 * The GameController button which is pressed or released 296 */ 297 GameController.Button button; 298 /** 299 * true, if the button is pressed 300 */ 301 bool isPressed; 302 } 303 304 /** 305 * The Game Controller device Event structure 306 */ 307 struct ControllerDeviceEvent { 308 /** 309 * The instance id of the joystick which reported the event 310 */ 311 int which; 312 } 313 314 /** 315 * The Finger Touch Event structure 316 */ 317 struct TouchFingerEvent { 318 /** 319 * The id of the touch device 320 */ 321 long touchId; 322 /** 323 * The id of the finger who touched the device 324 */ 325 long fingerId; 326 /** 327 * The x coordinate of the touch event, in range of 0 .. 1 328 * Multiply it with the width if the Window to get the real x coordinate 329 */ 330 float x; 331 /** 332 * The y coordinate of the touch event, in range of 0 .. 1 333 * Multiply it with the height if the Window to get the real y coordinate 334 */ 335 float y; 336 /** 337 * The distance of the x coordinate (since the last event) in range of 0 .. 1 338 */ 339 float dx; 340 /** 341 * The distance of the y coordinate (since the last event) in range of 0 .. 1 342 */ 343 float dy; 344 /** 345 * The quantity of pressure applied in range of 0 .. 1 346 */ 347 float pressure; 348 } 349 350 /** 351 * Mouse union 352 */ 353 union MouseUnion { 354 MouseButtonEvent button; /// Mouse button Event 355 MouseMotionEvent motion; /// Mouse motion Event 356 MouseWheelEvent wheel; /// Mouse wheel Event 357 } 358 359 /** 360 * Joystick union 361 */ 362 union JoystickUnion { 363 JoystickAxisEvent motion; /// Joystick motion Event 364 JoystickButtonEvent button; /// Joystick button Event 365 JoystickHatEvent hat; /// Joystick hat Event 366 JoystickDeviceEvent device; /// Joystick device Event 367 } 368 369 /** 370 * Game Controller union 371 */ 372 union ControllerUnion { 373 ControllerAxisEvent motion; /// Controller motion Event 374 ControllerButtonEvent button; /// Controller button Event 375 ControllerDeviceEvent device; /// Controller device Event 376 } 377 378 /** 379 * The Event structure. 380 * Event defines a system event and it's parameters 381 * 382 * Author: Randy Schuett (rswhite4@googlemail.com) 383 */ 384 struct Event { 385 /** 386 * All supported Event Types. 387 */ 388 enum Type { 389 Quit = SDL_QUIT, /// Quit Event. Time to close the window. 390 391 Window = SDL_WINDOWEVENT, /// Something happens with the window. 392 393 KeyDown = SDL_KEYDOWN, /// A key is pressed. 394 KeyUp = SDL_KEYUP, /// A key is released. 395 396 MouseMotion = SDL_MOUSEMOTION, /// The mouse has moved. 397 MouseButtonDown = SDL_MOUSEBUTTONDOWN, /// A mouse button is pressed. 398 MouseButtonUp = SDL_MOUSEBUTTONUP, /// A mouse button is released. 399 MouseWheel = SDL_MOUSEWHEEL, /// The mouse wheel has scolled. 400 401 JoystickAxisMotion = SDL_JOYAXISMOTION, /// A Joystick axis has moved 402 JoystickButtonDown = SDL_JOYBUTTONDOWN, /// A Joystick button is pressed 403 JoystickButtonUp = SDL_JOYBUTTONUP, /// A Joystick button is released 404 JoystickHatMotion = SDL_JOYHATMOTION, /// A Joystick hat has moved 405 JoystickDeviceAdded = SDL_JOYDEVICEADDED, /// A Joystick was added 406 JoystickDeviceRemoved = SDL_JOYDEVICEREMOVED, /// A Joystick was removed 407 408 ControllerAxisMotion = SDL_CONTROLLERAXISMOTION, /// A GameController axis has moved 409 ControllerButtonDown = SDL_CONTROLLERBUTTONDOWN, /// A GameController button is pressed 410 ControllerButtonUp = SDL_CONTROLLERBUTTONUP, /// A GameController button is released 411 ControllerDeviceAdded = SDL_CONTROLLERDEVICEADDED, /// A GameController was added 412 ControllerDeviceRemoved = SDL_CONTROLLERDEVICEREMOVED, /// A GameController was removed 413 ControllerDeviceMapped = SDL_CONTROLLERDEVICEREMAPPED, /// A GameController was mapped 414 415 FingerMotion = SDL_FINGERMOTION, /// A finger was moved onto the touch device 416 FingerDown = SDL_FINGERDOWN, /// A finger is pressed onto the touch device 417 FingerUp = SDL_FINGERUP, /// A finger is released of the touch device 418 } 419 420 /** 421 * The type of the Event 422 */ 423 Type type; 424 /** 425 * Milliseconds since the app is running 426 */ 427 uint timestamp; 428 /** 429 * The window which has raised this event 430 */ 431 uint windowId; 432 433 union { 434 KeyboardEvent keyboard; /// Keyboard Event 435 WindowEvent window; /// Window Event 436 MouseUnion mouse; /// Mouse Events 437 JoystickUnion joystick; /// Joystick Events 438 ControllerUnion controller; /// Controller Events 439 TouchFingerEvent fingerTouch; /// Finger-Touch Events 440 } 441 } 442 443 package: 444 445 @nogc 446 bool _translate(Event* event, ref const SDL_Event sdl_event) nothrow { 447 assert(event, "Event is null"); 448 449 switch (sdl_event.type) { 450 case Event.Type.KeyDown: 451 case Event.Type.KeyUp: 452 event.type = cast(Event.Type) sdl_event.type; 453 event.timestamp = sdl_event.key.timestamp; 454 event.windowId = sdl_event.key.windowID; 455 event.keyboard.isPressed = sdl_event.key.state == SDL_PRESSED; 456 event.keyboard.key = cast(Keyboard.Key) sdl_event.key.keysym.sym; 457 event.keyboard.isRepeat = sdl_event.key.repeat != 0; 458 event.keyboard.mod = Keyboard.getModifier(); 459 460 return true; 461 case Event.Type.Window: 462 event.type = Event.Type.Window; 463 event.windowId = sdl_event.window.windowID; 464 event.timestamp = sdl_event.window.timestamp; 465 466 switch (sdl_event.window.event) { 467 case WindowEvent.Type.Moved: 468 event.window.motion.x = sdl_event.window.data1; 469 event.window.motion.y = sdl_event.window.data2; 470 471 break; 472 case WindowEvent.Type.Resized: 473 event.window.size.width = sdl_event.window.data1; 474 event.window.size.height = sdl_event.window.data2; 475 476 break; 477 default: break; 478 } 479 480 event.window.event = cast(WindowEvent.Type) sdl_event.window.event; 481 482 return true; 483 case Event.Type.Quit: 484 event.type = Event.Type.Quit; 485 486 return true; 487 case Event.Type.MouseButtonDown: 488 case Event.Type.MouseButtonUp: 489 event.type = cast(Event.Type) sdl_event.type; 490 event.timestamp = sdl_event.button.timestamp; 491 event.windowId = sdl_event.button.windowID; 492 event.mouse.button.isPressed = sdl_event.button.state == SDL_PRESSED; 493 event.mouse.button.button = cast(Mouse.Button) sdl_event.button.button; 494 event.mouse.button.clicks = sdl_event.button.clicks; 495 event.mouse.button.x = sdl_event.button.x; 496 event.mouse.button.y = sdl_event.button.y; 497 498 return true; 499 case Event.Type.MouseMotion: 500 event.type = Event.Type.MouseMotion; 501 event.timestamp = sdl_event.motion.timestamp; 502 event.windowId = sdl_event.motion.windowID; 503 event.mouse.motion.isPressed = sdl_event.motion.state == SDL_PRESSED; 504 event.mouse.motion.x = sdl_event.motion.x; 505 event.mouse.motion.y = sdl_event.motion.y; 506 event.mouse.motion.rel_x = sdl_event.motion.xrel; 507 event.mouse.motion.rel_y = sdl_event.motion.yrel; 508 509 return true; 510 case Event.Type.MouseWheel: 511 event.type = Event.Type.MouseWheel; 512 event.timestamp = sdl_event.wheel.timestamp; 513 event.windowId = sdl_event.wheel.windowID; 514 event.mouse.wheel.x = sdl_event.wheel.x; 515 event.mouse.wheel.y = sdl_event.wheel.y; 516 517 static if (SDL_VERSION_ATLEAST(2, 0, 4)) { 518 event.mouse.wheel.isFlipped = sdl_event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED; 519 } 520 521 return true; 522 case Event.Type.JoystickAxisMotion: 523 event.type = Event.Type.JoystickAxisMotion; 524 event.timestamp = sdl_event.jaxis.timestamp; 525 event.joystick.motion.which = sdl_event.jaxis.which; 526 event.joystick.motion.axis = sdl_event.jaxis.axis; 527 event.joystick.motion.value = sdl_event.jaxis.value; 528 529 return true; 530 case Event.Type.JoystickButtonDown: 531 case Event.Type.JoystickButtonUp: 532 event.type = cast(Event.Type) sdl_event.type; 533 event.timestamp = sdl_event.jbutton.timestamp; 534 event.joystick.button.isPressed = sdl_event.jbutton.state == SDL_PRESSED; 535 event.joystick.button.which = sdl_event.jbutton.which; 536 event.joystick.button.button = sdl_event.jbutton.button; 537 538 return true; 539 case Event.Type.JoystickHatMotion: 540 event.type = Event.Type.JoystickHatMotion; 541 event.timestamp = sdl_event.jhat.timestamp; 542 event.joystick.hat.hat = sdl_event.jhat.hat; 543 event.joystick.hat.value = cast(Joystick.Hat) sdl_event.jhat.value; 544 event.joystick.hat.which = sdl_event.jhat.which; 545 546 return true; 547 case Event.Type.JoystickDeviceAdded: 548 case Event.Type.JoystickDeviceRemoved: 549 event.type = cast(Event.Type) sdl_event.type; 550 event.timestamp = sdl_event.jdevice.timestamp; 551 event.joystick.device.which = sdl_event.jdevice.which; 552 553 return true; 554 case Event.Type.ControllerAxisMotion: 555 event.type = Event.Type.ControllerAxisMotion; 556 event.timestamp = sdl_event.caxis.timestamp; 557 event.controller.motion.which = sdl_event.caxis.which; 558 event.controller.motion.axis = cast(GameController.Axis) sdl_event.caxis.axis; 559 event.controller.motion.value = sdl_event.caxis.value; 560 561 return true; 562 case Event.Type.ControllerButtonDown: 563 case Event.Type.ControllerButtonUp: 564 event.type = cast(Event.Type) sdl_event.type; 565 event.timestamp = sdl_event.cbutton.timestamp; 566 event.controller.button.isPressed = sdl_event.cbutton.state == SDL_PRESSED; 567 event.controller.button.which = sdl_event.cbutton.which; 568 event.controller.button.button = cast(GameController.Button) sdl_event.cbutton.button; 569 570 return true; 571 case Event.Type.ControllerDeviceAdded: 572 case Event.Type.ControllerDeviceRemoved: 573 case Event.Type.ControllerDeviceMapped: 574 event.timestamp = sdl_event.cdevice.timestamp; 575 event.type = cast(Event.Type) sdl_event.cdevice.type; 576 event.controller.device.which = sdl_event.cdevice.which; 577 578 return true; 579 case Event.Type.FingerMotion: 580 case Event.Type.FingerDown: 581 case Event.Type.FingerUp: 582 event.timestamp = sdl_event.tfinger.timestamp; 583 event.type = cast(Event.Type) sdl_event.tfinger.type; 584 event.fingerTouch.touchId = sdl_event.tfinger.touchId; 585 event.fingerTouch.fingerId = sdl_event.tfinger.fingerId; 586 event.fingerTouch.x = sdl_event.tfinger.x; 587 event.fingerTouch.y = sdl_event.tfinger.y; 588 event.fingerTouch.dx = sdl_event.tfinger.dx; 589 event.fingerTouch.dy = sdl_event.tfinger.dy; 590 event.fingerTouch.pressure = sdl_event.tfinger.pressure; 591 592 return true; 593 default: break; 594 } 595 596 return false; 597 }