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