Skip to content

Commit 308c78f

Browse files
committed
feat: Add bitflags type (WindowFlags) for SDL_WindowFlags
1 parent ae94de8 commit 308c78f

File tree

1 file changed

+111
-28
lines changed

1 file changed

+111
-28
lines changed

src/sdl3/video.rs

Lines changed: 111 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,60 @@ impl DisplayMode {
477477
}
478478
}
479479

480+
/// Flags controlling various on/off state on a window. Bitflags wrapper around
481+
/// [`SDL_WindowFlags`].
482+
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
483+
pub struct WindowFlags(pub SDL_WindowFlags);
484+
485+
impl WindowFlags {
486+
pub const fn as_u32(self) -> u32 {
487+
self.0 as u32
488+
}
489+
}
490+
491+
impl From<SDL_WindowFlags> for WindowFlags {
492+
fn from(value: SDL_WindowFlags) -> Self {
493+
WindowFlags(value)
494+
}
495+
}
496+
497+
impl From<WindowFlags> for SDL_WindowFlags {
498+
fn from(value: WindowFlags) -> Self {
499+
value.0
500+
}
501+
}
502+
503+
bitflags! {
504+
impl WindowFlags: SDL_WindowFlags {
505+
const FULLSCREEN = sys::video::SDL_WINDOW_FULLSCREEN;
506+
const OPENGL = sys::video::SDL_WINDOW_OPENGL;
507+
const OCCLUDED = sys::video::SDL_WINDOW_OCCLUDED;
508+
const HIDDEN = sys::video::SDL_WINDOW_HIDDEN;
509+
const BORDERLESS = sys::video::SDL_WINDOW_BORDERLESS;
510+
const RESIZABLE = sys::video::SDL_WINDOW_RESIZABLE;
511+
const MINIMIZED = sys::video::SDL_WINDOW_MINIMIZED;
512+
const MAXIMIZED = sys::video::SDL_WINDOW_MAXIMIZED;
513+
const MOUSE_GRABBED = sys::video::SDL_WINDOW_MOUSE_GRABBED;
514+
const INPUT_FOCUS = sys::video::SDL_WINDOW_INPUT_FOCUS;
515+
const MOUSE_FOCUS = sys::video::SDL_WINDOW_MOUSE_FOCUS;
516+
const EXTERNAL = sys::video::SDL_WINDOW_EXTERNAL;
517+
const MODAL = sys::video::SDL_WINDOW_MODAL;
518+
const HIGH_PIXEL_DENSITY = sys::video::SDL_WINDOW_HIGH_PIXEL_DENSITY;
519+
const MOUSE_CAPTURE = sys::video::SDL_WINDOW_MOUSE_CAPTURE;
520+
const MOUSE_RELATIVE_MODE = sys::video::SDL_WINDOW_MOUSE_RELATIVE_MODE;
521+
const ALWAYS_ON_TOP = sys::video::SDL_WINDOW_ALWAYS_ON_TOP;
522+
const UTILITY = sys::video::SDL_WINDOW_UTILITY;
523+
const TOOLTIP = sys::video::SDL_WINDOW_TOOLTIP;
524+
const POPUP_MENU = sys::video::SDL_WINDOW_POPUP_MENU;
525+
const KEYBOARD_GRABBED = sys::video::SDL_WINDOW_KEYBOARD_GRABBED;
526+
const VULKAN = sys::video::SDL_WINDOW_VULKAN;
527+
const METAL = sys::video::SDL_WINDOW_METAL;
528+
const TRANSPARENT = sys::video::SDL_WINDOW_TRANSPARENT;
529+
const NOT_FOCUSABLE = sys::video::SDL_WINDOW_NOT_FOCUSABLE;
530+
const _ = !0;
531+
}
532+
}
533+
480534
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
481535
pub enum FullscreenType {
482536
Off = 0,
@@ -1229,7 +1283,7 @@ pub struct WindowBuilder {
12291283
height: u32,
12301284
x: WindowPos,
12311285
y: WindowPos,
1232-
window_flags: u32,
1286+
window_flags: WindowFlags,
12331287
create_metal_view: bool,
12341288
/// The window builder cannot be built on a non-main thread, so prevent cross-threaded moves and references.
12351289
/// `!Send` and `!Sync`,
@@ -1245,7 +1299,7 @@ impl WindowBuilder {
12451299
height,
12461300
x: WindowPos::Undefined,
12471301
y: WindowPos::Undefined,
1248-
window_flags: 0,
1302+
window_flags: WindowFlags(0),
12491303
subsystem: v.clone(),
12501304
create_metal_view: false,
12511305
}
@@ -1302,7 +1356,11 @@ impl WindowBuilder {
13021356
raw_height.into(),
13031357
);
13041358
let flags_cstr = CString::new("SDL.window.create.flags").unwrap();
1305-
SDL_SetNumberProperty(props, flags_cstr.as_ptr(), self.window_flags.into());
1359+
SDL_SetNumberProperty(
1360+
props,
1361+
flags_cstr.as_ptr(),
1362+
self.window_flags.0 as sys::stdinc::Sint64,
1363+
);
13061364

13071365
let raw = sys::video::SDL_CreateWindowWithProperties(props);
13081366
SDL_DestroyProperties(props);
@@ -1328,12 +1386,23 @@ impl WindowBuilder {
13281386

13291387
/// Gets the underlying window flags.
13301388
pub fn window_flags(&self) -> u32 {
1389+
self.window_flags.as_u32()
1390+
}
1391+
1392+
pub fn flags(&self) -> WindowFlags {
13311393
self.window_flags
13321394
}
13331395

13341396
/// Sets the underlying window flags.
13351397
/// This will effectively undo any previous build operations, excluding window size and position.
13361398
pub fn set_window_flags(&mut self, flags: u32) -> &mut WindowBuilder {
1399+
self.window_flags = WindowFlags(flags as SDL_WindowFlags);
1400+
self
1401+
}
1402+
1403+
/// Sets the underlying window flags.
1404+
/// This will effectively undo any previous build operations, excluding window size and position.
1405+
pub fn set_flags(&mut self, flags: WindowFlags) -> &mut WindowBuilder {
13371406
self.window_flags = flags;
13381407
self
13391408
}
@@ -1354,61 +1423,61 @@ impl WindowBuilder {
13541423

13551424
/// Sets the window to fullscreen.
13561425
pub fn fullscreen(&mut self) -> &mut WindowBuilder {
1357-
self.window_flags |= sys::video::SDL_WINDOW_FULLSCREEN as u32;
1426+
self.window_flags |= WindowFlags::FULLSCREEN;
13581427
self
13591428
}
13601429

13611430
/// Window uses high pixel density back buffer if possible.
13621431
pub fn high_pixel_density(&mut self) -> &mut WindowBuilder {
1363-
self.window_flags |= sys::video::SDL_WINDOW_HIGH_PIXEL_DENSITY as u32;
1432+
self.window_flags |= WindowFlags::HIGH_PIXEL_DENSITY;
13641433
self
13651434
}
13661435

13671436
/// Sets the window to be usable with an OpenGL context
13681437
pub fn opengl(&mut self) -> &mut WindowBuilder {
1369-
self.window_flags |= sys::video::SDL_WINDOW_OPENGL as u32;
1438+
self.window_flags |= WindowFlags::OPENGL;
13701439
self
13711440
}
13721441

13731442
/// Sets the window to be usable with a Vulkan instance
13741443
pub fn vulkan(&mut self) -> &mut WindowBuilder {
1375-
self.window_flags |= sys::video::SDL_WINDOW_VULKAN as u32;
1444+
self.window_flags |= WindowFlags::VULKAN;
13761445
self
13771446
}
13781447

13791448
/// Hides the window.
13801449
pub fn hidden(&mut self) -> &mut WindowBuilder {
1381-
self.window_flags |= sys::video::SDL_WINDOW_HIDDEN as u32;
1450+
self.window_flags |= WindowFlags::HIDDEN;
13821451
self
13831452
}
13841453

13851454
/// Removes the window decoration.
13861455
pub fn borderless(&mut self) -> &mut WindowBuilder {
1387-
self.window_flags |= sys::video::SDL_WINDOW_BORDERLESS as u32;
1456+
self.window_flags |= WindowFlags::BORDERLESS;
13881457
self
13891458
}
13901459

13911460
/// Sets the window to be resizable.
13921461
pub fn resizable(&mut self) -> &mut WindowBuilder {
1393-
self.window_flags |= sys::video::SDL_WINDOW_RESIZABLE as u32;
1462+
self.window_flags |= WindowFlags::RESIZABLE;
13941463
self
13951464
}
13961465

13971466
/// Minimizes the window.
13981467
pub fn minimized(&mut self) -> &mut WindowBuilder {
1399-
self.window_flags |= sys::video::SDL_WINDOW_MINIMIZED as u32;
1468+
self.window_flags |= WindowFlags::MINIMIZED;
14001469
self
14011470
}
14021471

14031472
/// Maximizes the window.
14041473
pub fn maximized(&mut self) -> &mut WindowBuilder {
1405-
self.window_flags |= sys::video::SDL_WINDOW_MAXIMIZED as u32;
1474+
self.window_flags |= WindowFlags::MAXIMIZED;
14061475
self
14071476
}
14081477

14091478
/// Sets the window to have grabbed input focus.
14101479
pub fn input_grabbed(&mut self) -> &mut WindowBuilder {
1411-
self.window_flags |= sys::video::SDL_WINDOW_MOUSE_GRABBED as u32;
1480+
self.window_flags |= WindowFlags::MOUSE_GRABBED;
14121481
self
14131482
}
14141483

@@ -1428,7 +1497,7 @@ pub struct PopupWindowBuilder {
14281497
height: u32,
14291498
offset_x: i32,
14301499
offset_y: i32,
1431-
window_flags: u32,
1500+
window_flags: WindowFlags,
14321501
create_metal_view: bool,
14331502
/// The window builder cannot be built on a non-main thread, so prevent cross-threaded moves and references.
14341503
/// `!Send` and `!Sync`,
@@ -1449,7 +1518,7 @@ impl PopupWindowBuilder {
14491518
height,
14501519
offset_x: 0,
14511520
offset_y: 0,
1452-
window_flags: 0,
1521+
window_flags: WindowFlags(0),
14531522
subsystem: v.clone(),
14541523
create_metal_view: false,
14551524
}
@@ -1465,15 +1534,17 @@ impl PopupWindowBuilder {
14651534
if self.height >= (1 << 31) {
14661535
return Err(HeightOverflows(self.width));
14671536
}
1468-
if (self.window_flags & sys::video::SDL_WINDOW_TOOLTIP as u32 != 0)
1469-
&& (self.window_flags & sys::video::SDL_WINDOW_POPUP_MENU as u32 != 0)
1537+
if self
1538+
.window_flags
1539+
.contains(WindowFlags::TOOLTIP | WindowFlags::POPUP_MENU)
14701540
{
14711541
return Err(SdlError(Error(
14721542
"SDL_WINDOW_TOOLTIP and SDL_WINDOW_POPUP are mutually exclusive".to_owned(),
14731543
)));
14741544
}
1475-
if (self.window_flags & sys::video::SDL_WINDOW_TOOLTIP as u32 == 0)
1476-
&& (self.window_flags & sys::video::SDL_WINDOW_POPUP_MENU as u32 == 0)
1545+
if !self
1546+
.window_flags
1547+
.intersects(WindowFlags::TOOLTIP | WindowFlags::POPUP_MENU)
14771548
{
14781549
return Err(SdlError(Error(
14791550
"SDL_WINDOW_TOOLTIP or SDL_WINDOW_POPUP are required for popup windows".to_owned(),
@@ -1509,12 +1580,24 @@ impl PopupWindowBuilder {
15091580

15101581
/// Gets the underlying window flags.
15111582
pub fn window_flags(&self) -> u32 {
1583+
self.window_flags.as_u32()
1584+
}
1585+
1586+
/// Gets the underlying window flags.
1587+
pub fn flags(&self) -> WindowFlags {
15121588
self.window_flags
15131589
}
15141590

15151591
/// Sets the underlying window flags.
15161592
/// This will effectively undo any previous build operations, excluding window size and position.
15171593
pub fn set_window_flags(&mut self, flags: u32) -> &mut PopupWindowBuilder {
1594+
self.window_flags = WindowFlags(flags as SDL_WindowFlags);
1595+
self
1596+
}
1597+
1598+
/// Sets the underlying window flags.
1599+
/// This will effectively undo any previous build operations, excluding window size and position.
1600+
pub fn set_flags(&mut self, flags: WindowFlags) -> &mut PopupWindowBuilder {
15181601
self.window_flags = flags;
15191602
self
15201603
}
@@ -1528,31 +1611,31 @@ impl PopupWindowBuilder {
15281611

15291612
/// Sets the window to be usable with an OpenGL context
15301613
pub fn opengl(&mut self) -> &mut PopupWindowBuilder {
1531-
self.window_flags |= sys::video::SDL_WINDOW_OPENGL as u32;
1614+
self.window_flags |= WindowFlags::OPENGL;
15321615
self
15331616
}
15341617

15351618
/// Sets the window to be usable with a Vulkan instance
15361619
pub fn vulkan(&mut self) -> &mut PopupWindowBuilder {
1537-
self.window_flags |= sys::video::SDL_WINDOW_VULKAN as u32;
1620+
self.window_flags |= WindowFlags::VULKAN;
15381621
self
15391622
}
15401623

15411624
/// Hides the window.
15421625
pub fn hidden(&mut self) -> &mut PopupWindowBuilder {
1543-
self.window_flags |= sys::video::SDL_WINDOW_HIDDEN as u32;
1626+
self.window_flags |= WindowFlags::HIDDEN;
15441627
self
15451628
}
15461629

15471630
/// Sets the window to be resizable.
15481631
pub fn resizable(&mut self) -> &mut PopupWindowBuilder {
1549-
self.window_flags |= sys::video::SDL_WINDOW_RESIZABLE as u32;
1632+
self.window_flags |= WindowFlags::RESIZABLE;
15501633
self
15511634
}
15521635

15531636
/// Sets the window to have grabbed input focus.
15541637
pub fn input_grabbed(&mut self) -> &mut PopupWindowBuilder {
1555-
self.window_flags |= sys::video::SDL_WINDOW_MOUSE_GRABBED as u32;
1638+
self.window_flags |= WindowFlags::MOUSE_GRABBED;
15561639
self
15571640
}
15581641

@@ -1566,25 +1649,25 @@ impl PopupWindowBuilder {
15661649

15671650
/// Sets the window to be a tooltip.
15681651
pub fn tooltip(&mut self) -> &mut PopupWindowBuilder {
1569-
self.window_flags |= sys::video::SDL_WINDOW_TOOLTIP as u32;
1652+
self.window_flags |= WindowFlags::TOOLTIP;
15701653
self
15711654
}
15721655

15731656
/// Sets the window to be a popup menu.
15741657
pub fn popup_menu(&mut self) -> &mut PopupWindowBuilder {
1575-
self.window_flags |= sys::video::SDL_WINDOW_POPUP_MENU as u32;
1658+
self.window_flags |= WindowFlags::POPUP_MENU;
15761659
self
15771660
}
15781661

15791662
/// Sets the window to be transparent
15801663
pub fn transparent(&mut self) -> &mut PopupWindowBuilder {
1581-
self.window_flags |= sys::video::SDL_WINDOW_TRANSPARENT as u32;
1664+
self.window_flags |= WindowFlags::TRANSPARENT;
15821665
self
15831666
}
15841667

15851668
/// Sets the window to be shown on top of all other windows
15861669
pub fn always_on_top(&mut self) -> &mut PopupWindowBuilder {
1587-
self.window_flags |= sys::video::SDL_WINDOW_ALWAYS_ON_TOP as u32;
1670+
self.window_flags |= WindowFlags::ALWAYS_ON_TOP;
15881671
self
15891672
}
15901673
}

0 commit comments

Comments
 (0)