1 /++ 2 + Authors: Avaxar <avaxar@nekkl.org> 3 + Copyright: Copyright © 2023, Avaxar 4 + License: $(LINK2 https://mit-license.org, MIT License) 5 +/ 6 7 module dsdl2.event; 8 @safe: 9 10 import bindbc.sdl; 11 import dsdl2.sdl; 12 import dsdl2.display; 13 import dsdl2.keyboard; 14 import dsdl2.mouse; 15 16 import std.conv : to; 17 import std.format : format; 18 19 /++ 20 + Wraps `SDL_PumpEvents` which retrieves events from input devices 21 +/ 22 void pumpEvents() @trusted { 23 SDL_PumpEvents(); 24 } 25 26 /++ 27 + Wraps `SDL_PollEvent` which returns the latest event in queue 28 + 29 + Returns: `dsdl2.Event` if there's an event, otherwise `null` 30 + Example: 31 + --- 32 + // Polls every upcoming event in queue 33 + dsdl2.pumpEvents(); 34 + while (auto event = dsdl2.pollEvent()){ 35 + if (cast(dsdl2.QuitEvent)event) { 36 + dsdl2.quit(); 37 + } 38 + } 39 + --- 40 +/ 41 Event pollEvent() @trusted { 42 SDL_Event event = void; 43 if (SDL_PollEvent(&event) == 1) { 44 return Event.fromSDL(event); 45 } 46 else { 47 return null; 48 } 49 } 50 51 /++ 52 + D abstract class that wraps `SDL_Event` containing details of an event polled from `dsdl2.pollEvent()` 53 +/ 54 abstract class Event { 55 SDL_Event sdlEvent; /// Internal `SDL_Event` struct 56 57 override string toString() const; 58 59 /++ 60 + Gets the `SDL_EventType` of the underlying `SDL_Event` 61 + 62 + Returns: `SDL_EventType` enumeration from bindbc-sdl 63 +/ 64 SDL_EventType sdlEventType() const nothrow @property { 65 return this.sdlEvent.type; 66 } 67 68 /++ 69 + Proxy to the timestamp of the `dsdl2.Event` 70 + 71 + Returns: timestamp of the `dsdl2.Event` 72 +/ 73 ref inout(uint) timestamp() return inout @property { 74 return this.sdlEvent.common.timestamp; 75 } 76 77 /++ 78 + Turns a vanilla `SDL_Event` from bindbc-sdl to `dsdl2.Event` 79 + 80 + Params: 81 + sdlEvent = vanilla `SDL_Event` from bindbc-sdl 82 + Returns: `dsdl2.Event` of the same attributes 83 +/ 84 static Event fromSDL(SDL_Event sdlEvent) @trusted { 85 Event event; 86 switch (sdlEvent.type) { 87 default: 88 event = new UnknownEvent(sdlEvent); 89 break; 90 91 case SDL_QUIT: 92 event = new QuitEvent; 93 break; 94 95 case SDL_APP_TERMINATING: 96 event = new AppTerminatingEvent; 97 break; 98 99 case SDL_APP_LOWMEMORY: 100 event = new AppLowMemoryEvent; 101 break; 102 103 case SDL_APP_WILLENTERBACKGROUND: 104 event = new AppWillEnterBackgroundEvent; 105 break; 106 107 case SDL_APP_DIDENTERBACKGROUND: 108 event = new AppDidEnterBackgroundEvent; 109 break; 110 111 case SDL_APP_WILLENTERFOREGROUND: 112 event = new AppWillEnterForegroundEvent; 113 break; 114 115 case SDL_APP_DIDENTERFOREGROUND: 116 event = new AppDidEnterForegroundEvent; 117 break; 118 119 static if (sdlSupport >= SDLSupport.v2_0_14) { 120 case SDL_LOCALECHANGED: 121 event = new LocaleChangeEvent; 122 break; 123 } 124 125 static if (sdlSupport >= SDLSupport.v2_0_9) { 126 case SDL_DISPLAYEVENT: 127 event = DisplayEvent.fromSDL(sdlEvent); 128 break; 129 } 130 131 case SDL_WINDOWEVENT: 132 event = WindowEvent.fromSDL(sdlEvent); 133 break; 134 135 case SDL_SYSWMEVENT: 136 event = new SysWMEvent(sdlEvent.syswm.msg); 137 break; 138 139 case SDL_KEYDOWN: 140 case SDL_KEYUP: 141 event = KeyboardEvent.fromSDL(sdlEvent); 142 break; 143 144 case SDL_TEXTEDITING: 145 event = new TextEditingEvent(sdlEvent.edit.windowID, sdlEvent.edit.text.ptr.to!string, 146 sdlEvent.edit.start.to!uint, sdlEvent.edit.length.to!uint); 147 break; 148 149 case SDL_TEXTINPUT: 150 event = new TextInputEvent(sdlEvent.text.windowID, sdlEvent.text.text.ptr.to!string); 151 break; 152 153 static if (sdlSupport >= SDLSupport.v2_0_4) { 154 case SDL_KEYMAPCHANGED: 155 event = new KeymapChangedEvent; 156 break; 157 } 158 159 case SDL_MOUSEMOTION: 160 event = new MouseMotionEvent(sdlEvent.motion.windowID, sdlEvent.motion.which, 161 MouseState(sdlEvent.motion.state), 162 [sdlEvent.motion.x, sdlEvent.motion.y], 163 [sdlEvent.motion.xrel, sdlEvent.motion.yrel]); 164 break; 165 166 case SDL_MOUSEBUTTONDOWN: 167 case SDL_MOUSEBUTTONUP: 168 event = MouseButtonEvent.fromSDL(sdlEvent); 169 break; 170 171 case SDL_MOUSEWHEEL: 172 static if (sdlSupport >= SDLSupport.v2_0_18) { 173 event = new MouseWheelEvent(sdlEvent.wheel.windowID, sdlEvent.wheel.which, 174 [sdlEvent.wheel.x, sdlEvent.wheel.y], cast(MouseWheel) sdlEvent.wheel.direction, 175 [sdlEvent.wheel.preciseX, sdlEvent.wheel.preciseY]); 176 break; 177 } 178 else static if (sdlSupport >= SDLSupport.v2_0_4) { 179 event = new MouseWheelEvent(sdlEvent.wheel.windowID, sdlEvent.wheel.which, 180 [sdlEvent.wheel.x, sdlEvent.wheel.y], cast(MouseWheel) sdlEvent.wheel.direction); 181 break; 182 } 183 else { 184 event = new MouseWheelEvent(sdlEvent.wheel.windowID, sdlEvent.wheel.which, 185 [sdlEvent.wheel.x, sdlEvent.wheel.y]); 186 break; 187 } 188 189 case SDL_FINGERMOTION: 190 case SDL_FINGERDOWN: 191 case SDL_FINGERUP: 192 event = FingerEvent.fromSDL(sdlEvent); 193 break; 194 195 case SDL_MULTIGESTURE: 196 event = new MultiGestureEvent(sdlEvent.mgesture.touchId, sdlEvent.mgesture.dTheta, 197 sdlEvent.mgesture.dDist, sdlEvent.mgesture.x, sdlEvent.mgesture.y, sdlEvent.mgesture.numFingers); 198 break; 199 200 case SDL_DOLLARGESTURE: 201 case SDL_DOLLARRECORD: 202 event = DollarEvent.fromSDL(sdlEvent); 203 break; 204 205 case SDL_DROPFILE: 206 static if (sdlSupport >= SDLSupport.v2_0_5) { 207 case SDL_DROPTEXT: 208 case SDL_DROPBEGIN: 209 case SDL_DROPCOMPLETE: 210 } 211 event = DropFileEvent.fromSDL(sdlEvent); 212 break; 213 } 214 215 event.timestamp = sdlEvent.common.timestamp; 216 return event; 217 } 218 } 219 220 /++ 221 + D class that wraps SDL events that aren't recognized by dsdl2 222 +/ 223 final class UnknownEvent : Event { 224 this(SDL_Event sdlEvent) { 225 this.sdlEvent = sdlEvent; 226 } 227 228 override string toString() const { 229 return "dsdl2.UnknownEvent(%s)".format(this.sdlEvent); 230 } 231 } 232 233 /++ 234 + D class that wraps `SDL_QUIT` `SDL_Event`s 235 +/ 236 final class QuitEvent : Event { 237 this() { 238 this.sdlEvent.type = SDL_QUIT; 239 } 240 241 invariant { 242 assert(this.sdlEvent.type == SDL_QUIT); 243 } 244 245 override string toString() const { 246 return "dsdl2.QuitEvent()"; 247 } 248 } 249 250 /++ 251 + D class that wraps `SDL_APP_TERMINATING` `SDL_Event`s 252 +/ 253 final class AppTerminatingEvent : Event { 254 this() { 255 this.sdlEvent.type = SDL_APP_TERMINATING; 256 } 257 258 invariant { 259 assert(this.sdlEvent.type == SDL_APP_TERMINATING); 260 } 261 262 override string toString() const { 263 return "dsdl2.AppTerminatingEvent()"; 264 } 265 } 266 267 /++ 268 + D class that wraps `SDL_APP_LOWMEMORY` `SDL_Event`s 269 +/ 270 final class AppLowMemoryEvent : Event { 271 this() { 272 this.sdlEvent.type = SDL_APP_LOWMEMORY; 273 } 274 275 invariant { 276 assert(this.sdlEvent.type == SDL_APP_LOWMEMORY); 277 } 278 279 override string toString() const { 280 return "dsdl2.AppLowMemoryEvent()"; 281 } 282 } 283 284 /++ 285 + D class that wraps `SDL_APP_WILLENTERBACKGROUND` `SDL_Event`s 286 +/ 287 final class AppWillEnterBackgroundEvent : Event { 288 this() { 289 this.sdlEvent.type = SDL_APP_WILLENTERBACKGROUND; 290 } 291 292 invariant { 293 assert(this.sdlEvent.type == SDL_APP_WILLENTERBACKGROUND); 294 } 295 296 override string toString() const { 297 return "dsdl2.AppWillEnterBackgroundEvent()"; 298 } 299 } 300 301 /++ 302 + D class that wraps `SDL_APP_DIDENTERBACKGROUND` `SDL_Event`s 303 +/ 304 final class AppDidEnterBackgroundEvent : Event { 305 this() { 306 this.sdlEvent.type = SDL_APP_DIDENTERBACKGROUND; 307 } 308 309 invariant { 310 assert(this.sdlEvent.type == SDL_APP_DIDENTERBACKGROUND); 311 } 312 313 override string toString() const { 314 return "dsdl2.AppDidEnterBackgroundEvent()"; 315 } 316 } 317 318 /++ 319 + D class that wraps `SDL_APP_WILLENTERFOREGROUND` `SDL_Event`s 320 +/ 321 final class AppWillEnterForegroundEvent : Event { 322 this() { 323 this.sdlEvent.type = SDL_APP_WILLENTERFOREGROUND; 324 } 325 326 invariant { 327 assert(this.sdlEvent.type == SDL_APP_WILLENTERFOREGROUND); 328 } 329 330 override string toString() const { 331 return "dsdl2.AppWillEnterForegroundEvent()"; 332 } 333 } 334 335 /++ 336 + D class that wraps `SDL_APP_DIDENTERFOREGROUND` `SDL_Event`s 337 +/ 338 final class AppDidEnterForegroundEvent : Event { 339 this() { 340 this.sdlEvent.type = SDL_APP_DIDENTERFOREGROUND; 341 } 342 343 invariant { 344 assert(this.sdlEvent.type == SDL_APP_DIDENTERFOREGROUND); 345 } 346 347 override string toString() const { 348 return "dsdl2.AppDidEnterForegroundEvent()"; 349 } 350 } 351 352 static if (sdlSupport >= SDLSupport.v2_0_14) { 353 /++ 354 + D class that wraps `SDL_LOCALECHANGED` `SDL_Event`s (from SDL 2.0.14) 355 +/ 356 class LocaleChangeEvent : Event { 357 this() { 358 this.sdlEvent.type = SDL_LOCALECHANGED; 359 } 360 361 invariant { 362 assert(this.sdlEvent.type == SDL_LOCALECHANGED); 363 } 364 365 override string toString() const { 366 return "dsdl2.LocaleChangeEvent()"; 367 } 368 } 369 } 370 371 static if (sdlSupport >= SDLSupport.v2_0_9) { 372 /++ 373 + D abstract class that wraps `SDL_DISPLAYEVENT` `SDL_Event`s (from SDL 2.0.9) 374 +/ 375 abstract class DisplayEvent : Event { 376 invariant { 377 assert(this.sdlEvent.type == SDL_DISPLAYEVENT); 378 } 379 380 SDL_DisplayEventID sdlDisplayEventID() const nothrow @property { 381 return this.sdlEvent.display.event; 382 } 383 384 ref inout(uint) display() return inout @property { 385 return this.sdlEvent.display.display; 386 } 387 388 static Event fromSDL(SDL_Event sdlEvent) 389 in { 390 assert(sdlEvent.type == SDL_DISPLAYEVENT); 391 } 392 do { 393 Event event; 394 switch (sdlEvent.display.event) { 395 default: 396 event = new UnknownEvent(sdlEvent); 397 break; 398 399 case SDL_DISPLAYEVENT_ORIENTATION: 400 event = new DisplayOrientationEvent(sdlEvent.display.display, 401 cast(DisplayOrientation) sdlEvent.display.data1); 402 break; 403 404 static if (sdlSupport >= SDLSupport.v2_0_14) { 405 case SDL_DISPLAYEVENT_CONNECTED: 406 event = new DisplayConnectedEvent(sdlEvent.display.display); 407 break; 408 409 case SDL_DISPLAYEVENT_DISCONNECTED: 410 event = new DisplayDisconnectedEvent(sdlEvent.display.display); 411 break; 412 } 413 414 static if (sdlSupport >= SDLSupport.v2_28) { 415 case SDL_DISPLAYEVENT_MOVED: 416 event = new DisplayMovedEvent(sdlEvent.display.display); 417 break; 418 } 419 } 420 421 event.timestamp = sdlEvent.display.timestamp; 422 return event; 423 } 424 } 425 426 /++ 427 + D class that wraps `SDL_DISPLAYEVENT_ORIENTATION` `SDL_DISPLAYEVENT` `SDL_Event`s (from SDL 2.0.9) 428 +/ 429 class DisplayOrientationEvent : DisplayEvent { 430 this(uint display, DisplayOrientation orientation) { 431 this.sdlEvent.type = SDL_DISPLAYEVENT; 432 this.sdlEvent.display.event = SDL_DISPLAYEVENT_ORIENTATION; 433 this.sdlEvent.display.display = display; 434 this.sdlEvent.display.data1 = orientation; 435 } 436 437 invariant { 438 assert(this.sdlEvent.display.event == SDL_DISPLAYEVENT_ORIENTATION); 439 } 440 441 override string toString() const { 442 return "dsdl2.DisplayOrientationEvent(%d, %d)".format(this.display, this.orientation); 443 } 444 445 ref inout(DisplayOrientation) orientation() return inout @property @trusted { 446 return *cast(inout(DisplayOrientation*))&this.sdlEvent.display.data1; 447 } 448 } 449 } 450 451 static if (sdlSupport >= SDLSupport.v2_0_14) { 452 /++ 453 + D class that wraps `SDL_DISPLAYEVENT_CONNECTED` `SDL_DISPLAYEVENT` `SDL_Event`s (from SDL 2.0.14) 454 +/ 455 class DisplayConnectedEvent : DisplayEvent { 456 this(uint display) { 457 this.sdlEvent.type = SDL_DISPLAYEVENT; 458 this.sdlEvent.display.event = SDL_DISPLAYEVENT_CONNECTED; 459 this.sdlEvent.display.display = display; 460 } 461 462 invariant { 463 assert(this.sdlEvent.display.event == SDL_DISPLAYEVENT_CONNECTED); 464 } 465 466 override string toString() const { 467 return "dsdl2.DisplayConnectedEvent(%d)".format(this.display); 468 } 469 } 470 471 /++ 472 + D class that wraps `SDL_DISPLAYEVENT_DISCONNECTED` `SDL_DISPLAYEVENT` `SDL_Event`s (from SDL 2.0.14) 473 +/ 474 class DisplayDisconnectedEvent : DisplayEvent { 475 this(uint display) { 476 this.sdlEvent.type = SDL_DISPLAYEVENT; 477 this.sdlEvent.display.event = SDL_DISPLAYEVENT_DISCONNECTED; 478 this.sdlEvent.display.display = display; 479 } 480 481 invariant { 482 assert(this.sdlEvent.display.event == SDL_DISPLAYEVENT_DISCONNECTED); 483 } 484 485 override string toString() const { 486 return "dsdl2.DisplayDisconnectedEvent(%d)".format(this.display); 487 } 488 } 489 } 490 491 static if (sdlSupport >= SDLSupport.v2_28) { 492 /++ 493 + D class that wraps `SDL_DISPLAYEVENT_MOVED` `SDL_DISPLAYEVENT` `SDL_Event`s (from SDL 2.0.28) 494 +/ 495 class DisplayMovedEvent : DisplayEvent { 496 this(uint display) { 497 this.sdlEvent.type = SDL_DISPLAYEVENT; 498 this.sdlEvent.display.event = SDL_DISPLAYEVENT_MOVED; 499 this.sdlEvent.display.display = display; 500 } 501 502 invariant { 503 assert(this.sdlEvent.display.event == SDL_DISPLAYEVENT_MOVED); 504 } 505 506 override string toString() const { 507 return "dsdl2.DisplayMovedEvent(%d)".format(this.display); 508 } 509 } 510 } 511 512 /++ 513 + D abstract class that wraps `SDL_WINDOWEVENT` `SDL_Event`s 514 +/ 515 abstract class WindowEvent : Event { 516 invariant { 517 assert(this.sdlEvent.type == SDL_WINDOWEVENT); 518 } 519 520 SDL_WindowEventID sdlWindowEventID() const nothrow @property { 521 return this.sdlEvent.window.event; 522 } 523 524 ref inout(uint) windowID() return inout @property { 525 return this.sdlEvent.window.windowID; 526 } 527 528 static Event fromSDL(SDL_Event sdlEvent) 529 in { 530 assert(sdlEvent.type == SDL_WINDOWEVENT); 531 } 532 do { 533 Event event; 534 switch (sdlEvent.window.event) { 535 default: 536 event = new UnknownEvent(sdlEvent); 537 break; 538 539 case SDL_WINDOWEVENT_SHOWN: 540 event = new WindowShownEvent(sdlEvent.window.windowID); 541 break; 542 543 case SDL_WINDOWEVENT_HIDDEN: 544 event = new WindowHiddenEvent(sdlEvent.window.windowID); 545 break; 546 547 case SDL_WINDOWEVENT_EXPOSED: 548 event = new WindowExposedEvent(sdlEvent.window.windowID); 549 break; 550 551 case SDL_WINDOWEVENT_MOVED: 552 event = new WindowMovedEvent(sdlEvent.window.windowID, 553 [sdlEvent.window.data1, sdlEvent.window.data2]); 554 break; 555 556 case SDL_WINDOWEVENT_RESIZED: 557 event = new WindowResizedEvent(sdlEvent.window.windowID, 558 [sdlEvent.window.data1, sdlEvent.window.data2]); 559 break; 560 561 case SDL_WINDOWEVENT_SIZE_CHANGED: 562 event = new WindowSizeChangedEvent(sdlEvent.window.windowID); 563 break; 564 565 case SDL_WINDOWEVENT_MINIMIZED: 566 event = new WindowMinimizedEvent(sdlEvent.window.windowID); 567 break; 568 569 case SDL_WINDOWEVENT_MAXIMIZED: 570 event = new WindowMaximizedEvent(sdlEvent.window.windowID); 571 break; 572 573 case SDL_WINDOWEVENT_RESTORED: 574 event = new WindowRestoredEvent(sdlEvent.window.windowID); 575 break; 576 577 case SDL_WINDOWEVENT_ENTER: 578 event = new WindowEnterEvent(sdlEvent.window.windowID); 579 break; 580 581 case SDL_WINDOWEVENT_LEAVE: 582 event = new WindowLeaveEvent(sdlEvent.window.windowID); 583 break; 584 585 case SDL_WINDOWEVENT_FOCUS_GAINED: 586 event = new WindowFocusGainedEvent(sdlEvent.window.windowID); 587 break; 588 589 case SDL_WINDOWEVENT_FOCUS_LOST: 590 event = new WindowFocusLostEvent(sdlEvent.window.windowID); 591 break; 592 593 case SDL_WINDOWEVENT_CLOSE: 594 event = new WindowCloseEvent(sdlEvent.window.windowID); 595 break; 596 597 static if (sdlSupport >= SDLSupport.v2_0_5) { 598 case SDL_WINDOWEVENT_TAKE_FOCUS: 599 event = new WindowTakeFocusEvent(sdlEvent.window.windowID); 600 break; 601 602 case SDL_WINDOWEVENT_HIT_TEST: 603 event = new WindowHitTestEvent(sdlEvent.window.windowID); 604 break; 605 } 606 607 static if (sdlSupport >= SDLSupport.v2_0_18) { 608 case SDL_WINDOWEVENT_ICCPROF_CHANGED: 609 event = new WindowICCProfileChangedEvent(sdlEvent.window.windowID); 610 break; 611 612 case SDL_WINDOWEVENT_DISPLAY_CHANGED: 613 event = new WindowDisplayChangedEvent(sdlEvent.window.windowID, 614 sdlEvent.window.data1); 615 break; 616 } 617 } 618 619 event.timestamp = sdlEvent.window.timestamp; 620 return event; 621 } 622 } 623 624 /++ 625 + D class that wraps `SDL_WINDOWEVENT_SHOWN` `SDL_WINDOWEVENT` `SDL_Event`s 626 +/ 627 final class WindowShownEvent : WindowEvent { 628 this(uint windowID) { 629 this.sdlEvent.type = SDL_WINDOWEVENT; 630 this.sdlEvent.window.event = SDL_WINDOWEVENT_SHOWN; 631 this.sdlEvent.window.windowID = windowID; 632 } 633 634 invariant { 635 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_SHOWN); 636 } 637 638 override string toString() const { 639 return "dsdl2.WindowShownEvent(%d)".format(this.windowID); 640 } 641 } 642 643 /++ 644 + D class that wraps `SDL_WINDOWEVENT_HIDDEN` `SDL_WINDOWEVENT` `SDL_Event`s 645 +/ 646 final class WindowHiddenEvent : WindowEvent { 647 this(uint windowID) { 648 this.sdlEvent.type = SDL_WINDOWEVENT; 649 this.sdlEvent.window.event = SDL_WINDOWEVENT_HIDDEN; 650 this.sdlEvent.window.windowID = windowID; 651 } 652 653 invariant { 654 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_HIDDEN); 655 } 656 657 override string toString() const { 658 return "dsdl2.WindowHiddenEvent(%d)".format(this.windowID); 659 } 660 } 661 662 /++ 663 + D class that wraps `SDL_WINDOWEVENT_EXPOSED` `SDL_WINDOWEVENT` `SDL_Event`s 664 +/ 665 final class WindowExposedEvent : WindowEvent { 666 this(uint windowID) { 667 this.sdlEvent.type = SDL_WINDOWEVENT; 668 this.sdlEvent.window.event = SDL_WINDOWEVENT_EXPOSED; 669 this.sdlEvent.window.windowID = windowID; 670 } 671 672 invariant { 673 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_EXPOSED); 674 } 675 676 override string toString() const { 677 return "dsdl2.WindowExposedEvent(%d)".format(this.windowID); 678 } 679 } 680 681 /++ 682 + D class that wraps `SDL_WINDOWEVENT_MOVED` `SDL_WINDOWEVENT` `SDL_Event`s 683 +/ 684 final class WindowMovedEvent : WindowEvent { 685 this(uint windowID, int[2] xy) { 686 this.sdlEvent.type = SDL_WINDOWEVENT; 687 this.sdlEvent.window.event = SDL_WINDOWEVENT_MOVED; 688 this.sdlEvent.window.windowID = windowID; 689 this.sdlEvent.window.data1 = xy[0]; 690 this.sdlEvent.window.data2 = xy[1]; 691 } 692 693 invariant { 694 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_MOVED); 695 } 696 697 override string toString() const { 698 return "dsdl2.WindowMovedEvent(%d, %s)".format(this.windowID, this.xy); 699 } 700 701 ref inout(int) x() return inout @property { 702 return this.sdlEvent.window.data1; 703 } 704 705 ref inout(int) y() return inout @property { 706 return this.sdlEvent.window.data2; 707 } 708 709 ref inout(int[2]) xy() return inout @property @trusted { 710 return *cast(inout(int[2]*))&this.sdlEvent.window.data1; 711 } 712 } 713 714 /++ 715 + D class that wraps `SDL_WINDOWEVENT_RESIZED` `SDL_WINDOWEVENT` `SDL_Event`s 716 +/ 717 final class WindowResizedEvent : WindowEvent { 718 this(uint windowID, uint[2] size) { 719 this.sdlEvent.type = SDL_WINDOWEVENT; 720 this.sdlEvent.window.event = SDL_WINDOWEVENT_RESIZED; 721 this.sdlEvent.window.windowID = windowID; 722 this.sdlEvent.window.data1 = size[0].to!int; 723 this.sdlEvent.window.data2 = size[1].to!int; 724 } 725 726 invariant { 727 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_RESIZED); 728 } 729 730 override string toString() const { 731 return "dsdl2.WindowResizedEvent(%d, %s)".format(this.windowID, this.size); 732 } 733 734 ref inout(uint) width() return inout @property @trusted { 735 return *cast(inout(uint*))&this.sdlEvent.window.data1; 736 } 737 738 ref inout(uint) height() return inout @property @trusted { 739 return *cast(inout(uint*))&this.sdlEvent.window.data2; 740 } 741 742 ref inout(uint[2]) size() return inout @property @trusted { 743 return *cast(inout(uint[2]*))&this.sdlEvent.window.data1; 744 } 745 } 746 747 /++ 748 + D class that wraps `SDL_WINDOWEVENT_SIZE_CHANGED` `SDL_WINDOWEVENT` `SDL_Event`s 749 +/ 750 final class WindowSizeChangedEvent : WindowEvent { 751 this(uint windowID) { 752 this.sdlEvent.type = SDL_WINDOWEVENT; 753 this.sdlEvent.window.event = SDL_WINDOWEVENT_SIZE_CHANGED; 754 this.sdlEvent.window.windowID = windowID; 755 } 756 757 invariant { 758 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_SIZE_CHANGED); 759 } 760 761 override string toString() const { 762 return "dsdl2.WindowSizeChangedEvent(%d)".format(this.windowID); 763 } 764 } 765 766 /++ 767 + D class that wraps `SDL_WINDOWEVENT_MINIMIZED` `SDL_WINDOWEVENT` `SDL_Event`s 768 +/ 769 final class WindowMinimizedEvent : WindowEvent { 770 this(uint windowID) { 771 this.sdlEvent.type = SDL_WINDOWEVENT; 772 this.sdlEvent.window.event = SDL_WINDOWEVENT_MINIMIZED; 773 this.sdlEvent.window.windowID = windowID; 774 } 775 776 invariant { 777 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_MINIMIZED); 778 } 779 780 override string toString() const { 781 return "dsdl2.WindowMinimizedEvent(%d)".format(this.windowID); 782 } 783 } 784 785 /++ 786 + D class that wraps `SDL_WINDOWEVENT_MAXIMIZED` `SDL_WINDOWEVENT` `SDL_Event`s 787 +/ 788 final class WindowMaximizedEvent : WindowEvent { 789 this(uint windowID) { 790 this.sdlEvent.type = SDL_WINDOWEVENT; 791 this.sdlEvent.window.event = SDL_WINDOWEVENT_MAXIMIZED; 792 this.sdlEvent.window.windowID = windowID; 793 } 794 795 invariant { 796 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_MAXIMIZED); 797 } 798 799 override string toString() const { 800 return "dsdl2.WindowMaximizedEvent(%d)".format(this.windowID); 801 } 802 } 803 804 /++ 805 + D class that wraps `SDL_WINDOWEVENT_RESTORED` `SDL_WINDOWEVENT` `SDL_Event`s 806 +/ 807 final class WindowRestoredEvent : WindowEvent { 808 this(uint windowID) { 809 this.sdlEvent.type = SDL_WINDOWEVENT; 810 this.sdlEvent.window.event = SDL_WINDOWEVENT_RESTORED; 811 this.sdlEvent.window.windowID = windowID; 812 } 813 814 invariant { 815 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_RESTORED); 816 } 817 818 override string toString() const { 819 return "dsdl2.WindowRestoredEvent(%d)".format(this.windowID); 820 } 821 } 822 823 /++ 824 + D class that wraps `SDL_WINDOWEVENT_ENTER` `SDL_WINDOWEVENT` `SDL_Event`s 825 +/ 826 final class WindowEnterEvent : WindowEvent { 827 this(uint windowID) { 828 this.sdlEvent.type = SDL_WINDOWEVENT; 829 this.sdlEvent.window.event = SDL_WINDOWEVENT_ENTER; 830 this.sdlEvent.window.windowID = windowID; 831 } 832 833 invariant { 834 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_ENTER); 835 } 836 837 override string toString() const { 838 return "dsdl2.WindowEnterEvent(%d)".format(this.windowID); 839 } 840 } 841 842 /++ 843 + D class that wraps `SDL_WINDOWEVENT_LEAVE` `SDL_WINDOWEVENT` `SDL_Event`s 844 +/ 845 final class WindowLeaveEvent : WindowEvent { 846 this(uint windowID) { 847 this.sdlEvent.type = SDL_WINDOWEVENT; 848 this.sdlEvent.window.event = SDL_WINDOWEVENT_LEAVE; 849 this.sdlEvent.window.windowID = windowID; 850 } 851 852 invariant { 853 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_LEAVE); 854 } 855 856 override string toString() const { 857 return "dsdl2.WindowLeaveEvent(%d)".format(this.windowID); 858 } 859 } 860 861 /++ 862 + D class that wraps `SDL_WINDOWEVENT_FOCUS_GAINED` `SDL_WINDOWEVENT` `SDL_Event`s 863 +/ 864 final class WindowFocusGainedEvent : WindowEvent { 865 this(uint windowID) { 866 this.sdlEvent.type = SDL_WINDOWEVENT; 867 this.sdlEvent.window.event = SDL_WINDOWEVENT_FOCUS_GAINED; 868 this.sdlEvent.window.windowID = windowID; 869 } 870 871 invariant { 872 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); 873 } 874 875 override string toString() const { 876 return "dsdl2.WindowFocusGainedEvent(%d)".format(this.windowID); 877 } 878 } 879 880 /++ 881 + D class that wraps `SDL_WINDOWEVENT_FOCUS_LOST` `SDL_WINDOWEVENT` `SDL_Event`s 882 +/ 883 final class WindowFocusLostEvent : WindowEvent { 884 this(uint windowID) { 885 this.sdlEvent.type = SDL_WINDOWEVENT; 886 this.sdlEvent.window.event = SDL_WINDOWEVENT_FOCUS_LOST; 887 this.sdlEvent.window.windowID = windowID; 888 } 889 890 invariant { 891 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_FOCUS_LOST); 892 } 893 894 override string toString() const { 895 return "dsdl2.WindowFocusLostEvent(%d)".format(this.windowID); 896 } 897 } 898 899 /++ 900 + D class that wraps `SDL_WINDOWEVENT_CLOSE` `SDL_WINDOWEVENT` `SDL_Event`s 901 +/ 902 final class WindowCloseEvent : WindowEvent { 903 this(uint windowID) { 904 this.sdlEvent.type = SDL_WINDOWEVENT; 905 this.sdlEvent.window.event = SDL_WINDOWEVENT_CLOSE; 906 this.sdlEvent.window.windowID = windowID; 907 } 908 909 invariant { 910 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_CLOSE); 911 } 912 913 override string toString() const { 914 return "dsdl2.WindowCloseEvent(%d)".format(this.windowID); 915 } 916 } 917 918 static if (sdlSupport >= SDLSupport.v2_0_5) { 919 /++ 920 + D class that wraps `SDL_WINDOWEVENT_TAKE_FOCUS` `SDL_WINDOWEVENT` `SDL_Event`s (from SDL 2.0.5) 921 +/ 922 class WindowTakeFocusEvent : WindowEvent { 923 this(uint windowID) { 924 this.sdlEvent.type = SDL_WINDOWEVENT; 925 this.sdlEvent.window.event = SDL_WINDOWEVENT_TAKE_FOCUS; 926 this.sdlEvent.window.windowID = windowID; 927 } 928 929 invariant { 930 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_TAKE_FOCUS); 931 } 932 933 override string toString() const { 934 return "dsdl2.WindowTakeFocusEvent(%d)".format(this.windowID); 935 } 936 } 937 938 /++ 939 + D class that wraps `SDL_WINDOWEVENT_HIT_TEST` `SDL_WINDOWEVENT` `SDL_Event`s (from SDL 2.0.5) 940 +/ 941 class WindowHitTestEvent : WindowEvent { 942 this(uint windowID) { 943 this.sdlEvent.type = SDL_WINDOWEVENT; 944 this.sdlEvent.window.event = SDL_WINDOWEVENT_HIT_TEST; 945 this.sdlEvent.window.windowID = windowID; 946 } 947 948 invariant { 949 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_HIT_TEST); 950 } 951 952 override string toString() const { 953 return "dsdl2.WindowHitTestEvent(%d)".format(this.windowID); 954 } 955 } 956 } 957 958 static if (sdlSupport >= SDLSupport.v2_0_18) { 959 /++ 960 + D class that wraps `SDL_WINDOWEVENT_ICCPROF_CHANGED` `SDL_WINDOWEVENT` `SDL_Event`s (from SDL 2.0.18) 961 +/ 962 class WindowICCProfileChangedEvent : WindowEvent { 963 this(uint windowID) { 964 this.sdlEvent.type = SDL_WINDOWEVENT; 965 this.sdlEvent.window.event = SDL_WINDOWEVENT_ICCPROF_CHANGED; 966 this.sdlEvent.window.windowID = windowID; 967 } 968 969 invariant { 970 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_ICCPROF_CHANGED); 971 } 972 973 override string toString() const { 974 return "dsdl2.WindowICCProfileChangedEvent(%d)".format(this.windowID); 975 } 976 } 977 978 /++ 979 + D class that wraps `SDL_WINDOWEVENT_DISPLAY_CHANGED` `SDL_WINDOWEVENT` `SDL_Event`s (from SDL 2.0.18) 980 +/ 981 class WindowDisplayChangedEvent : WindowEvent { 982 this(uint windowID, uint display) { 983 this.sdlEvent.type = SDL_WINDOWEVENT; 984 this.sdlEvent.window.event = SDL_WINDOWEVENT_DISPLAY_CHANGED; 985 this.sdlEvent.window.windowID = windowID; 986 this.sdlEvent.window.data1 = display.to!int; 987 } 988 989 invariant { 990 assert(this.sdlEvent.window.event == SDL_WINDOWEVENT_DISPLAY_CHANGED); 991 } 992 993 override string toString() const { 994 return "dsdl2.WindowDisplayChangedEvent(%d)".format(this.windowID, this.display); 995 } 996 997 ref inout(int) display() return inout @property { 998 return this.sdlEvent.window.data1; 999 } 1000 } 1001 } 1002 1003 /++ 1004 + D class that wraps `SDL_SYSWMEVENT` `SDL_Event`s 1005 +/ 1006 final class SysWMEvent : Event { 1007 this(SDL_SysWMmsg* msg) @system { 1008 this.sdlEvent.type = SDL_SYSWMEVENT; 1009 this.sdlEvent.syswm.msg = msg; 1010 } 1011 1012 @trusted invariant { // @suppress(dscanner.trust_too_much) 1013 assert(this.sdlEvent.syswm.msg !is null); 1014 } 1015 1016 override string toString() const @trusted { 1017 return "dsdl2.SysWMEvent(0x%x)".format(this.msg); 1018 } 1019 1020 ref inout(SDL_SysWMmsg*) msg() return inout @property @system { 1021 return this.sdlEvent.syswm.msg; 1022 } 1023 } 1024 1025 /++ 1026 + D abstract class that wraps keyboard `SDL_Event`s 1027 +/ 1028 abstract class KeyboardEvent : Event { 1029 invariant { 1030 assert(this.sdlEvent.type == SDL_KEYDOWN || this.sdlEvent.type == SDL_KEYUP); 1031 } 1032 1033 ref inout(uint) windowID() return inout @property { 1034 return this.sdlEvent.key.windowID; 1035 } 1036 1037 ref inout(ubyte) repeat() return inout @property { 1038 return this.sdlEvent.key.repeat; 1039 } 1040 1041 ref inout(Scancode) scancode() return inout @property @trusted { 1042 return *cast(inout(Scancode*))&this.sdlEvent.key.keysym.scancode; 1043 } 1044 1045 ref inout(Keycode) sym() return inout @property @trusted { 1046 return *cast(inout(Keycode*))&this.sdlEvent.key.keysym.sym; 1047 } 1048 1049 Keymod mod() const @property { 1050 return Keymod(this.sdlEvent.key.keysym.mod); 1051 } 1052 1053 void mod(Keymod newMod) @property { 1054 this.sdlEvent.key.keysym.mod = newMod.sdlKeymod; 1055 } 1056 1057 static Event fromSDL(SDL_Event sdlEvent) 1058 in { 1059 assert(sdlEvent.type == SDL_KEYDOWN || sdlEvent.type == SDL_KEYUP); 1060 } 1061 do { 1062 Event event; 1063 switch (sdlEvent.type) { 1064 default: 1065 assert(false); 1066 1067 case SDL_KEYDOWN: 1068 event = new KeyDownKeyboardEvent(sdlEvent.key.windowID, sdlEvent.key.repeat, 1069 cast(Scancode) sdlEvent.key.keysym.scancode, cast(Keycode) sdlEvent.key.keysym.sym, 1070 Keymod(sdlEvent.key.keysym.mod)); 1071 break; 1072 1073 case SDL_KEYUP: 1074 event = new KeyUpKeyboardEvent(sdlEvent.key.windowID, sdlEvent.key.repeat, 1075 cast(Scancode) sdlEvent.key.keysym.scancode, cast(Keycode) sdlEvent.key.keysym.sym, 1076 Keymod(sdlEvent.key.keysym.mod)); 1077 break; 1078 } 1079 1080 event.timestamp = sdlEvent.key.timestamp; 1081 return event; 1082 } 1083 } 1084 1085 /++ 1086 + D class that wraps `SDL_KEYDOWN` `SDL_Event`s 1087 +/ 1088 final class KeyDownKeyboardEvent : KeyboardEvent { 1089 this(uint windowID, ubyte repeat, Scancode scancode, Keycode sym, Keymod mod) { 1090 this.sdlEvent.type = SDL_KEYDOWN; 1091 this.sdlEvent.key.windowID = windowID; 1092 this.sdlEvent.key.repeat = repeat; 1093 this.sdlEvent.key.keysym.scancode = cast(SDL_Scancode) scancode; 1094 this.sdlEvent.key.keysym.sym = cast(SDL_Keycode) sym; 1095 this.sdlEvent.key.keysym.mod = mod.sdlKeymod; 1096 } 1097 1098 invariant { 1099 assert(this.sdlEvent.type == SDL_KEYDOWN); 1100 } 1101 1102 override string toString() const { 1103 return "dsdl2.KeyDownKeyboardEvent(%d, %d, %s, %s, %s)".format(this.windowID, this.repeat, this.scancode, 1104 this.sym, this.mod); 1105 } 1106 } 1107 1108 /++ 1109 + D class that wraps `SDL_KEYUP` `SDL_Event`s 1110 +/ 1111 final class KeyUpKeyboardEvent : KeyboardEvent { 1112 this(uint windowID, ubyte repeat, Scancode scancode, Keycode sym, Keymod mod) { 1113 this.sdlEvent.type = SDL_KEYUP; 1114 this.sdlEvent.key.windowID = windowID; 1115 this.sdlEvent.key.repeat = repeat; 1116 this.sdlEvent.key.keysym.scancode = cast(SDL_Scancode) scancode; 1117 this.sdlEvent.key.keysym.sym = cast(SDL_Keycode) sym; 1118 this.sdlEvent.key.keysym.mod = mod.sdlKeymod; 1119 } 1120 1121 invariant { 1122 assert(this.sdlEvent.type == SDL_KEYUP); 1123 } 1124 1125 override string toString() const { 1126 return "dsdl2.KeyUpKeyboardEvent(%d, %d, %s, %s, %s)".format(this.windowID, this.repeat, this.scancode, 1127 this.sym, this.mod); 1128 } 1129 } 1130 1131 /++ 1132 + D class that wraps `SDL_TEXTEDITING` `SDL_Event`s 1133 +/ 1134 final class TextEditingEvent : Event { 1135 this(uint windowID, string text, uint start, uint length) 1136 in { 1137 assert(text.length < 32); 1138 } 1139 do { 1140 this.sdlEvent.type = SDL_TEXTEDITING; 1141 this.sdlEvent.edit.windowID = windowID; 1142 this.sdlEvent.edit.text[0 .. text.length] = text[]; 1143 this.sdlEvent.edit.start = start.to!int; 1144 this.sdlEvent.edit.length = length.to!int; 1145 } 1146 1147 invariant { 1148 assert(this.sdlEvent.type == SDL_TEXTEDITING); 1149 } 1150 1151 override string toString() const @trusted { 1152 return "dsdl2.TextEditingEvent(%d, %s, %d, %d)".format(this.windowID, 1153 [this.text].to!string[1 .. $ - 1], this.start, this.length); 1154 } 1155 1156 ref inout(uint) windowID() return inout @property { 1157 return this.sdlEvent.edit.windowID; 1158 } 1159 1160 string text() const @property @trusted { 1161 return this.sdlEvent.edit.text.ptr.to!string; 1162 } 1163 1164 void text(string newText) @property 1165 in { 1166 assert(newText.length < 32); 1167 } 1168 do { 1169 this.sdlEvent.edit.text[0 .. newText.length] = newText[]; 1170 } 1171 1172 ref inout(uint) start() return inout @property { 1173 return *cast(inout(uint*))&this.sdlEvent.edit.start; 1174 } 1175 1176 ref inout(uint) length() return inout @property { 1177 return *cast(inout(uint*))&this.sdlEvent.edit.length; 1178 } 1179 } 1180 1181 /++ 1182 + D class that wraps `SDL_TEXTINPUT` `SDL_Event`s 1183 +/ 1184 final class TextInputEvent : Event { 1185 this(uint windowID, string text) 1186 in { 1187 assert(text.length < 32); 1188 } 1189 do { 1190 this.sdlEvent.type = SDL_TEXTINPUT; 1191 this.sdlEvent.edit.windowID = windowID; 1192 this.sdlEvent.edit.text[0 .. text.length] = text[]; 1193 } 1194 1195 invariant { 1196 assert(this.sdlEvent.type == SDL_TEXTINPUT); 1197 } 1198 1199 override string toString() const @trusted { 1200 return "dsdl2.TextInputEvent(%d, %s)".format(this.windowID, 1201 [this.text].to!string[1 .. $ - 1]); 1202 } 1203 1204 ref inout(uint) windowID() return inout @property { 1205 return this.sdlEvent.edit.windowID; 1206 } 1207 1208 string text() const @property @trusted { 1209 return this.sdlEvent.edit.text.ptr.to!string; 1210 } 1211 1212 void text(string newText) @property 1213 in { 1214 assert(newText.length < 32); 1215 } 1216 do { 1217 this.sdlEvent.edit.text[0 .. newText.length] = newText[]; 1218 } 1219 } 1220 1221 static if (sdlSupport >= SDLSupport.v2_0_4) { 1222 /++ 1223 + D class that wraps `SDL_KEYMAPCHANGED` `SDL_Event`s (from SDL 2.0.4) 1224 +/ 1225 final class KeymapChangedEvent : Event { 1226 this() { 1227 this.sdlEvent.type = SDL_KEYMAPCHANGED; 1228 } 1229 1230 invariant { 1231 assert(this.sdlEvent.type == SDL_KEYMAPCHANGED); 1232 } 1233 1234 override string toString() const { 1235 return "dsdl2.KeymapChangedEvent()"; 1236 } 1237 } 1238 } 1239 1240 /++ 1241 + D class that wraps `SDL_MOUSEMOTION` `SDL_Event`s 1242 +/ 1243 final class MouseMotionEvent : Event { 1244 this(uint windowID, uint which, MouseState state, int[2] xy, int[2] xyRel) { 1245 this.sdlEvent.type = SDL_MOUSEMOTION; 1246 this.sdlEvent.motion.windowID = windowID; 1247 this.sdlEvent.motion.which = which; 1248 this.sdlEvent.motion.state = state.sdlMouseState; 1249 this.sdlEvent.motion.x = xy[0]; 1250 this.sdlEvent.motion.y = xy[1]; 1251 this.sdlEvent.motion.xrel = xyRel[0]; 1252 this.sdlEvent.motion.yrel = xyRel[1]; 1253 } 1254 1255 invariant { 1256 assert(this.sdlEvent.type == SDL_MOUSEMOTION); 1257 } 1258 1259 override string toString() const { 1260 return "dsdl2.MouseMotionEvent(%d, %d, %s, %s, %s)".format(this.windowID, this.which, 1261 this.state, this.xy, this.xyRel); 1262 } 1263 1264 ref inout(uint) windowID() return inout @property { 1265 return this.sdlEvent.motion.windowID; 1266 } 1267 1268 ref inout(uint) which() return inout @property { 1269 return this.sdlEvent.motion.which; 1270 } 1271 1272 MouseState state() const @property { 1273 return MouseState(this.sdlEvent.motion.state); 1274 } 1275 1276 void state(MouseState newState) @property { 1277 this.sdlEvent.motion.state = newState.sdlMouseState; 1278 } 1279 1280 ref inout(int) x() return inout @property { 1281 return this.sdlEvent.motion.x; 1282 } 1283 1284 ref inout(int) y() return inout @property { 1285 return this.sdlEvent.motion.y; 1286 } 1287 1288 ref inout(int[2]) xy() return inout @property @trusted { 1289 return *cast(inout(int[2]*))&this.sdlEvent.motion.x; 1290 } 1291 1292 ref inout(int) xRel() return inout @property { 1293 return this.sdlEvent.motion.xrel; 1294 } 1295 1296 ref inout(int) yRel() return inout @property { 1297 return this.sdlEvent.motion.yrel; 1298 } 1299 1300 ref inout(int[2]) xyRel() return inout @property @trusted { 1301 return *cast(inout(int[2]*))&this.sdlEvent.motion.xrel; 1302 } 1303 } 1304 1305 /++ 1306 + D abstract class that wraps mouse button `SDL_Event`s 1307 +/ 1308 abstract class MouseButtonEvent : Event { 1309 invariant { 1310 assert(this.sdlEvent.type == SDL_MOUSEBUTTONDOWN || this.sdlEvent.type == SDL_MOUSEBUTTONUP); 1311 } 1312 1313 ref inout(uint) windowID() return inout @property { 1314 return this.sdlEvent.button.windowID; 1315 } 1316 1317 ref inout(uint) which() return inout @property { 1318 return this.sdlEvent.button.which; 1319 } 1320 1321 ref inout(MouseButton) button() inout @property @trusted { 1322 return *cast(inout(MouseButton*))&this.sdlEvent.button.button; 1323 } 1324 1325 ref inout(ubyte) clicks() return inout @property { 1326 static if (sdlSupport >= SDLSupport.v2_0_2) { 1327 return this.sdlEvent.button.clicks; 1328 } 1329 else { 1330 return this.sdlEvent.button.padding1; 1331 } 1332 } 1333 1334 ref inout(int) x() return inout @property { 1335 return this.sdlEvent.button.x; 1336 } 1337 1338 ref inout(int) y() return inout @property { 1339 return this.sdlEvent.button.y; 1340 } 1341 1342 ref inout(int[2]) xy() return inout @property @trusted { 1343 return *cast(inout(int[2]*))&this.sdlEvent.button.x; 1344 } 1345 1346 static Event fromSDL(SDL_Event sdlEvent) 1347 in { 1348 assert(sdlEvent.type == SDL_MOUSEBUTTONDOWN || sdlEvent.type == SDL_MOUSEBUTTONUP); 1349 } 1350 do { 1351 Event event; 1352 switch (sdlEvent.type) { 1353 default: 1354 assert(false); 1355 1356 case SDL_MOUSEBUTTONDOWN: 1357 static if (sdlSupport >= SDLSupport.v2_0_2) { 1358 event = new MouseButtonDownEvent(sdlEvent.button.windowID, sdlEvent.button.which, 1359 cast(MouseButton) sdlEvent.button.button, sdlEvent.button.clicks, 1360 [sdlEvent.button.x, sdlEvent.button.y]); 1361 } 1362 else { 1363 event = new MouseButtonDownEvent(sdlEvent.button.windowID, sdlEvent.button.which, 1364 cast(MouseButton) sdlEvent.button.button, 1, 1365 [sdlEvent.button.x, sdlEvent.button.y]); 1366 } 1367 break; 1368 1369 case SDL_MOUSEBUTTONUP: 1370 static if (sdlSupport >= SDLSupport.v2_0_2) { 1371 event = new MouseButtonUpEvent(sdlEvent.button.windowID, sdlEvent.button.which, 1372 cast(MouseButton) sdlEvent.button.button, sdlEvent.button.clicks, 1373 [sdlEvent.button.x, sdlEvent.button.y]); 1374 } 1375 else { 1376 event = new MouseButtonUpEvent(sdlEvent.button.windowID, sdlEvent.button.which, 1377 cast(MouseButton) sdlEvent.button.button, 1, 1378 [sdlEvent.button.x, sdlEvent.button.y]); 1379 } 1380 break; 1381 } 1382 1383 event.timestamp = sdlEvent.button.timestamp; 1384 return event; 1385 } 1386 } 1387 1388 /++ 1389 + D class that wraps `SDL_MOUSEBUTTONDOWN` `SDL_Event`s 1390 +/ 1391 final class MouseButtonDownEvent : MouseButtonEvent { 1392 this(uint windowID, uint which, MouseButton button, ubyte clicks, int[2] xy) { 1393 this.sdlEvent.type = SDL_MOUSEBUTTONDOWN; 1394 this.sdlEvent.button.windowID = windowID; 1395 this.sdlEvent.button.which = which; 1396 this.sdlEvent.button.button = button; 1397 this.sdlEvent.button.state = SDL_PRESSED; 1398 static if (sdlSupport >= SDLSupport.v2_0_2) { 1399 this.sdlEvent.button.clicks = clicks; 1400 } 1401 else { 1402 this.sdlEvent.button.padding1 = clicks; 1403 } 1404 this.sdlEvent.button.x = xy[0]; 1405 this.sdlEvent.button.y = xy[1]; 1406 } 1407 1408 invariant { 1409 assert(this.sdlEvent.type == SDL_MOUSEBUTTONDOWN); 1410 assert(this.sdlEvent.button.state == SDL_PRESSED); 1411 } 1412 1413 override string toString() const { 1414 return "dsdl2.MouseButtonDownEvent(%d, %d, %s, %d, %s)".format(this.windowID, 1415 this.which, this.button, this.clicks, this.xy); 1416 } 1417 } 1418 1419 /++ 1420 + D class that wraps `SDL_MOUSEBUTTONUP` `SDL_Event`s 1421 +/ 1422 final class MouseButtonUpEvent : MouseButtonEvent { 1423 this(uint windowID, uint which, MouseButton button, ubyte clicks, int[2] xy) { 1424 this.sdlEvent.type = SDL_MOUSEBUTTONDOWN; 1425 this.sdlEvent.button.windowID = windowID; 1426 this.sdlEvent.button.which = which; 1427 this.sdlEvent.button.button = button; 1428 this.sdlEvent.button.state = SDL_RELEASED; 1429 static if (sdlSupport >= SDLSupport.v2_0_2) { 1430 this.sdlEvent.button.clicks = clicks; 1431 } 1432 else { 1433 this.sdlEvent.button.padding1 = clicks; 1434 } 1435 this.sdlEvent.button.x = xy[0]; 1436 this.sdlEvent.button.y = xy[1]; 1437 } 1438 1439 invariant { 1440 assert(this.sdlEvent.type == SDL_MOUSEBUTTONDOWN); 1441 assert(this.sdlEvent.button.state == SDL_RELEASED); 1442 } 1443 1444 override string toString() const { 1445 return "dsdl2.MouseButtonUpEvent(%d, %d, %s, %d, %s)".format(this.windowID, 1446 this.which, this.button, this.clicks, this.xy); 1447 } 1448 } 1449 1450 /++ 1451 + D class that wraps `SDL_MOUSEWHEEL` `SDL_Event`s 1452 +/ 1453 final class MouseWheelEvent : Event { 1454 static if (sdlSupport >= SDLSupport.v2_0_18) { 1455 this(uint windowID, uint which, int[2] xy, MouseWheel direction = MouseWheel.normal, 1456 float[2] preciseXY = [0.0, 0.0]) { 1457 this.sdlEvent.type = SDL_MOUSEWHEEL; 1458 this.sdlEvent.wheel.windowID = windowID; 1459 this.sdlEvent.wheel.which = which; 1460 this.sdlEvent.wheel.x = xy[0]; 1461 this.sdlEvent.wheel.y = xy[1]; 1462 this.sdlEvent.wheel.direction = cast(uint) direction; 1463 this.sdlEvent.wheel.preciseX = preciseXY[0]; 1464 this.sdlEvent.wheel.preciseY = preciseXY[1]; 1465 } 1466 } 1467 else static if (sdlSupport >= SDLSupport.v2_0_4) { 1468 this(uint windowID, uint which, int[2] xy, MouseWheel direction = MouseWheel.normal) { 1469 this.sdlEvent.type = SDL_MOUSEWHEEL; 1470 this.sdlEvent.wheel.windowID = windowID; 1471 this.sdlEvent.wheel.which = which; 1472 this.sdlEvent.wheel.x = xy[0]; 1473 this.sdlEvent.wheel.y = xy[1]; 1474 this.sdlEvent.wheel.direction = cast(uint) direction; 1475 } 1476 } 1477 else { 1478 this(uint windowID, uint which, int[2] xy) { 1479 this.sdlEvent.type = SDL_MOUSEWHEEL; 1480 this.sdlEvent.wheel.windowID = windowID; 1481 this.sdlEvent.wheel.which = which; 1482 this.sdlEvent.wheel.x = xy[0]; 1483 this.sdlEvent.wheel.y = xy[1]; 1484 } 1485 } 1486 1487 invariant { 1488 assert(this.sdlEvent.type == SDL_MOUSEWHEEL); 1489 } 1490 1491 ref inout(uint) windowID() return inout @property { 1492 return this.sdlEvent.wheel.windowID; 1493 } 1494 1495 override string toString() const { 1496 static if (sdlSupport >= SDLSupport.v2_0_18) { 1497 return "dsdl2.MouseWheelEvent(%d, %d, %s, %s, %s)".format(this.windowID, this.which, 1498 this.xy, this.direction, this.preciseXY); 1499 } 1500 else static if (sdlSupport >= SDLSupport.v2_0_4) { 1501 return "dsdl2.MouseWheelEvent(%d, %d, %s, %s)".format(this.windowID, this.which, this.xy, 1502 this.direction); 1503 } 1504 else { 1505 return "dsdl2.MouseWheelEvent(%d, %d, %s)".format(this.windowID, this.which, this.xy); 1506 } 1507 } 1508 1509 ref inout(uint) which() return inout @property { 1510 return this.sdlEvent.wheel.which; 1511 } 1512 1513 ref inout(int) x() return inout @property { 1514 return this.sdlEvent.wheel.x; 1515 } 1516 1517 ref inout(int) y() return inout @property { 1518 return this.sdlEvent.wheel.y; 1519 } 1520 1521 ref inout(int[2]) xy() return inout @property @trusted { 1522 return *cast(inout(int[2]*))&this.sdlEvent.wheel.x; 1523 } 1524 1525 static if (sdlSupport >= SDLSupport.v2_0_4) { 1526 ref inout(MouseWheel) direction() return inout @property @trusted { 1527 return *cast(inout(MouseWheel*))&this.sdlEvent.wheel.direction; 1528 } 1529 } 1530 1531 static if (sdlSupport >= SDLSupport.v2_0_18) { 1532 ref inout(float) preciseX() return inout @property { 1533 return this.sdlEvent.wheel.preciseX; 1534 } 1535 1536 ref inout(float) preciseY() return inout @property { 1537 return this.sdlEvent.wheel.preciseY; 1538 } 1539 1540 ref inout(float[2]) preciseXY() return inout @property @trusted { 1541 return *cast(inout(float[2]*))&this.sdlEvent.wheel.preciseX; 1542 } 1543 } 1544 } 1545 1546 /++ 1547 + D abstract class that wraps touch finger `SDL_Event`s 1548 +/ 1549 abstract class FingerEvent : Event { 1550 invariant { 1551 assert(this.sdlEvent.type == SDL_FINGERMOTION || this.sdlEvent.type == SDL_FINGERDOWN 1552 || this.sdlEvent.type == SDL_FINGERUP); 1553 } 1554 1555 ref inout(ulong) touchID() return inout @property { 1556 return *cast(inout ulong*)&this.sdlEvent.tfinger.touchId; 1557 } 1558 1559 ref inout(ulong) fingerID() return inout @property { 1560 return *cast(inout ulong*)&this.sdlEvent.tfinger.fingerId; 1561 } 1562 1563 ref inout(float) x() return inout @property { 1564 return this.sdlEvent.tfinger.x; 1565 } 1566 1567 ref inout(float) y() return inout @property { 1568 return this.sdlEvent.tfinger.y; 1569 } 1570 1571 ref inout(float) dx() return inout @property { 1572 return this.sdlEvent.tfinger.dx; 1573 } 1574 1575 ref inout(float) dy() return inout @property { 1576 return this.sdlEvent.tfinger.dy; 1577 } 1578 1579 ref inout(float) pressure() return inout @property { 1580 return this.sdlEvent.tfinger.pressure; 1581 } 1582 1583 static if (sdlSupport >= SDLSupport.v2_0_12) { 1584 ref inout(uint) windowID() return inout @property { 1585 return this.sdlEvent.tfinger.windowID; 1586 } 1587 } 1588 1589 static Event fromSDL(SDL_Event sdlEvent) 1590 in { 1591 assert(sdlEvent.tfinger.type == SDL_FINGERMOTION || sdlEvent.tfinger.type == SDL_FINGERDOWN 1592 || sdlEvent.tfinger.type == SDL_FINGERUP); 1593 } 1594 do { 1595 Event event; 1596 switch (sdlEvent.type) { 1597 default: 1598 assert(false); 1599 1600 case SDL_FINGERMOTION: 1601 static if (sdlSupport >= SDLSupport.v2_0_12) { 1602 event = new FingerMotionEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1603 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure, 1604 sdlEvent.tfinger.windowID); 1605 } 1606 else { 1607 event = new FingerMotionEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1608 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure); 1609 } 1610 break; 1611 1612 case SDL_FINGERDOWN: 1613 static if (sdlSupport >= SDLSupport.v2_0_12) { 1614 event = new FingerDownEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1615 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure, 1616 sdlEvent.tfinger.windowID); 1617 } 1618 else { 1619 event = new FingerDownEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1620 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure); 1621 } 1622 break; 1623 1624 case SDL_FINGERUP: 1625 static if (sdlSupport >= SDLSupport.v2_0_12) { 1626 event = new FingerUpEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1627 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure, 1628 sdlEvent.tfinger.windowID); 1629 } 1630 else { 1631 event = new FingerUpEvent(sdlEvent.tfinger.touchId, sdlEvent.tfinger.fingerId, sdlEvent.tfinger.x, 1632 sdlEvent.tfinger.y, sdlEvent.tfinger.dx, sdlEvent.tfinger.dy, sdlEvent.tfinger.pressure); 1633 } 1634 break; 1635 } 1636 1637 event.timestamp = sdlEvent.tfinger.timestamp; 1638 return event; 1639 } 1640 } 1641 1642 /++ 1643 + D class that wraps `SDL_FINGERMOTION` `SDL_Event`s 1644 +/ 1645 class FingerMotionEvent : FingerEvent { 1646 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure) { 1647 this.sdlEvent.type = SDL_FINGERMOTION; 1648 this.sdlEvent.tfinger.touchId = touchID.to!long; 1649 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1650 this.sdlEvent.tfinger.x = x; 1651 this.sdlEvent.tfinger.y = y; 1652 this.sdlEvent.tfinger.dx = dx; 1653 this.sdlEvent.tfinger.dy = dy; 1654 this.sdlEvent.tfinger.pressure = pressure; 1655 } 1656 1657 static if (sdlSupport >= SDLSupport.v2_0_12) { 1658 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure, 1659 uint windowID) { 1660 this.sdlEvent.type = SDL_FINGERMOTION; 1661 this.sdlEvent.tfinger.touchId = touchID.to!long; 1662 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1663 this.sdlEvent.tfinger.x = x; 1664 this.sdlEvent.tfinger.y = y; 1665 this.sdlEvent.tfinger.dx = dx; 1666 this.sdlEvent.tfinger.dy = dy; 1667 this.sdlEvent.tfinger.pressure = pressure; 1668 this.sdlEvent.tfinger.windowID = windowID; 1669 } 1670 } 1671 1672 invariant { 1673 assert(this.sdlEvent.type == SDL_FINGERMOTION); 1674 } 1675 1676 override string toString() const { 1677 static if (sdlSupport >= SDLSupport.v2_0_12) { 1678 return "dsdl2.FingerMotionEvent(%d, %d, %f, %f, %f, %f, %f, %d)".format(this.touchID, this.fingerID, 1679 this.x, this.y, this.dx, this.dy, this.pressure, this.windowID); 1680 } 1681 else { 1682 return "dsdl2.FingerMotionEvent(%d, %d, %f, %f, %f, %f, %f)".format(this.touchID, this.fingerID, 1683 this.x, this.y, this.dx, this.dy, this.pressure); 1684 } 1685 } 1686 } 1687 1688 /++ 1689 + D class that wraps `SDL_FINGERDOWN` `SDL_Event`s 1690 +/ 1691 class FingerDownEvent : FingerEvent { 1692 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure) { 1693 this.sdlEvent.type = SDL_FINGERDOWN; 1694 this.sdlEvent.tfinger.touchId = touchID.to!long; 1695 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1696 this.sdlEvent.tfinger.x = x; 1697 this.sdlEvent.tfinger.y = y; 1698 this.sdlEvent.tfinger.dx = dx; 1699 this.sdlEvent.tfinger.dy = dy; 1700 this.sdlEvent.tfinger.pressure = pressure; 1701 } 1702 1703 static if (sdlSupport >= SDLSupport.v2_0_12) { 1704 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure, 1705 uint windowID) { 1706 this.sdlEvent.type = SDL_FINGERDOWN; 1707 this.sdlEvent.tfinger.touchId = touchID.to!long; 1708 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1709 this.sdlEvent.tfinger.x = x; 1710 this.sdlEvent.tfinger.y = y; 1711 this.sdlEvent.tfinger.dx = dx; 1712 this.sdlEvent.tfinger.dy = dy; 1713 this.sdlEvent.tfinger.pressure = pressure; 1714 this.sdlEvent.tfinger.windowID = windowID; 1715 } 1716 } 1717 1718 invariant { 1719 assert(this.sdlEvent.type == SDL_FINGERDOWN); 1720 } 1721 1722 override string toString() const { 1723 static if (sdlSupport >= SDLSupport.v2_0_12) { 1724 return "dsdl2.FingerDownEvent(%d, %d, %f, %f, %f, %f, %f, %d)".format(this.touchID, this.fingerID, 1725 this.x, this.y, this.dx, this.dy, this.pressure, this.windowID); 1726 } 1727 else { 1728 return "dsdl2.FingerDownEvent(%d, %d, %f, %f, %f, %f, %f)".format(this.touchID, this.fingerID, 1729 this.x, this.y, this.dx, this.dy, this.pressure); 1730 } 1731 } 1732 } 1733 1734 /++ 1735 + D class that wraps `SDL_FINGERUP` `SDL_Event`s 1736 +/ 1737 class FingerUpEvent : FingerEvent { 1738 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure) { 1739 this.sdlEvent.type = SDL_FINGERUP; 1740 this.sdlEvent.tfinger.touchId = touchID.to!long; 1741 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1742 this.sdlEvent.tfinger.x = x; 1743 this.sdlEvent.tfinger.y = y; 1744 this.sdlEvent.tfinger.dx = dx; 1745 this.sdlEvent.tfinger.dy = dy; 1746 this.sdlEvent.tfinger.pressure = pressure; 1747 } 1748 1749 static if (sdlSupport >= SDLSupport.v2_0_12) { 1750 this(ulong touchID, ulong fingerID, float x, float y, float dx, float dy, float pressure, 1751 uint windowID) { 1752 this.sdlEvent.type = SDL_FINGERUP; 1753 this.sdlEvent.tfinger.touchId = touchID.to!long; 1754 this.sdlEvent.tfinger.fingerId = fingerID.to!long; 1755 this.sdlEvent.tfinger.x = x; 1756 this.sdlEvent.tfinger.y = y; 1757 this.sdlEvent.tfinger.dx = dx; 1758 this.sdlEvent.tfinger.dy = dy; 1759 this.sdlEvent.tfinger.pressure = pressure; 1760 this.sdlEvent.tfinger.windowID = windowID; 1761 } 1762 } 1763 1764 invariant { 1765 assert(this.sdlEvent.type == SDL_FINGERUP); 1766 } 1767 1768 override string toString() const { 1769 static if (sdlSupport >= SDLSupport.v2_0_12) { 1770 return "dsdl2.FingerUpEvent(%d, %d, %f, %f, %f, %f, %f, %d)".format(this.touchID, this.fingerID, 1771 this.x, this.y, this.dx, this.dy, this.pressure, this.windowID); 1772 } 1773 else { 1774 return "dsdl2.FingerUpEvent(%d, %d, %f, %f, %f, %f, %f)".format(this.touchID, this.fingerID, 1775 this.x, this.y, this.dx, this.dy, this.pressure); 1776 } 1777 } 1778 } 1779 1780 /++ 1781 + D class that wraps `SDL_MULTIGESTURE` `SDL_Event`s 1782 +/ 1783 class MultiGestureEvent : Event { 1784 this(ulong touchID, float dTheta, float dDist, float x, float y, ushort numFingers) { 1785 this.sdlEvent.type = SDL_MULTIGESTURE; 1786 this.sdlEvent.mgesture.touchId = touchID.to!long; 1787 this.sdlEvent.mgesture.dTheta = dTheta; 1788 this.sdlEvent.mgesture.dDist = dDist; 1789 this.sdlEvent.mgesture.x = x; 1790 this.sdlEvent.mgesture.y = y; 1791 this.sdlEvent.mgesture.numFingers = numFingers; 1792 } 1793 1794 invariant { 1795 assert(this.sdlEvent.type == SDL_MULTIGESTURE); 1796 } 1797 1798 override string toString() const { 1799 return "dsdl2.MultiGestureEvent(%d, %f, %f, %f, %f, %d)".format(this.touchID, 1800 this.dTheta, this.dDist, this.x, this.y, this.numFingers); 1801 } 1802 1803 ref inout(ulong) touchID() return inout @property { 1804 return *cast(inout ulong*)&this.sdlEvent.mgesture.touchId; 1805 } 1806 1807 ref inout(float) dTheta() return inout @property { 1808 return this.sdlEvent.mgesture.dTheta; 1809 } 1810 1811 ref inout(float) dDist() return inout @property { 1812 return this.sdlEvent.mgesture.dDist; 1813 } 1814 1815 ref inout(float) x() return inout @property { 1816 return this.sdlEvent.mgesture.x; 1817 } 1818 1819 ref inout(float) y() return inout @property { 1820 return this.sdlEvent.mgesture.y; 1821 } 1822 1823 ref inout(ushort) numFingers() return inout @property { 1824 return this.sdlEvent.mgesture.numFingers; 1825 } 1826 } 1827 1828 /++ 1829 + D abstract class that wraps dollar gesture `SDL_Event`s 1830 +/ 1831 abstract class DollarEvent : Event { 1832 invariant { 1833 assert(this.sdlEvent.type == SDL_DOLLARGESTURE || this.sdlEvent.type == SDL_DOLLARRECORD); 1834 } 1835 1836 ref inout(ulong) touchID() return inout @property { 1837 return *cast(inout ulong*)&this.sdlEvent.dgesture.touchId; 1838 } 1839 1840 ref inout(ulong) gestureID() return inout @property { 1841 return *cast(inout ulong*)&this.sdlEvent.dgesture.gestureId; 1842 } 1843 1844 static Event fromSDL(SDL_Event sdlEvent) 1845 in { 1846 assert(sdlEvent.type == SDL_DOLLARGESTURE || sdlEvent.type == SDL_DOLLARRECORD); 1847 } 1848 do { 1849 Event event; 1850 switch (sdlEvent.type) { 1851 default: 1852 assert(false); 1853 1854 case SDL_DOLLARGESTURE: 1855 event = new DollarGestureEvent(sdlEvent.dgesture.touchId, sdlEvent.dgesture.gestureId, 1856 sdlEvent.dgesture.numFingers, sdlEvent.dgesture.error, sdlEvent.dgesture.x, sdlEvent.dgesture.y); 1857 break; 1858 1859 case SDL_DOLLARRECORD: 1860 event = new DollarRecordEvent(sdlEvent.dgesture.touchId, sdlEvent.dgesture.gestureId); 1861 break; 1862 } 1863 1864 event.timestamp = sdlEvent.tfinger.timestamp; 1865 return event; 1866 } 1867 } 1868 1869 /++ 1870 + D class that wraps `SDL_DOLLARGESTURE` `SDL_Event`s 1871 +/ 1872 class DollarGestureEvent : DollarEvent { 1873 this(ulong touchID, ulong gestureID, uint numFingers, float error, float x, float y) { 1874 this.sdlEvent.type = SDL_DOLLARGESTURE; 1875 this.sdlEvent.dgesture.touchId = touchID.to!long; 1876 this.sdlEvent.dgesture.gestureId = gestureID.to!long; 1877 this.sdlEvent.dgesture.numFingers = numFingers; 1878 this.sdlEvent.dgesture.error = error; 1879 this.sdlEvent.dgesture.x = x; 1880 this.sdlEvent.dgesture.y = y; 1881 } 1882 1883 invariant { 1884 assert(this.sdlEvent.type == SDL_DOLLARGESTURE); 1885 } 1886 1887 override string toString() const { 1888 return "dsdl2.DollarGestureEvent(%d, %d, %d, %f, %f, %f)".format(this.touchID, this.gestureID, this.numFingers, 1889 this.error, this.x, this.y); 1890 } 1891 1892 ref inout(uint) numFingers() return inout @property { 1893 return this.sdlEvent.dgesture.numFingers; 1894 } 1895 1896 ref inout(float) error() return inout @property { 1897 return this.sdlEvent.dgesture.error; 1898 } 1899 1900 ref inout(float) x() return inout @property { 1901 return this.sdlEvent.dgesture.x; 1902 } 1903 1904 ref inout(float) y() return inout @property { 1905 return this.sdlEvent.dgesture.y; 1906 } 1907 } 1908 1909 /++ 1910 + D class that wraps `SDL_DOLLARRECORD` `SDL_Event`s 1911 +/ 1912 class DollarRecordEvent : DollarEvent { 1913 this(ulong touchID, ulong gestureID) { 1914 this.sdlEvent.type = SDL_DOLLARRECORD; 1915 this.sdlEvent.dgesture.touchId = touchID.to!long; 1916 this.sdlEvent.dgesture.gestureId = gestureID.to!long; 1917 } 1918 1919 invariant { 1920 assert(this.sdlEvent.type == SDL_DOLLARRECORD); 1921 } 1922 1923 override string toString() const { 1924 return "dsdl2.DollarRecordEvent(%d, %d)".format(this.touchID, this.gestureID); 1925 } 1926 } 1927 1928 /++ 1929 + D abstract class that wraps drop `SDL_Event`s 1930 +/ 1931 abstract class DropEvent : Event { 1932 ~this() @trusted { 1933 if (this.sdlEvent.drop.file !is null) { 1934 SDL_free(this.sdlEvent.drop.file); 1935 } 1936 } 1937 1938 invariant { 1939 static if (sdlSupport >= SDLSupport.v2_0_5) { 1940 assert(this.sdlEvent.type == SDL_DROPFILE || this.sdlEvent.type == SDL_DROPTEXT 1941 || this.sdlEvent.type == SDL_DROPBEGIN || this.sdlEvent.type == SDL_DROPCOMPLETE); 1942 } 1943 else { 1944 assert(this.sdlEvent.type == SDL_DROPFILE); 1945 } 1946 } 1947 1948 static if (sdlSupport >= SDLSupport.v2_0_5) { 1949 ref inout(uint) windowID() return inout @property @trusted { 1950 return this.sdlEvent.drop.windowID; 1951 } 1952 } 1953 1954 static Event fromSDL(SDL_Event sdlEvent) @trusted 1955 in { 1956 static if (sdlSupport >= SDLSupport.v2_0_5) { 1957 assert(sdlEvent.type == SDL_DROPFILE || sdlEvent.type == SDL_DROPTEXT 1958 || sdlEvent.type == SDL_DROPBEGIN || sdlEvent.type == SDL_DROPCOMPLETE); 1959 } 1960 else { 1961 assert(sdlEvent.type == SDL_DROPFILE); 1962 } 1963 } 1964 do { 1965 Event event; 1966 switch (sdlEvent.type) { 1967 default: 1968 assert(false); 1969 1970 case SDL_DROPFILE: 1971 static if (sdlSupport >= SDLSupport.v2_0_5) { 1972 event = new DropFileEvent(sdlEvent.drop.file.to!string, sdlEvent.drop.windowID); 1973 } 1974 else { 1975 event = new DropFileEvent(sdlEvent.drop.file.to!string); 1976 } 1977 break; 1978 1979 static if (sdlSupport >= SDLSupport.v2_0_5) { 1980 case SDL_DROPTEXT: 1981 event = new DropTextEvent(sdlEvent.drop.file.to!string, sdlEvent.drop.windowID); 1982 break; 1983 1984 case SDL_DROPBEGIN: 1985 event = new DropBeginEvent(sdlEvent.drop.windowID); 1986 break; 1987 1988 case SDL_DROPCOMPLETE: 1989 event = new DropCompleteEvent(sdlEvent.drop.windowID); 1990 break; 1991 } 1992 } 1993 1994 event.timestamp = sdlEvent.drop.timestamp; 1995 return event; 1996 } 1997 } 1998 1999 /++ 2000 + D class that wraps `SDL_DROPFILE` `SDL_Event`s 2001 +/ 2002 class DropFileEvent : DropEvent { 2003 this(string file) @trusted { 2004 this.sdlEvent.type = SDL_DROPFILE; 2005 this.sdlEvent.drop.file = cast(char*) SDL_malloc(file.length + 1); 2006 this.sdlEvent.drop.file[0 .. file.length] = file[0 .. file.length]; 2007 this.sdlEvent.drop.file[file.length] = '\0'; 2008 } 2009 2010 static if (sdlSupport >= SDLSupport.v2_0_5) { 2011 this(string file, uint windowID) @trusted { 2012 this.sdlEvent.type = SDL_DROPFILE; 2013 this.sdlEvent.drop.file = cast(char*) SDL_malloc(file.length + 1); 2014 this.sdlEvent.drop.file[0 .. file.length] = file[0 .. file.length]; 2015 this.sdlEvent.drop.file[file.length] = '\0'; 2016 this.sdlEvent.drop.windowID = windowID; 2017 } 2018 } 2019 2020 @trusted invariant { // @suppress(dscanner.trust_too_much) 2021 assert(this.sdlEvent.type == SDL_DROPFILE); 2022 assert(this.sdlEvent.drop.file !is null); 2023 } 2024 2025 override string toString() const { 2026 static if (sdlSupport >= SDLSupport.v2_0_5) { 2027 return "dsdl2.DropFileEvent(%s, %d)".format(this.file, this.windowID); 2028 } 2029 else { 2030 return "dsdl2.DropFileEvent(%s)".format(this.file); 2031 } 2032 } 2033 2034 string file() const @property @trusted { 2035 return this.sdlEvent.drop.file.to!string; 2036 } 2037 2038 void file(string newFile) @property @trusted { 2039 SDL_realloc(this.sdlEvent.drop.file, newFile.length + 1); 2040 this.sdlEvent.drop.file[0 .. newFile.length] = newFile[0 .. newFile.length]; 2041 this.sdlEvent.drop.file[newFile.length] = '\0'; 2042 } 2043 } 2044 2045 static if (sdlSupport >= SDLSupport.v2_0_5) { 2046 /++ 2047 + D class that wraps `SDL_DROPTEXT` `SDL_Event`s (from SDL 2.0.5) 2048 +/ 2049 class DropTextEvent : DropEvent { 2050 this(string file, uint windowID) @trusted { 2051 this.sdlEvent.type = SDL_DROPTEXT; 2052 this.sdlEvent.drop.file = cast(char*) SDL_malloc(file.length + 1); 2053 this.sdlEvent.drop.file[0 .. file.length] = file[0 .. file.length]; 2054 this.sdlEvent.drop.file[file.length] = '\0'; 2055 this.sdlEvent.drop.windowID = windowID; 2056 } 2057 2058 @trusted invariant { // @suppress(dscanner.trust_too_much) 2059 assert(this.sdlEvent.type == SDL_DROPTEXT); 2060 assert(this.sdlEvent.drop.file !is null); 2061 } 2062 2063 override string toString() const { 2064 return "dsdl2.DropTextEvent(%s, %d)".format(this.file, this.windowID); 2065 } 2066 2067 string file() const @property @trusted { 2068 return this.sdlEvent.drop.file.to!string; 2069 } 2070 2071 void file(string newFile) @property @trusted { 2072 SDL_realloc(this.sdlEvent.drop.file, newFile.length + 1); 2073 this.sdlEvent.drop.file[0 .. newFile.length] = newFile[0 .. newFile.length]; 2074 this.sdlEvent.drop.file[newFile.length] = '\0'; 2075 } 2076 } 2077 2078 /++ 2079 + D class that wraps `SDL_DROPBEGIN` `SDL_Event`s (from SDL 2.0.5) 2080 +/ 2081 class DropBeginEvent : DropEvent { 2082 this(uint windowID) @trusted { 2083 this.sdlEvent.type = SDL_DROPBEGIN; 2084 this.sdlEvent.drop.windowID = windowID; 2085 } 2086 2087 invariant { 2088 assert(this.sdlEvent.type == SDL_DROPBEGIN); 2089 } 2090 2091 override string toString() const { 2092 return "dsdl2.DropBeginEvent(%d)".format(this.windowID); 2093 } 2094 } 2095 2096 /++ 2097 + D class that wraps `SDL_DROPCOMPLETE` `SDL_Event`s (from SDL 2.0.5) 2098 +/ 2099 class DropCompleteEvent : DropEvent { 2100 this(uint windowID) @trusted { 2101 this.sdlEvent.type = SDL_DROPCOMPLETE; 2102 this.sdlEvent.drop.windowID = windowID; 2103 } 2104 2105 invariant { 2106 assert(this.sdlEvent.type == SDL_DROPCOMPLETE); 2107 } 2108 2109 override string toString() const { 2110 return "dsdl2.DropCompleteEvent(%d)".format(this.windowID); 2111 } 2112 } 2113 }