rolmodl
C++ API for the Simple Directmedia Library 2 (SDL2)
Mouse.hpp
1 #pragma once
2 
3 #include "forwarddecl/Mouse.hpp"
4 
5 #include "Geom.hpp"
6 
7 namespace rolmodl::mouse {
8  class Cursor {
9  public:
10  Cursor(const Cursor& that) = delete;
11  Cursor(Cursor&& that) noexcept;
12  ~Cursor();
13 
14  Cursor& operator=(const Cursor& that) = delete;
15  Cursor& operator=(Cursor&& that) noexcept;
16 
17  friend void swap(Cursor& a, Cursor& b) noexcept;
18 
19  void use() noexcept;
20  SDL_Cursor* unsafeRaw() noexcept;
21 
22  private:
23  Cursor() noexcept;
24  explicit Cursor(SDL_Cursor* data) noexcept;
25 
26  friend Cursor cursor::system::create(const cursor::system::Type t);
27  friend void cursor::unsafe::useRaw(Cursor* c) noexcept;
28 
29  void unused() noexcept;
30  void free() noexcept;
31 
32  SDL_Cursor* data_;
33  bool destructed_;
34  };
35  namespace cursor {
36  namespace detail {
37  static Cursor* active_cursor = nullptr; // todo: use optional?
38  }
39  namespace unsafe {
40  void useRaw(Cursor* c) noexcept;
41  }
42 
43  void useDefault() noexcept;
44  namespace system {
45  enum class Type {
46  arrow, iBeam, wait, crosshair, waitArrow, forbidden, hand,
47  resize_nw_se, resize_ne_sw, resize_we, resize_ns, resize_all
48  };
49 
50  namespace type::unsafe {
51  constexpr SDL_SystemCursor toSDLEnum(const Type t) noexcept {
52  if (t == Type::arrow)
53  return SDL_SYSTEM_CURSOR_ARROW;
54  else if (t == Type::iBeam)
55  return SDL_SYSTEM_CURSOR_IBEAM;
56  else if (t == Type::wait)
57  return SDL_SYSTEM_CURSOR_WAIT;
58  else if (t == Type::crosshair)
59  return SDL_SYSTEM_CURSOR_CROSSHAIR;
60  else if (t == Type::waitArrow)
61  return SDL_SYSTEM_CURSOR_WAITARROW;
62  else if (t == Type::resize_nw_se)
63  return SDL_SYSTEM_CURSOR_SIZENWSE;
64  else if (t == Type::resize_ne_sw)
65  return SDL_SYSTEM_CURSOR_SIZENESW;
66  else if (t == Type::resize_we)
67  return SDL_SYSTEM_CURSOR_SIZEWE;
68  else if (t == Type::resize_ns)
69  return SDL_SYSTEM_CURSOR_SIZENS;
70  else if (t == Type::resize_all)
71  return SDL_SYSTEM_CURSOR_SIZEALL;
72  else if (t == Type::forbidden)
73  return SDL_SYSTEM_CURSOR_NO;
74  // else if (t == Type::hand)
75  return SDL_SYSTEM_CURSOR_HAND;
76  }
77 
78  constexpr Type fromSDLEnum(const SDL_SystemCursor t) noexcept {
79  if (t == SDL_SYSTEM_CURSOR_ARROW)
80  return Type::arrow;
81  else if (t == SDL_SYSTEM_CURSOR_IBEAM)
82  return Type::iBeam;
83  else if (t == SDL_SYSTEM_CURSOR_WAIT)
84  return Type::wait;
85  else if (t == SDL_SYSTEM_CURSOR_CROSSHAIR)
86  return Type::crosshair;
87  else if (t == SDL_SYSTEM_CURSOR_WAITARROW)
88  return Type::waitArrow;
89  else if (t == SDL_SYSTEM_CURSOR_SIZENWSE)
90  return Type::resize_nw_se;
91  else if (t == SDL_SYSTEM_CURSOR_SIZENESW)
92  return Type::resize_ne_sw;
93  else if (t == SDL_SYSTEM_CURSOR_SIZEWE)
94  return Type::resize_we;
95  else if (t == SDL_SYSTEM_CURSOR_SIZENS)
96  return Type::resize_ns;
97  else if (t == SDL_SYSTEM_CURSOR_SIZEALL)
98  return Type::resize_all;
99  else if (t == SDL_SYSTEM_CURSOR_NO)
100  return Type::forbidden;
101  // else if (t == SDL_SYSTEM_CURSOR_HAND)
102  return Type::hand;
103  }
104  }
105 
106  Cursor create(const Type t);
107 
108  Cursor arrow();
109  Cursor iBeam();
110  Cursor wait();
111  Cursor crosshair();
112  Cursor waitArrow();
113  Cursor forbidden();
114  Cursor hand();
115 
116  namespace resize {
117  Cursor nw_se();
118  Cursor ne_sw();
119  Cursor we();
120  Cursor ns();
121  Cursor all();
122  }
123  }
124  }
125 
126  enum class Btn {
127  left, right, middle, x1, x2,
128  l = left, r = right, m = middle
129  };
130 
131  namespace btn::unsafe {
132  constexpr uint32_t toSDLEnum(const Btn b) noexcept {
133  if (b == Btn::left)
134  return SDL_BUTTON_LEFT;
135  else if (b == Btn::right)
136  return SDL_BUTTON_RIGHT;
137  else if (b == Btn::middle)
138  return SDL_BUTTON_MIDDLE;
139  else if (b == Btn::x1)
140  return SDL_BUTTON_X1;
141  // else if (b == Btn::x2)
142  return SDL_BUTTON_X2;
143  }
144 
145  constexpr Btn fromSDLEnum(const uint32_t b) noexcept {
146  if (b == SDL_BUTTON_LEFT)
147  return Btn::left;
148  else if (b == SDL_BUTTON_RIGHT)
149  return Btn::right;
150  else if (b == SDL_BUTTON_MIDDLE)
151  return Btn::middle;
152  else if (b == SDL_BUTTON_X1)
153  return Btn::x1;
154  // else if (b == SDL_BUTTON_X2)
155  return Btn::x2;
156  }
157  }
158 
159  struct BtnState {
160  public:
161  explicit constexpr BtnState(const uint32_t raw) noexcept :
162  raw_(raw)
163  {}
164 
165  constexpr bool left() const noexcept {
166  return get(Btn::left);
167  }
168  constexpr bool right() const noexcept {
169  return get(Btn::right);
170  }
171  constexpr bool middle() const noexcept {
172  return get(Btn::middle);
173  }
174  constexpr bool x1() const noexcept {
175  return get(Btn::x1);
176  }
177  constexpr bool x2() const noexcept {
178  return get(Btn::x2);
179  }
180 
181  constexpr bool l() const noexcept {return left();}
182  constexpr bool r() const noexcept {return right();}
183  constexpr bool m() const noexcept {return middle();}
184 
185  constexpr bool get(const Btn b) const noexcept {
186  return raw_ & SDL_BUTTON(btn::unsafe::toSDLEnum(b));
187  }
188 
189  private:
190  uint32_t raw_;
191  };
192 
193  namespace detail {
194  class BaseState {
195  public:
196  const geom::Pos& pos() const noexcept;
197  const BtnState& btnState() const noexcept;
198 
199  protected:
200  explicit BaseState(const uint32_t b) noexcept;
201 
202  geom::Pos p_;
203  BtnState btnState_;
204  };
205  }
206  class State : public detail::BaseState {
207  public:
208  // fixme: SDL_PumpEvents required before calls
209  State() noexcept;
210  };
212  public:
213  // fixme: SDL_PumpEvents required before calls
214  GlobalState() noexcept;
215  };
216 
217  void capture();
218  void release();
219 
220  void move(const geom::Pos p);
221 }
Geom.hpp
rolmodl::mouse::Cursor
Definition: Mouse.hpp:8
rolmodl::mouse::detail::BaseState
Definition: Mouse.hpp:194
rolmodl::mouse::BtnState
Definition: Mouse.hpp:159
std::left
T left(T... args)
rolmodl::geom::Pos
int point data type. The value is in pixels. Semantically different from rolmodl::geom::Size.
Definition: Geom.hpp:18
rolmodl::mouse::State
Definition: Mouse.hpp:206
rolmodl::mouse::GlobalState
Definition: Mouse.hpp:211