rolmodl
C++ API for the Simple Directmedia Library 2 (SDL2)
Mouse.cpp
1 #include "hpp/Mouse.hpp"
2 
3 #include <cassert>
4 #include <utility>
5 
6 #include "hpp/Base.hpp"
7 
9 namespace rolmodl::mouse {
10  namespace cursor {
11  namespace unsafe {
12  void useRaw(Cursor* c) noexcept { // todo: weird API
13  using detail::active_cursor;
14 
15  if (active_cursor != nullptr)
16  active_cursor->unused();
17  SDL_SetCursor(c == nullptr ? SDL_GetDefaultCursor() : c->unsafeRaw());
18  }
19  }
20 
21  void useDefault() noexcept {
22  unsafe::useRaw(nullptr);
23  }
24 
25  namespace system {
26  Cursor create(const Type t) {
27  SDL_Cursor* c = SDL_CreateSystemCursor(type::unsafe::toSDLEnum(t));
28  if (c == nullptr)
29  throw sdlexception();
30  return Cursor(c);
31  }
32 
33  Cursor arrow() {
34  return create(Type::arrow);
35  }
36  Cursor iBeam() {
37  return create(Type::iBeam);
38  }
39  Cursor wait() {
40  return create(Type::wait);
41  }
42  Cursor crosshair() {
43  return create(Type::crosshair);
44  }
45  Cursor waitArrow() {
46  return create(Type::waitArrow);
47  }
48  Cursor forbidden() {
49  return create(Type::forbidden);
50  }
51  Cursor hand() {
52  return create(Type::hand);
53  }
54 
55  namespace resize {
56  Cursor nw_se() {
57  return create(Type::resize_nw_se);
58  }
59  Cursor ne_sw() {
60  return create(Type::resize_ne_sw);
61  }
62  Cursor we() {
63  return create(Type::resize_we);
64  }
65  Cursor ns() {
66  return create(Type::resize_ns);
67  }
68  Cursor all() {
69  return create(Type::resize_all);
70  }
71  }
72  }
73  }
74 
75  Cursor::Cursor() noexcept : Cursor(nullptr)
76  {}
77  /*explicit*/ Cursor::Cursor(SDL_Cursor* data) noexcept :
78  data_(data),
79  destructed_(false)
80  {}
81  Cursor::Cursor(Cursor&& that) noexcept :
82  Cursor()
83  {
84  swap(*this, that);
85  }
86  Cursor::~Cursor() {
87  if (cursor::detail::active_cursor == this) {
88  destructed_ = true;
89  return;
90  }
91 
92  free();
93  }
94 
95  Cursor& Cursor::operator=(Cursor&& that) noexcept {
96  swap(*this, that);
97  return *this;
98  }
99 
100  void swap(Cursor& a, Cursor& b) noexcept {
101  using std::swap;
102  swap(a.data_, b.data_);
103  swap(a.destructed_, b.destructed_);
104  }
105 
106  void Cursor::use() noexcept {
107  cursor::unsafe::useRaw(this);
108  }
109  void Cursor::unused() noexcept {
110  if (!destructed_)
111  return;
112  free();
113  }
114  void Cursor::free() noexcept {
115  if (data_ != nullptr)
116  SDL_FreeCursor(data_);
117  }
118 
119  SDL_Cursor* Cursor::unsafeRaw() noexcept {
120  assert(data_ != nullptr);
121  return data_;
122  }
123 
124  namespace detail {
125  /*explicit*/ BaseState::BaseState(const uint32_t b) noexcept :
126  btnState_(b)
127  {}
128  const geom::Pos& BaseState::pos() const noexcept {
129  return p_;
130  }
131  const BtnState& BaseState::btnState() const noexcept {
132  return btnState_;
133  }
134  }
135 
136  State::State() noexcept :
137  BaseState(SDL_GetMouseState(&p_.x, &p_.y))
138  {}
139  GlobalState::GlobalState() noexcept :
140  BaseState(SDL_GetGlobalMouseState(&p_.x, &p_.y))
141  {}
142 
143  void capture() {
144  throwOnErr(SDL_CaptureMouse(SDL_TRUE));
145  }
146  void release() {
147  throwOnErr(SDL_CaptureMouse(SDL_FALSE));
148  }
149 
150  void move(const geom::Pos p) {
151  throwOnErr(SDL_WarpMouseGlobal(p.x, p.y));
152  }
153 }
rolmodl::detail::throwOnErr
int throwOnErr(const int code)
Throw a rolmodl::sdlexception if code < 0.
Definition: Base.cpp:370
utility
std::system
T system(T... args)
std::swap
T swap(T... args)
cassert
Base.hpp