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.window; 8 @safe: 9 10 import bindbc.sdl; 11 import dsdl2.sdl; 12 import dsdl2.display; 13 import dsdl2.pixels; 14 import dsdl2.rect; 15 import dsdl2.renderer; 16 import dsdl2.surface; 17 18 import core.memory : GC; 19 import std.conv : to; 20 import std.format : format; 21 import std.string : toStringz; 22 import std.typecons : Nullable, nullable; 23 24 /++ 25 + D enum that wraps `SDL_WINDOWPOS_*` to specify certain state of position in `dsdl2.Window` construction 26 +/ 27 enum WindowPos : uint { 28 centered = SDL_WINDOWPOS_CENTERED, /// Wraps `SDL_WINDOWPOS_CENTERED` which sets the window to be in the center 29 undefined = SDL_WINDOWPOS_UNDEFINED /// Wraps `SDL_WINDOWPOS_UNDEFINED` which leaves the window's position undefined 30 } 31 32 private uint toSDLWindowFlags(bool fullscreen, bool fullscreenDesktop, bool openGL, bool shown, bool hidden, 33 bool borderless, bool resizable, bool minimized, bool maximized, bool inputGrabbed, bool inputFocus, 34 bool mouseFocus, bool foreign, bool allowHighDPI, bool mouseCapture, bool alwaysOnTop, bool skipTaskbar, 35 bool utility, bool tooltip, bool popupMenu, bool vulkan, bool metal, bool mouseGrabbed, bool keyboardGrabbed) 36 in { 37 static if (sdlSupport < SDLSupport.v2_0_1) { 38 assert(allowHighDPI == false); 39 } 40 else { 41 if (allowHighDPI) { 42 assert(getVersion() >= Version(2, 0, 1)); 43 } 44 } 45 46 static if (sdlSupport < SDLSupport.v2_0_4) { 47 assert(mouseCapture == false); 48 } 49 else { 50 if (mouseCapture) { 51 assert(getVersion() >= Version(2, 0, 4)); 52 } 53 } 54 55 static if (sdlSupport < SDLSupport.v2_0_5) { 56 assert(alwaysOnTop == false); 57 assert(skipTaskbar == false); 58 assert(utility == false); 59 assert(tooltip == false); 60 assert(popupMenu == false); 61 } 62 else { 63 if (alwaysOnTop || skipTaskbar || utility || tooltip || popupMenu) { 64 assert(getVersion() >= Version(2, 0, 5)); 65 } 66 } 67 68 static if (sdlSupport < SDLSupport.v2_0_6) { 69 assert(vulkan == false); 70 assert(metal == false); 71 } 72 else { 73 if (vulkan || metal) { 74 assert(getVersion() >= Version(2, 0, 6)); 75 } 76 } 77 78 static if (sdlSupport < SDLSupport.v2_0_16) { 79 assert(mouseGrabbed == false); 80 assert(keyboardGrabbed == false); 81 } 82 else { 83 if (mouseGrabbed || keyboardGrabbed) { 84 assert(getVersion() >= Version(2, 0, 16)); 85 } 86 } 87 } 88 do { 89 uint flags = 0; 90 91 flags |= fullscreen ? SDL_WINDOW_FULLSCREEN : 0; 92 flags |= fullscreenDesktop ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; 93 flags |= openGL ? SDL_WINDOW_OPENGL : 0; 94 flags |= shown ? SDL_WINDOW_SHOWN : 0; 95 flags |= hidden ? SDL_WINDOW_HIDDEN : 0; 96 flags |= borderless ? SDL_WINDOW_BORDERLESS : 0; 97 flags |= resizable ? SDL_WINDOW_RESIZABLE : 0; 98 flags |= minimized ? SDL_WINDOW_MINIMIZED : 0; 99 flags |= maximized ? SDL_WINDOW_MAXIMIZED : 0; 100 flags |= inputGrabbed ? SDL_WINDOW_INPUT_GRABBED : 0; 101 flags |= inputFocus ? SDL_WINDOW_INPUT_FOCUS : 0; 102 flags |= mouseFocus ? SDL_WINDOW_MOUSE_FOCUS : 0; 103 flags |= foreign ? SDL_WINDOW_FOREIGN : 0; 104 105 static if (sdlSupport >= SDLSupport.v2_0_1) { 106 flags |= allowHighDPI ? SDL_WINDOW_ALLOW_HIGHDPI : 0; 107 } 108 static if (sdlSupport >= SDLSupport.v2_0_4) { 109 flags |= mouseCapture ? SDL_WINDOW_MOUSE_CAPTURE : 0; 110 } 111 static if (sdlSupport >= SDLSupport.v2_0_5) { 112 flags |= alwaysOnTop ? SDL_WINDOW_ALWAYS_ON_TOP : 0; 113 flags |= skipTaskbar ? SDL_WINDOW_SKIP_TASKBAR : 0; 114 flags |= utility ? SDL_WINDOW_UTILITY : 0; 115 flags |= tooltip ? SDL_WINDOW_TOOLTIP : 0; 116 flags |= popupMenu ? SDL_WINDOW_POPUP_MENU : 0; 117 } 118 static if (sdlSupport >= SDLSupport.v2_0_6) { 119 flags |= vulkan ? SDL_WINDOW_VULKAN : 0; 120 flags |= metal ? SDL_WINDOW_METAL : 0; 121 } 122 static if (sdlSupport >= SDLSupport.v2_0_16) { 123 flags |= mouseGrabbed ? SDL_WINDOW_MOUSE_GRABBED : 0; 124 flags |= keyboardGrabbed ? SDL_WINDOW_KEYBOARD_GRABBED : 0; 125 } 126 127 return flags; 128 } 129 130 static if (sdlSupport >= SDLSupport.v2_0_16) { 131 /++ 132 + D enum that wraps `SDL_FlashOperation` (from SDL 2.0.16) defining window flashing operations 133 +/ 134 enum FlashOperation { 135 /++ 136 + Wraps `SDL_FLASH_*` enumeration constants 137 +/ 138 cancel = SDL_FLASH_CANCEL, 139 briefly = SDL_FLASH_BRIEFLY, /// ditto 140 untilFocused = SDL_FLASH_UNTIL_FOCUSED /// ditto 141 } 142 } 143 144 /++ 145 + D class that wraps `SDL_Window` managing a window instance specific to the OS 146 + 147 + `dsdl2.Window` provides access to creating windows and managing them for rendering. Internally, SDL uses 148 + OS functions to summon the window. 149 + 150 + Example: 151 + --- 152 + auto window = new dsdl2.Window("My Window", [dsdl2.WindowPos.centered, dsdl2.WindowPos.centered], [800, 600]); 153 + window.surface.fill(dsdl2.Color(255, 0, 0)); 154 + window.update(); 155 + --- 156 +/ 157 final class Window { 158 private PixelFormat pixelFormatProxy = null; 159 private Surface surfaceProxy = null; 160 private bool isOwner = true; 161 private void* userRef = null; 162 163 @system SDL_Window* sdlWindow = null; /// Internal `SDL_Window` pointer 164 165 /++ 166 + Constructs a `dsdl2.Window` from a vanilla `SDL_Window*` from bindbc-sdl 167 + 168 + Params: 169 + sdlWindow = the `SDL_Window` pointer to manage 170 + isOwner = whether the instance owns the given `SDL_Window*` and should destroy it on its own 171 + userRef = optional pointer to maintain reference link, avoiding GC cleanup 172 +/ 173 this(SDL_Window* sdlWindow, bool isOwner = true, void* userRef = null) @system 174 in { 175 assert(sdlWindow !is null); 176 } 177 do { 178 this.sdlWindow = sdlWindow; 179 this.isOwner = isOwner; 180 this.userRef = userRef; 181 } 182 183 /++ 184 + Creates an SDL-handled window from a native pointer handle of the OS, which wraps `SDL_CreateWindowFrom` 185 + 186 + Params: 187 + nativeHandle = pointer to the native OS window 188 + Throws: `dsdl2.SDLException` if window creation failed 189 +/ 190 this(void* nativeHandle) @system 191 in { 192 assert(nativeHandle !is null); 193 } 194 do { 195 this.sdlWindow = SDL_CreateWindowFrom(nativeHandle); 196 if (this.sdlWindow is null) { 197 throw new SDLException; 198 } 199 } 200 201 /++ 202 + Creates a window on the desktop placed at a coordinate in the screen, which wraps `SDL_CreateWindow` 203 + 204 + Params: 205 + title = title given to the shown window 206 + position = top-left position of the window in the desktop environment (pair of two `uint`s or flags from 207 + `dsdl2.WindowPos`) 208 + size = size of the window in pixels 209 + fullscreen = adds `SDL_WINDOW_FULLSCREEN` flag 210 + fullscreenDesktop = adds `SDL_WINDOW_FULLSCREEN_DESKTOP` flag 211 + openGL = adds `SDL_WINDOW_OPENGL` flag 212 + shown = adds `SDL_WINDOW_SHOWN` flag 213 + hidden = adds `SDL_WINDOW_HIDDEN` flag 214 + borderless = adds `SDL_WINDOW_BORDERLESS` flag 215 + resizable = adds `SDL_WINDOW_RESIZABLE` flag 216 + minimized = adds `SDL_WINDOW_MINIMIZED` flag 217 + maximized = adds `SDL_WINDOW_MAXIMIZED` flag 218 + inputGrabbed = adds `SDL_WINDOW_INPUT_GRABBED` flag 219 + inputFocus = adds `SDL_WINDOW_INPUT_FOCUS` flag 220 + mouseFocus = adds `SDL_WINDOW_MOUSE_FOCUS` flag 221 + foreign = adds `SDL_WINDOW_FOREIGN` flag 222 + allowHighDPI = adds `SDL_WINDOW_ALLOW_HIGHDPI` flag (from SDL 2.0.1) 223 + mouseCapture = adds `SDL_WINDOW_MOUSE_CAPTURE` flag (from SDL 2.0.2) 224 + alwaysOnTop = adds `SDL_WINDOW_ALWAYS_ON_TOP` flag (from SDL 2.0.5) 225 + skipTaskbar = adds `SDL_WINDOW_SKIP_TASKBAR` flag (from SDL 2.0.5) 226 + utility = adds `SDL_WINDOW_UTILITY` flag (from SDL 2.0.5) 227 + tooltip = adds `SDL_WINDOW_TOOLTIP` flag (from SDL 2.0.5) 228 + popupMenu = adds `SDL_WINDOW_POPUP_MENU` flag (from SDL 2.0.5) 229 + vulkan = adds `SDL_WINDOW_VULKAN` flag (from SDL 2.0.6) 230 + metal = adds `SDL_WINDOW_METAL` flag (from SDL 2.0.6) 231 + mouseGrabbed = adds `SDL_WINDOW_MOUSE_GRABBED` flag (from SDL 2.0.16) 232 + keyboardGrabbed = adds `SDL_WINDOW_KEYBOARD_GRABBED` flag (from SDL 2.0.16) 233 + Throws: `dsdl2.SDLException` if window creation failed 234 +/ 235 this(string title, uint[2] position, uint[2] size, bool fullscreen = false, bool fullscreenDesktop = false, 236 bool openGL = false, bool shown = false, bool hidden = false, bool borderless = false, bool resizable = false, 237 bool minimized = false, bool maximized = false, bool inputGrabbed = false, bool inputFocus = false, 238 bool mouseFocus = false, bool foreign = false, bool allowHighDPI = false, bool mouseCapture = false, 239 bool alwaysOnTop = false, bool skipTaskbar = false, bool utility = false, bool tooltip = false, 240 bool popupMenu = false, bool vulkan = false, bool metal = false, bool mouseGrabbed = false, 241 bool keyboardGrabbed = false) @trusted 242 in { 243 assert(title !is null); 244 } 245 do { 246 uint flags = toSDLWindowFlags(fullscreen, fullscreenDesktop, openGL, shown, hidden, borderless, resizable, 247 minimized, maximized, inputGrabbed, inputFocus, mouseFocus, foreign, allowHighDPI, mouseCapture, 248 alwaysOnTop, skipTaskbar, utility, tooltip, popupMenu, vulkan, metal, mouseGrabbed, keyboardGrabbed); 249 250 this.sdlWindow = SDL_CreateWindow(title.toStringz(), position[0].to!int, position[1].to!int, 251 size[0].to!int, size[1].to!int, flags); 252 if (this.sdlWindow is null) { 253 throw new SDLException; 254 } 255 } 256 257 ~this() @trusted { 258 if (this.isOwner) { 259 SDL_DestroyWindow(this.sdlWindow); 260 } 261 } 262 263 @trusted invariant { // @suppress(dscanner.trust_too_much) 264 // Instance might be in an invalid state due to holding a non-owned externally-freed object when 265 // destructed in an unpredictable order. 266 if (!this.isOwner && GC.inFinalizer) { 267 return; 268 } 269 270 assert(this.sdlWindow !is null); 271 } 272 273 /++ 274 + Equality operator overload 275 +/ 276 bool opEquals(const Window rhs) const @trusted { 277 return this.sdlWindow is rhs.sdlWindow; 278 } 279 280 /++ 281 + Gets the hash of the `dsdl2.Window` 282 + 283 + Returns: unique hash for the instance being the pointer of the internal `SDL_Window` pointer 284 +/ 285 override hash_t toHash() const @trusted { 286 return cast(hash_t) this.sdlWindow; 287 } 288 289 /++ 290 + Formats the `dsdl2.Window` into its construction representation: `"dsdl2.Window(<sdlWindow>)"` 291 + 292 + Returns: the formatted `string` 293 +/ 294 override string toString() const @trusted { 295 return "dsdl2.Window(0x%x)".format(this.sdlWindow); 296 } 297 298 /++ 299 + Wraps `SDL_GetWindowID` which gets the internal window ID of the `dsdl2.Window` 300 + 301 + Returns: `uint` of the internal window ID 302 +/ 303 uint id() const @property @trusted { 304 return SDL_GetWindowID(cast(SDL_Window*) this.sdlWindow); 305 } 306 307 /++ 308 + Wraps `SDL_GetWindowDisplayIndex` which gets the display where the center of the window is located 309 + 310 + Returns: `dsdl2.Display` of the display the window is located 311 + Throws: `dsdl2.SDLException` if failed to get the display 312 +/ 313 const(Display) display() const @property @trusted { 314 int index = SDL_GetWindowDisplayIndex(cast(SDL_Window*) this.sdlWindow); 315 if (index < 0) { 316 throw new SDLException; 317 } 318 319 return getDisplays()[index]; 320 } 321 322 /++ 323 + Wraps `SDL_GetWindowDisplayMode` which gets the window's display mode attributes 324 + 325 + Returns: `dsdl2.DisplayMode` storing the attributes 326 + Throws: `dsdl2.SDLException` if failed to get the display mode 327 +/ 328 DisplayMode displayMode() const @property @trusted { 329 SDL_DisplayMode sdlMode = void; 330 if (SDL_GetWindowDisplayMode(cast(SDL_Window*) this.sdlWindow, &sdlMode) != 0) { 331 throw new SDLException; 332 } 333 334 return DisplayMode(sdlMode); 335 } 336 337 /++ 338 + Wraps `SDL_SetWindowDisplayMode` which sets new display mode attributes to the window 339 + 340 + Params: 341 + newDisplayMode = `dsdl2.DisplayMode` containing the desired attributes 342 + Throws: `dsdl2.SDLException` if failed to set the display mode 343 +/ 344 void displayMode(DisplayMode newDisplayMode) @property @trusted { 345 SDL_DisplayMode sdlMode = newDisplayMode.sdlDisplayMode; 346 if (SDL_SetWindowDisplayMode(this.sdlWindow, &sdlMode) != 0) { 347 throw new SDLException; 348 } 349 } 350 351 /++ 352 + Gets the `dsdl2.PixelFormat` used for pixel data of the window 353 + 354 + Returns: read-only `dsdl2.PixelFormat` instance 355 +/ 356 const(PixelFormat) pixelFormat() const @property @trusted { 357 // If the internal pixel format pointer happens to change, rewire the proxy. 358 if (this.pixelFormatProxy is null || 359 this.pixelFormatProxy.sdlPixelFormatEnum !is SDL_GetWindowPixelFormat(cast(SDL_Window*) this.sdlWindow)) { 360 (cast(Window) this).pixelFormatProxy = 361 new PixelFormat(SDL_GetWindowPixelFormat(cast(SDL_Window*) this.sdlWindow)); 362 } 363 364 return this.pixelFormatProxy; 365 } 366 367 /++ 368 + Wraps `SDL_GetRenderer` which gets the renderer of the window 369 + 370 + Returns: `dsdl2.Renderer` proxy 371 +/ 372 inout(Renderer) renderer() inout @property @trusted { 373 if (SDL_Renderer* sdlRenderer = SDL_GetRenderer(cast(SDL_Window*) this.sdlWindow)) { 374 return cast(inout(Renderer)) new Renderer(sdlRenderer, false, cast(void*) this); 375 } 376 else { 377 throw new SDLException; 378 } 379 } 380 381 /++ 382 + Wraps `SDL_GetWindowTitle` which gets the shown title of the window 383 + 384 + Returns: title `string` of the window 385 +/ 386 string title() const @property @trusted { 387 return SDL_GetWindowTitle(cast(SDL_Window*) this.sdlWindow).to!string; 388 } 389 390 /++ 391 + Wraps `SDL_SetWindowTitle` which sets a new title to the window 392 + 393 + Params: 394 + newTitle = `string` of the new title 395 +/ 396 void title(string newTitle) @property @trusted { 397 SDL_SetWindowTitle(this.sdlWindow, newTitle.toStringz()); 398 } 399 400 /++ 401 + Wraps `SDL_SetWindowIcon` which sets a new icon to the window 402 + 403 + Params: 404 + newIcon = `dsdl2.Surface` of the new icon 405 +/ 406 void icon(Surface newIcon) @property @trusted 407 in { 408 assert(newIcon !is null); 409 } 410 do { 411 SDL_SetWindowIcon(this.sdlWindow, newIcon.sdlSurface); 412 } 413 414 /++ 415 + Wraps `SDL_GetWindowPosition` which gets the top-left X coordinate position of the window in 416 + the desktop environment 417 + 418 + Returns: top-left X coordinate position of the window in the desktop environment 419 +/ 420 int x() const @property @trusted { 421 int x = void; 422 SDL_GetWindowPosition(cast(SDL_Window*) this.sdlWindow, &x, null); 423 return x; 424 } 425 426 /++ 427 + Wraps `SDL_SetWindowPosition` which sets the X position of the window in the desktop environment 428 + 429 + Params: 430 + newX = top-left X coordinate of the new window position in the desktop environment 431 +/ 432 void x(int newX) @property @trusted { 433 SDL_SetWindowPosition(this.sdlWindow, newX, this.y); 434 } 435 436 /++ 437 + Wraps `SDL_GetWindowPosition` which gets the top-left Y coordinate position of the window in 438 + the desktop environment 439 + 440 + Returns: top-left Y coordinate position of the window in the desktop environment 441 +/ 442 int y() const @property @trusted { 443 int y = void; 444 SDL_GetWindowPosition(cast(SDL_Window*) this.sdlWindow, null, &y); 445 return y; 446 } 447 448 /++ 449 + Wraps `SDL_SetWindowPosition` which sets the Y position of the window in the desktop environment 450 + 451 + Params: 452 + newY = top-left Y coordinate of the new window position in the desktop environment 453 +/ 454 void y(int newY) @property @trusted { 455 SDL_SetWindowPosition(this.sdlWindow, this.x, newY); 456 } 457 458 /++ 459 + Wraps `SDL_GetWindowPosition` which gets the top-left coordinate position of the window in 460 + the desktop environment 461 + 462 + Returns: top-left coordinate position of the window in the desktop environment 463 +/ 464 int[2] position() const @property @trusted { 465 int[2] xy = void; 466 SDL_GetWindowPosition(cast(SDL_Window*) this.sdlWindow, &xy[0], &xy[1]); 467 return xy; 468 } 469 470 /++ 471 + Wraps `SDL_SetWindowPosition` which sets the position of the window in the desktop environment 472 + 473 + Params: 474 + newPosition = top-left coordinate of the new window position in the desktop environment 475 +/ 476 void position(int[2] newPosition) @property @trusted { 477 SDL_SetWindowPosition(this.sdlWindow, newPosition[0], newPosition[1]); 478 } 479 480 /++ 481 + Wraps `SDL_GetWindowSize` which gets the width of the window in pixels 482 + 483 + Returns: width of the window in pixels 484 +/ 485 uint width() const @property @trusted { 486 uint w = void; 487 SDL_GetWindowSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&w, null); 488 return w; 489 } 490 491 /++ 492 + Wraps `SDL_SetWindowSize` which resizes the width of the window in pixels 493 + 494 + Params: 495 + newWidth = new resized width of the window in pixels 496 +/ 497 void width(uint newWidth) @property @trusted { 498 SDL_SetWindowSize(this.sdlWindow, newWidth.to!int, this.height); 499 } 500 501 /++ 502 + Wraps `SDL_GetWindowSize` which gets the height of the window in pixels 503 + 504 + Returns: height of the window in pixels 505 +/ 506 uint height() const @property @trusted { 507 uint h = void; 508 SDL_GetWindowSize(cast(SDL_Window*) this.sdlWindow, null, cast(int*)&h); 509 return h; 510 } 511 512 /++ 513 + Wraps `SDL_SetWindowSize` which resizes the height of the window in pixels 514 + 515 + Params: 516 + newHeight = new resized height of the window in pixels 517 +/ 518 void height(uint newHeight) @property @trusted { 519 SDL_SetWindowSize(this.sdlWindow, this.width, newHeight.to!int); 520 } 521 522 /++ 523 + Wraps `SDL_GetWindowSize` which gets the size of the window in pixels 524 + 525 + Returns: size of the window in pixels 526 +/ 527 uint[2] size() const @property @trusted { 528 uint[2] wh = void; 529 SDL_GetWindowSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&wh[0], cast(int*)&wh[1]); 530 return wh; 531 } 532 533 /++ 534 + Wraps `SDL_SetWindowSize` which resizes the size of the window in pixels 535 + 536 + Params: 537 + newSize = new resized size of the window in pixels (width and height) 538 +/ 539 void size(uint[2] newSize) @property @trusted { 540 SDL_SetWindowSize(this.sdlWindow, newSize[0].to!int, newSize[1].to!int); 541 } 542 543 /++ 544 + Wraps `SDL_GetWindowMinimumSize` which gets the minimum size in pixels that the window can be 545 + resized to 546 + 547 + Returns: minimum set size of the window in pixels 548 +/ 549 uint[2] minimumSize() const @property @trusted { 550 uint[2] wh; 551 SDL_GetWindowMinimumSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&wh[0], cast(int*)&wh[1]); 552 return wh; 553 } 554 555 /++ 556 + Wraps `SDL_SetWindowMinimumSize` which sets the minimum size in pixels that the window can be 557 + resized to 558 + 559 + Params: 560 + newMinimumSize = new minimum set size of the window in pixels (width and height) 561 +/ 562 void minimumSize(uint[2] newMinimumSize) @property @trusted { 563 SDL_SetWindowMinimumSize(this.sdlWindow, newMinimumSize[0].to!int, 564 newMinimumSize[1].to!int); 565 } 566 567 /++ 568 + Wraps `SDL_GetWindowMaximumSize` which gets the maximum size in pixels that the window can be 569 + resized to 570 + 571 + Returns: maximum set size of the window in pixels 572 +/ 573 uint[2] maximumSize() const @property @trusted { 574 uint[2] wh; 575 SDL_GetWindowMaximumSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&wh[0], cast(int*)&wh[1]); 576 return wh; 577 } 578 579 /++ 580 + Wraps `SDL_SetWindowMaximumSize` which sets the maximum size in pixels that the window can be 581 + resized to 582 + 583 + Params: 584 + newMaximumSize = new maximum set size of the window in pixels (width and height) 585 +/ 586 void maximumSize(uint[2] newMaximumSize) @property @trusted { 587 SDL_SetWindowMaximumSize(this.sdlWindow, newMaximumSize[0].to!int, 588 newMaximumSize[1].to!int); 589 } 590 591 /++ 592 + Wraps `SDL_ShowWindow` which sets the window to be visible in the desktop environment 593 +/ 594 void show() @trusted { 595 SDL_ShowWindow(this.sdlWindow); 596 } 597 598 /++ 599 + Wraps `SDL_HideWindow` which sets the window to be invisible in the desktop environment 600 +/ 601 void hide() @trusted { 602 SDL_HideWindow(this.sdlWindow); 603 } 604 605 /++ 606 + Wraps `SDL_RaiseWindow` which raises the window above other windows, and sets input focus to the window 607 +/ 608 void raise() @trusted { 609 SDL_RaiseWindow(this.sdlWindow); 610 } 611 612 /++ 613 + Wraps `SDL_MaximizeWindow` which maximizes the window in the desktop environment 614 +/ 615 void maximize() @trusted { 616 SDL_MaximizeWindow(this.sdlWindow); 617 } 618 619 /++ 620 + Wraps `SDL_MinimizeWindow` which minimizes the window in the desktop environment 621 +/ 622 void minimize() @trusted { 623 SDL_MinimizeWindow(this.sdlWindow); 624 } 625 626 /++ 627 + Wraps `SDL_RestoreWindow` which restores the size and position of the window as it was originally 628 +/ 629 void restore() @trusted { 630 SDL_RestoreWindow(this.sdlWindow); 631 } 632 633 /++ 634 + Wraps `SDL_GetWindowFlags` to check whether the window is in real fullscreen 635 + 636 + Returns: `true` if the the window is in real fullscreen, otherwise `false` 637 +/ 638 bool fullscreen() const @property @trusted { 639 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN; 640 } 641 642 /++ 643 + Wraps `SDL_SetWindowFullscreen` which sets the fullscreen mode of the window 644 + 645 + Params: 646 + newFullscreen = `true` to make the window fullscreen, otherwise `false` 647 + Throws: `dsdl2.SDLException` if failed to set the window's fullscreen mode 648 +/ 649 void fullscreen(bool newFullscreen) @property @trusted { 650 if (SDL_SetWindowFullscreen(this.sdlWindow, newFullscreen ? SDL_WINDOW_FULLSCREEN : 0) != 0) { 651 throw new SDLException; 652 } 653 } 654 655 /++ 656 + Wraps `SDL_GetWindowFlags` to check whether the window is in desktop fullscreen 657 + 658 + Returns: `true` if the the window is in desktop fullscreen, otherwise `false` 659 +/ 660 bool fullscreenDesktop() const @property @trusted { 661 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) == 662 SDL_WINDOW_FULLSCREEN_DESKTOP; 663 } 664 665 /++ 666 + Wraps `SDL_GetWindowFlags` to check whether the window utilizes OpenGL 667 + 668 + Returns: `true` if the the window utilizes OpenGL, otherwise `false` 669 +/ 670 bool openGL() const @property @trusted { 671 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL; 672 } 673 674 static if (sdlSupport >= SDLSupport.v2_0_6) { 675 /++ 676 + Wraps `SDL_GetWindowFlags` to check whether the window utilizes Vulkan (from SDL 2.0.6) 677 + 678 + Returns: `true` if the the window utilizes Vulkan, otherwise `false` 679 +/ 680 bool vulkan() const @property @trusted 681 in { 682 assert(getVersion() >= Version(2, 0, 6)); 683 } 684 do { 685 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_VULKAN) == SDL_WINDOW_VULKAN; 686 } 687 688 /++ 689 + Wraps `SDL_GetWindowFlags` to check whether the window utilizes Metal (from SDL 2.0.6) 690 + 691 + Returns: `true` if the the window utilizes Metal, otherwise `false` 692 +/ 693 bool metal() const @property @trusted 694 in { 695 assert(getVersion() >= Version(2, 0, 6)); 696 } 697 do { 698 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_METAL) == SDL_WINDOW_METAL; 699 } 700 } 701 702 /++ 703 + Wraps `SDL_GetWindowFlags` to check whether the window is foreign 704 + 705 + Returns: `true` if the the window is foreign, otherwise `false` 706 +/ 707 bool foreign() const @property @trusted { 708 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_FOREIGN) == SDL_WINDOW_FOREIGN; 709 } 710 711 /++ 712 + Wraps `SDL_GetWindowFlags` to check whether the window is shown 713 + 714 + Returns: `true` if the the window is shown, otherwise `false` 715 +/ 716 bool shown() const @property @trusted { 717 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_SHOWN) == SDL_WINDOW_SHOWN; 718 } 719 720 /++ 721 + Wraps `SDL_GetWindowFlags` to check whether the window is hidden 722 + 723 + Returns: `true` if the the window is hidden, otherwise `false` 724 +/ 725 bool hidden() const @property @trusted { 726 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_HIDDEN) == SDL_WINDOW_HIDDEN; 727 } 728 729 /++ 730 + Wraps `SDL_GetWindowFlags` to check whether the borders of the window are non-existent 731 + 732 + Returns: `true` if borders of the window are non-existent, otherwise `false` 733 +/ 734 bool borderless() const @property @trusted { 735 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_BORDERLESS) == SDL_WINDOW_BORDERLESS; 736 } 737 738 /++ 739 + Wraps `SDL_GetWindowFlags` to check whether the borders of the window are visible 740 + 741 + Returns: `true` if borders are visible, otherwise `false` 742 +/ 743 bool bordered() const @property @trusted { 744 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_BORDERLESS) != SDL_WINDOW_BORDERLESS; 745 } 746 747 /++ 748 + Wraps `SDL_SetWindowBordered` which sets whether the borders' visibility 749 + 750 + Params: 751 + newBordered = `true` to make the borders visible, otherwise `false` 752 +/ 753 void bordered(bool newBordered) @property @trusted { 754 SDL_SetWindowBordered(this.sdlWindow, newBordered); 755 } 756 757 /++ 758 + Wraps `SDL_GetWindowFlags` to check whether the window's size is resizable by the user 759 + 760 + Returns: `true` if the window is resizable, otherwise `false` 761 +/ 762 bool resizable() const @property @trusted { 763 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_RESIZABLE) == SDL_WINDOW_RESIZABLE; 764 } 765 766 static if (sdlSupport >= SDLSupport.v2_0_5) { 767 /++ 768 + Wraps `SDL_SetWindowResizable` (from SDL 2.0.5) which sets the window's resizability 769 + 770 + Params: 771 + newResizable = `true` to make the window resizable, otherwise `false` 772 +/ 773 void resizable(bool newResizable) @property @trusted 774 in { 775 assert(getVersion() >= Version(2, 0, 5)); 776 } 777 do { 778 SDL_SetWindowResizable(this.sdlWindow, newResizable); 779 } 780 } 781 782 /++ 783 + Wraps `SDL_GetWindowFlags` to check whether the window is minimized 784 + 785 + Returns: `true` if window is minimized, otherwise `false` 786 +/ 787 bool minimized() const @property @trusted { 788 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_MINIMIZED) == SDL_WINDOW_MINIMIZED; 789 } 790 791 /++ 792 + Wraps `SDL_GetWindowFlags` to check whether the window is maximized 793 + 794 + Returns: `true` if window is maximized, otherwise `false` 795 +/ 796 bool maximized() const @property @trusted { 797 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_MAXIMIZED) == SDL_WINDOW_MAXIMIZED; 798 } 799 800 static if (sdlSupport >= SDLSupport.v2_0_1) { 801 /++ 802 + Wraps `SDL_GetWindowFlags` to check whether the window allows high DPI (from SDL 2.0.1) 803 + 804 + Returns: `true` if window allows high DPI, otherwise `false` 805 +/ 806 bool allowsHighDPI() const @property @trusted 807 in { 808 assert(getVersion() >= Version(2, 0, 1)); 809 } 810 do { 811 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_ALLOW_HIGHDPI) == 812 SDL_WINDOW_ALLOW_HIGHDPI; 813 } 814 } 815 816 static if (sdlSupport >= SDLSupport.v2_0_5) { 817 /++ 818 + Wraps `SDL_GetWindowFlags` to check whether the window is always on top (from SDL 2.0.5) 819 + 820 + Returns: `true` if window is always on top, otherwise `false` 821 +/ 822 bool alwaysOnTop() const @property @trusted 823 in { 824 assert(getVersion() >= Version(2, 0, 5)); 825 } 826 do { 827 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_ALWAYS_ON_TOP) == 828 SDL_WINDOW_ALWAYS_ON_TOP; 829 } 830 831 /++ 832 + Wraps `SDL_GetWindowFlags` to check whether the window is not on the taskbar (from SDL 2.0.5) 833 + 834 + Returns: `true` if window is not on the taskbar, otherwise `false` 835 +/ 836 bool skipsTaskbar() const @property @trusted 837 in { 838 assert(getVersion() >= Version(2, 0, 5)); 839 } 840 do { 841 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_SKIP_TASKBAR) == 842 SDL_WINDOW_SKIP_TASKBAR; 843 } 844 845 /++ 846 + Wraps `SDL_GetWindowFlags` to check whether the window is treated as a utility window (from SDL 2.0.5) 847 + 848 + Returns: `true` if window is treated as a utility window, otherwise `false` 849 +/ 850 bool utility() const @property @trusted 851 in { 852 assert(getVersion() >= Version(2, 0, 5)); 853 } 854 do { 855 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_UTILITY) == 856 SDL_WINDOW_UTILITY; 857 } 858 859 /++ 860 + Wraps `SDL_GetWindowFlags` to check whether the window is treated as a tooltip window (from SDL 2.0.5) 861 + 862 + Returns: `true` if window is treated as a tooltip window, otherwise `false` 863 +/ 864 bool tooltip() const @property @trusted 865 in { 866 assert(getVersion() >= Version(2, 0, 5)); 867 } 868 do { 869 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_TOOLTIP) == 870 SDL_WINDOW_TOOLTIP; 871 } 872 873 /++ 874 + Wraps `SDL_GetWindowFlags` to check whether the window is treated as a popup menu (from SDL 2.0.5) 875 + 876 + Returns: `true` if window is treated as a popup menu, otherwise `false` 877 +/ 878 bool popupMenu() const @property @trusted 879 in { 880 assert(getVersion() >= Version(2, 0, 5)); 881 } 882 do { 883 return (SDL_GetWindowFlags(cast(SDL_Window*) this.sdlWindow) & SDL_WINDOW_POPUP_MENU) == 884 SDL_WINDOW_POPUP_MENU; 885 } 886 } 887 888 /++ 889 + Wraps `SDL_GetWindowGrab` which gets the window's input grab mode 890 + 891 + Returns: `true` if the window is in input grab mode, otherwise `false` 892 +/ 893 bool inputGrab() const @property @trusted { 894 return SDL_GetWindowGrab(cast(SDL_Window*) this.sdlWindow) == SDL_TRUE; 895 } 896 897 /++ 898 + Wraps `SDL_SetWindowGrab` which sets the window's input grab mode 899 + 900 + Params: 901 + newGrab = `true` to set the window on input grab mode, otherwise `false` 902 +/ 903 void inputGrab(bool newGrab) @property @trusted { 904 SDL_SetWindowGrab(this.sdlWindow, newGrab); 905 } 906 907 /++ 908 + Wraps `SDL_GetWindowBrightness` which gets the window's brightness value 909 + 910 + Returns: `float` value from `0.0` to `1.0` indicating the window's brightness 911 +/ 912 float brightness() const @property @trusted { 913 return SDL_GetWindowBrightness(cast(SDL_Window*) this.sdlWindow); 914 } 915 916 /++ 917 + Wraps `SDL_SetWindowBrightness` which sets the window's brightness value 918 + 919 + Params: 920 + newBrightness = `float` value specifying the window's brightness from `0.0` (darkest) to `1.0` (brightest) 921 + Throws: `dsdl2.SDLException` if failed to set the window's brightness value 922 +/ 923 void brightness(float newBrightness) @property @trusted { 924 if (SDL_SetWindowBrightness(this.sdlWindow, newBrightness) != 0) { 925 throw new SDLException; 926 } 927 } 928 929 /++ 930 + Wraps `SDL_IsScreenKeyboardShown` which checks whether the screen keyboard is shown on the window 931 + 932 + Returns: `true` if the screen keyboard is shown, otherwise `false` 933 +/ 934 bool hasShownScreenKeyboard() const @property @trusted { 935 return SDL_IsScreenKeyboardShown(cast(SDL_Window*) this.sdlWindow) == SDL_TRUE; 936 } 937 938 /++ 939 + Wraps `SDL_GetKeyboardFocus` which verifies whether keyboard input is focused to the window 940 + 941 + Returns: `true` if keyboard input is focused, otherwise `false` 942 +/ 943 bool keyboardFocused() const @property @trusted { 944 return SDL_GetKeyboardFocus() == this.sdlWindow; 945 } 946 947 /++ 948 + Wraps `SDL_GetMouseFocus` which verifies whether mouse input is focused to the window 949 + 950 + Returns: `true` if mouse input is focused, otherwise `false` 951 +/ 952 bool mouseFocused() const @property @trusted { 953 return SDL_GetMouseFocus() == this.sdlWindow; 954 } 955 956 /++ 957 + Wraps `SDL_GetMouseState` which gets the mouse position in the window 958 + 959 + Returns: `[x, y]` of the mouse position relative to the window, otherwise `[-1, -1]` if mouse input is not 960 + focused to the window 961 +/ 962 int[2] mousePosition() const @property @trusted { 963 if (SDL_GetMouseFocus() != this.sdlWindow) { 964 return [-1, -1]; 965 } 966 967 int[2] pos = void; 968 SDL_GetMouseState(&pos[0], &pos[1]); 969 return pos; 970 } 971 972 /++ 973 + Wraps `SDL_WarpMouseInWindow` which sets the mouse position in the window 974 + 975 + Params: 976 + newMousePosition = coordinate of the mouse position to set 977 +/ 978 void mousePosition(int[2] newMousePosition) @property @trusted { 979 SDL_WarpMouseInWindow(this.sdlWindow, newMousePosition[0], newMousePosition[1]); 980 } 981 982 /++ 983 + Wraps `SDL_GetWindowSurface` which gets the window's surface for software rendering 984 + 985 + Returns: `dsdl2.Surface` proxy to the window's surface 986 + Throws: `dsdl2.SDLException` if failed to get the window's surface 987 +/ 988 inout(Surface) surface() inout @property @trusted { 989 SDL_Surface* surfacePtr = SDL_GetWindowSurface(cast(SDL_Window*) this.sdlWindow); 990 if (surfacePtr is null) { 991 throw new SDLException; 992 } 993 994 if (this.surfaceProxy is null) { 995 (cast(Window) this).surfaceProxy = new Surface(surfacePtr, false, cast(void*) this); 996 } 997 998 // If the surface pointer happens to change, rewire the proxy. 999 if (this.surfaceProxy.sdlSurface !is surfacePtr) { 1000 (cast(Window) this).surfaceProxy.sdlSurface = surfacePtr; 1001 } 1002 1003 return this.surfaceProxy; 1004 } 1005 1006 static if (sdlSupport >= SDLSupport.v2_28) { 1007 /++ 1008 + Wraps `SDL_DestroyWindowSurface` (from SDL 2.28) which destructs the underlying associated surface 1009 + of the window 1010 + 1011 + Throws: `dsdl2.SDLException` if failed to destruct the surface 1012 +/ 1013 void surface(typeof(null) _) @property @trusted 1014 in { 1015 assert(getVersion() >= Version(2, 28)); 1016 } 1017 do { 1018 if (SDL_DestroyWindowSurface(this.sdlWindow) != 0) { 1019 throw new SDLException; 1020 } 1021 } 1022 1023 /++ 1024 + Wraps `SDL_HasWindowSurface` (from SDL 2.28) which checks whether there is a surface associated with 1025 + the window 1026 + 1027 + Returns: `true` if the window has an associated surface, otherwise `false` 1028 +/ 1029 bool hasSurface() const @property @trusted 1030 in { 1031 assert(getVersion() >= Version(2, 28)); 1032 } 1033 do { 1034 return SDL_HasWindowSurface(cast(SDL_Window*) this.sdlWindow) == SDL_TRUE; 1035 } 1036 } 1037 1038 /++ 1039 + Wraps `SDL_UpdateWindowSurface` which makes the changes to the window's surface current 1040 + 1041 + Throws: `dsdl2.SDLException` if failed to update the window's changes 1042 +/ 1043 void update() @trusted { 1044 if (SDL_UpdateWindowSurface(this.sdlWindow) != 0) { 1045 throw new SDLException; 1046 } 1047 } 1048 1049 /++ 1050 + Wraps `SDL_UpdateWindowSurfaceRects` which makes the changes of certain parts of the window surface 1051 + as defined by a list of `dsdl2.Rect`s current 1052 + 1053 + Params: 1054 + rects = array of `dsdl2.Rect`s defining parts of the window surface to update 1055 + Throws: `dsdl2.SDLException` if failed to update the window's changes 1056 +/ 1057 void update(Rect[] rects) @trusted { 1058 if (SDL_UpdateWindowSurfaceRects(this.sdlWindow, cast(SDL_Rect*) rects.ptr, 1059 rects.length.to!int) != 0) { 1060 throw new SDLException; 1061 } 1062 } 1063 1064 /++ 1065 + Wraps `SDL_GL_SwapWindow` which updates the window with any OpenGL changes 1066 +/ 1067 void swapGL() @trusted { 1068 SDL_GL_SwapWindow(this.sdlWindow); 1069 } 1070 1071 static if (sdlSupport >= SDLSupport.v2_0_1) { 1072 /++ 1073 + Wraps `SDL_GL_GetDrawableSize` (from SDL 2.0.1) which gets the drawable height of the window in OpenGL 1074 + in pixels 1075 + 1076 + Returns: height of the window in OpenGL in pixels 1077 +/ 1078 uint drawableGLWidth() const @property @trusted 1079 in { 1080 assert(getVersion() >= Version(2, 0, 1)); 1081 } 1082 do { 1083 uint w = void; 1084 SDL_GL_GetDrawableSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&w, null); 1085 return w; 1086 } 1087 1088 /++ 1089 + Wraps `SDL_GL_GetDrawableSize` (from SDL 2.0.1) which gets the drawable width of the window in OpenGL 1090 + in pixels 1091 + 1092 + Returns: width of the window in OpenGL in pixels 1093 +/ 1094 uint drawableGLHeight() const @property @trusted 1095 in { 1096 assert(getVersion() >= Version(2, 0, 1)); 1097 } 1098 do { 1099 uint h = void; 1100 SDL_GL_GetDrawableSize(cast(SDL_Window*) this.sdlWindow, null, cast(int*)&h); 1101 return h; 1102 } 1103 1104 /++ 1105 + Wraps `SDL_GL_GetDrawableSize` (from SDL 2.0.1) which gets the drawable size of the window in OpenGL 1106 + in pixels 1107 + 1108 + Returns: size of the window in OpenGL in pixels 1109 +/ 1110 uint[2] drawableGLSize() const @property @trusted 1111 in { 1112 assert(getVersion() >= Version(2, 0, 1)); 1113 } 1114 do { 1115 uint[2] wh = void; 1116 SDL_GL_GetDrawableSize(cast(SDL_Window*) this.sdlWindow, cast(int*)&wh[0], cast(int*)&wh[1]); 1117 return wh; 1118 } 1119 } 1120 1121 static if (sdlSupport >= SDLSupport.v2_0_5) { 1122 /++ 1123 + Wraps `SDL_SetWindowInputFocus` (from SDL 2.0.5) which focuses the window to be in reach to the user 1124 + 1125 + Throws: `dsdl2.SDLException` if failed to focus the window 1126 +/ 1127 void focus() @trusted 1128 in { 1129 assert(getVersion() >= Version(2, 0, 5)); 1130 } 1131 do { 1132 if (SDL_SetWindowInputFocus(this.sdlWindow) != 0) { 1133 throw new SDLException; 1134 } 1135 } 1136 1137 /++ 1138 + Wraps `SDL_SetWindowModalFor` (from SDL 2.0.5) which sets the window to be a modal of another parent 1139 + window, making the window always be above its parent window 1140 + 1141 + Params: 1142 + parent = the parent window which owns the window as a modal 1143 + Throws: `dsdl2.SDLException` if failed to set the window as modal 1144 +/ 1145 void modalFor(Window parent) @trusted 1146 in { 1147 assert(getVersion() >= Version(2, 0, 5)); 1148 assert(parent !is null); 1149 } 1150 do { 1151 if (SDL_SetWindowModalFor(this.sdlWindow, parent.sdlWindow) != 0) { 1152 throw new SDLException; 1153 } 1154 } 1155 1156 /++ 1157 + Wraps `SDL_GetWindowOpacity` (from SDL 2.0.5) which gets the opacity of the window 1158 + 1159 + Returns: `float` indicating the opacity of the window from `0.0` (transparent) to `1.0` (opaque) 1160 + Throws: `dsdl2.SDLException` if failed to get the window's opacity 1161 +/ 1162 float opacity() const @property @trusted 1163 in { 1164 assert(getVersion() >= Version(2, 0, 5)); 1165 } 1166 do { 1167 float alpha = void; 1168 if (SDL_GetWindowOpacity(cast(SDL_Window*) this.sdlWindow, &alpha) != 0) { 1169 throw new SDLException; 1170 } 1171 1172 return alpha; 1173 } 1174 1175 /++ 1176 + Wraps `SDL_SetWindowOpacity` (from SDL 2.0.5) which sets the opacity of the window 1177 + 1178 + Params: 1179 + newOpacity = `float` indicating the opacity of the window from `0.0` (transparent) to `1.0` (opaque) 1180 + Throws: `dsdl2.SDLException` if failed to set the window's opacity 1181 +/ 1182 void opacity(float newOpacity) @property @trusted 1183 in { 1184 assert(getVersion() >= Version(2, 0, 5)); 1185 } 1186 do { 1187 if (SDL_SetWindowOpacity(this.sdlWindow, newOpacity) != 0) { 1188 throw new SDLException; 1189 } 1190 } 1191 } 1192 1193 static if (sdlSupport >= SDLSupport.v2_0_16) { 1194 /++ 1195 + Wraps `SDL_FlashWindow` (from SDL 2.0.16) which flashes the window in the desktop environment 1196 + 1197 + Params: 1198 + operation = flashing operation to do 1199 + Throws: `dsdl2.SDLException` if failed to flash the window 1200 +/ 1201 void flash(FlashOperation operation) @trusted 1202 in { 1203 assert(getVersion() >= Version(2, 0, 16)); 1204 } 1205 do { 1206 if (SDL_FlashWindow(this.sdlWindow, operation) != 0) { 1207 throw new SDLException; 1208 } 1209 } 1210 1211 /++ 1212 + Wraps `SDL_SetWindowAlwaysOnTop` (from SDL 2.0.16) which sets the status of the window always 1213 + being on top above other windows 1214 + 1215 + Params: 1216 + newOnTop = `true` to always make the window to be on top, otherwise `false` 1217 +/ 1218 void onTop(bool newOnTop) @property @trusted 1219 in { 1220 assert(getVersion() >= Version(2, 0, 16)); 1221 } 1222 do { 1223 SDL_SetWindowAlwaysOnTop(this.sdlWindow, newOnTop); 1224 } 1225 1226 /++ 1227 + Wraps `SDL_GetWindowKeyboardGrab` (from SDL 2.0.16) which gets the status of the window grabbing 1228 + onto keyboard input 1229 + 1230 + Returns: `true` if the window is grabbing onto keyboard input, otherwise `false` 1231 +/ 1232 bool keyboardGrab() const @property @trusted 1233 in { 1234 assert(getVersion() >= Version(2, 0, 16)); 1235 } 1236 do { 1237 return SDL_GetWindowKeyboardGrab(cast(SDL_Window*) this.sdlWindow) == SDL_TRUE; 1238 } 1239 1240 /++ 1241 + Wraps `SDL_SetWindowKeyboardGrab` (from SDL 2.0.16) which sets the status of the window grabbing 1242 + onto keyboard input 1243 + 1244 + Params: 1245 + newKeyboardGrab = `true` to enable keyboard grab, otherwise `false` 1246 +/ 1247 void keyboardGrab(bool newKeyboardGrab) @property @trusted 1248 in { 1249 assert(getVersion() >= Version(2, 0, 16)); 1250 } 1251 do { 1252 SDL_SetWindowKeyboardGrab(this.sdlWindow, newKeyboardGrab); 1253 } 1254 1255 /++ 1256 + Wraps `SDL_GetWindowMouseGrab` (from SDL 2.0.16) which gets the status of the window grabbing 1257 + onto mouse input 1258 + 1259 + Returns: `true` if the window is grabbing onto mouse input, otherwise `false` 1260 +/ 1261 bool mouseGrab() const @property @trusted 1262 in { 1263 assert(getVersion() >= Version(2, 0, 16)); 1264 } 1265 do { 1266 return SDL_GetWindowMouseGrab(cast(SDL_Window*) this.sdlWindow) == SDL_TRUE; 1267 } 1268 1269 /++ 1270 + Wraps `SDL_SetWindowMouseGrab` (from SDL 2.0.16) which sets the status of the window grabbing 1271 + onto mouse input 1272 + 1273 + Params: 1274 + newMouseGrab = `true` to enable mouse grab, otherwise `false` 1275 +/ 1276 void mouseGrab(bool newMouseGrab) @property @trusted 1277 in { 1278 assert(getVersion() >= Version(2, 0, 16)); 1279 } 1280 do { 1281 SDL_SetWindowMouseGrab(this.sdlWindow, newMouseGrab); 1282 } 1283 } 1284 1285 static if (sdlSupport >= SDLSupport.v2_0_18) { 1286 /++ 1287 + Wraps `SDL_GetWindowICCProfile` (from SDL 2.0.18) which gets the raw ICC profile data for the 1288 + screen the window is currently on 1289 + 1290 + Returns: untyped array buffer of the raw ICC profile data 1291 + Throws `dsdl2.SDLException` if failed to obtain the ICC profile data 1292 +/ 1293 void[] iccProfile() const @property @trusted 1294 in { 1295 assert(getVersion() >= Version(2, 0, 18)); 1296 } 1297 do { 1298 size_t size = void; 1299 void* data = SDL_GetWindowICCProfile(cast(SDL_Window*) this.sdlWindow, &size); 1300 scope (exit) 1301 SDL_free(data); 1302 1303 if (data is null) { 1304 throw new SDLException; 1305 } 1306 1307 // Copies the data under allocation with the GC, as `data` is a manually-handled resource 1308 // allocated by SDL 1309 return data[0 .. size].dup; 1310 } 1311 1312 /++ 1313 + Wraps `SDL_GetWindowMouseRect` (from SDL 2.0.18) which gets the window's mouse confinement rectangle 1314 + 1315 + Returns: `dsdl2.Rect` of the mouse's confinement rectangle in the window 1316 +/ 1317 Nullable!Rect mouseRect() const @property @trusted 1318 in { 1319 assert(getVersion() >= Version(2, 0, 18)); 1320 } 1321 do { 1322 const(SDL_Rect)* rect = SDL_GetWindowMouseRect(cast(SDL_Window*) this.sdlWindow); 1323 if (rect is null) { 1324 return Nullable!Rect.init; 1325 } 1326 else { 1327 return Rect(*rect).nullable; 1328 } 1329 } 1330 1331 /++ 1332 + Wraps `SDL_SetWindowMouseRect` (from SDL 2.0.18) which sets the window's mouse confinement rectangle 1333 + 1334 + Params: 1335 + newMouseRect = `dsdl2.Rect` specifying the rectangle in window coordinate space to confine the mouse 1336 + pointer in 1337 + Throws: `dsdl2.SDLException` if failed to set the confinement 1338 +/ 1339 void mouseRect(Rect newMouseRect) @property @trusted 1340 in { 1341 assert(getVersion() >= Version(2, 0, 18)); 1342 } 1343 do { 1344 if (SDL_SetWindowMouseRect(this.sdlWindow, &newMouseRect.sdlRect) != 0) { 1345 throw new SDLException; 1346 } 1347 } 1348 1349 /++ 1350 + Acts as `SDL_SetWindowMouseRect(window, NULL)` (from SDL 2.0.18) which resets the window's mouse 1351 + confinement rectangle 1352 + 1353 + Throws: `dsdl2.SDLException` if failed to reset the confinement 1354 +/ 1355 void mouseRect(typeof(null) _) @property @trusted 1356 in { 1357 assert(getVersion() >= Version(2, 0, 18)); 1358 } 1359 do { 1360 if (SDL_SetWindowMouseRect(this.sdlWindow, null) != 0) { 1361 throw new SDLException; 1362 } 1363 } 1364 1365 /++ 1366 + Wraps `SDL_SetWindowMouseRect` (from SDL 2.0.18) which sets or resets the window's mouse 1367 + confinement rectangle 1368 + 1369 + Params: 1370 + newMouseRect = `dsdl2.Rect` specifying the rectangle in window coordinate space to confine the mouse 1371 + pointer in; `null` to reset the confinement 1372 + Throws: `dsdl2.SDLException` if failed to set or reset the confinement 1373 +/ 1374 void mouseRect(Nullable!Rect newMouseRect) @property @trusted 1375 in { 1376 assert(getVersion() >= Version(2, 0, 18)); 1377 } 1378 do { 1379 if (newMouseRect.isNull) { 1380 this.mouseRect = null; 1381 } 1382 else { 1383 this.mouseRect = newMouseRect.get; 1384 } 1385 } 1386 } 1387 1388 static if (sdlSupport >= SDLSupport.v2_26) { 1389 /++ 1390 + Wraps `SDL_GetWindowSizeInPixels` (from SDL 2.26) which gets the actual size of the window in the 1391 + screen in pixels 1392 + 1393 + Returns: actual size of the window in the screen in pixels 1394 +/ 1395 uint[2] sizeInPixels() const @property @trusted 1396 in { 1397 assert(getVersion() >= Version(2, 26)); 1398 } 1399 do { 1400 uint[2] size = void; 1401 SDL_GetWindowSizeInPixels(cast(SDL_Window*) this.sdlWindow, cast(int*)&size[0], 1402 cast(int*)&size[1]); 1403 return size; 1404 } 1405 } 1406 }