1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use super::*;

mod gl_window;
pub use gl_window::*;

#[cfg(feature = "extern_crate_raw_window_handle")]
mod raw_window;
#[cfg(feature = "extern_crate_raw_window_handle")]
pub use raw_window::*;

/// A handle to an [`SDL_Window`](https://wiki.libsdl.org/SDL_CreateWindow).
///
/// This is the "Drawing Style Agnostic" core window stuff that's common to all
/// drawing APIs. You can't actually make one of these. Instead, you make a
/// window that's fused to the drawing API involved.
///
/// * [`SDL::crate_gl_window`](SDL::create_gl_window) gives a [`GlWindow`]
/// * ...more to come some day! (Vk and SDL Renderer)
#[repr(transparent)]
pub struct Window {
  // Note: The Init token is stored in the abstraction struct that bundles a
  // window with whatever else is being used to draw to the window (OGL, VK, or
  // SDL_Renderer) so that we don't have needless duplication.
  pub(crate) win: *mut fermium::SDL_Window,
}
impl Drop for Window {
  fn drop(&mut self) {
    unsafe { fermium::SDL_DestroyWindow(self.win) }
  }
}

impl Window {
  /// Use this to move the mouse to a given position within the window.
  ///
  /// This generates a mouse motion event.
  pub fn warp_mouse_in_window(&self, x: i32, y: i32) {
    unsafe { fermium::SDL_WarpMouseInWindow(self.win, x, y) }
  }
}

/// The starting position for a window.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WindowPosition {
  /// The (x,y) position specified.
  XY(i32, i32),
  /// Center the window on the screen.
  Centered,
  /// Put the window anywhere.
  Undefined,
}
impl Default for WindowPosition {
  /// ```rust
  /// use beryllium::WindowPosition;
  /// assert_eq!(WindowPosition::default(), WindowPosition::Undefined);
  /// ```
  fn default() -> Self {
    WindowPosition::Undefined
  }
}
impl WindowPosition {
  pub(crate) fn what_sdl_wants(self) -> (i32, i32) {
    match self {
      WindowPosition::XY(x, y) => (x, y),
      WindowPosition::Centered => (
        fermium::SDL_WINDOWPOS_CENTERED_MASK as i32,
        fermium::SDL_WINDOWPOS_CENTERED_MASK as i32,
      ),
      WindowPosition::Undefined => (
        fermium::SDL_WINDOWPOS_UNDEFINED_MASK as i32,
        fermium::SDL_WINDOWPOS_UNDEFINED_MASK as i32,
      ),
    }
  }
}

/// Allows you to specify the flags for window creation.
///
/// See [`SDL_WindowFlags`](https://wiki.libsdl.org/SDL_WindowFlags)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct WindowFlags(pub(crate) u32);
#[allow(non_upper_case_globals)]
impl WindowFlags {
  /// Window is visible.
  pub const Shown: WindowFlags = WindowFlags(fermium::SDL_WINDOW_SHOWN as u32);

  /// Window should support OpenGL.
  pub const OpenGL: WindowFlags =
    WindowFlags(fermium::SDL_WINDOW_OPENGL as u32);

  /// Window should support Vulkan.
  pub const Vulkan: WindowFlags =
    WindowFlags(fermium::SDL_WINDOW_VULKAN as u32);

  // TODO: more flags later.
}
impl core::ops::BitOr for WindowFlags {
  type Output = Self;
  fn bitor(self, rhs: Self) -> Self {
    Self(self.0 | rhs.0)
  }
}
impl core::ops::BitOrAssign for WindowFlags {
  fn bitor_assign(&mut self, rhs: Self) {
    *self = *self | rhs;
  }
}