Rose
Types.h
1 
8 #pragma once
9 
10 #include <iostream>
11 #include <tuple>
12 #include <utility>
13 #include "Color.h"
14 #include "Math.h"
15 
16 namespace rose {
17 
18  template<typename I = int>
19  constexpr I WINDOWPOS_UNDEFINED_DISPLAY(uint display=0) {
20  return static_cast<I>(SDL_WINDOWPOS_UNDEFINED_MASK | display);
21  }
22 
23  template<typename I = int>
24  constexpr I WINDOWPOS_CENTERED_DISPLAY(uint display=0) {
25  return static_cast<I>(SDL_WINDOWPOS_CENTERED_MASK | display);
26  }
27 
28  static constexpr int WINDOWPOS_UNDEFINED = WINDOWPOS_UNDEFINED_DISPLAY();
29  static constexpr int WINDOWPOS_CENTERED = WINDOWPOS_CENTERED_DISPLAY();
30 
34  enum RendererFlags : uint32_t {
35  RENDERER_SOFTWARE = static_cast<uint32_t>(SDL_RENDERER_SOFTWARE),
36  RENDERER_ACCELERATED = static_cast<uint32_t>(SDL_RENDERER_ACCELERATED),
37  RENDERER_PRESENTVSYNC = static_cast<uint32_t>(SDL_RENDERER_PRESENTVSYNC),
38  RENDERER_TARGETTEXTURE = static_cast<uint32_t>(SDL_RENDERER_TARGETTEXTURE)
39  };
40 
41  enum class Orientation {
42  Horizontal,
43  Vertical,
44  };
45 
50  enum class BorderStyle {
51  Unset,
52  None,
53  BevelOut,
54  BevelIn,
55  NotchOut,
56  NotchIn,
57  };
58 
63  enum class CornerStyle {
64  Unset,
65  Square,
66  Round,
67  };
68 
69  namespace set {
70  static constexpr std::string_view SetAppSize{"SetAppSize"};
71  static constexpr std::string_view SetAppPosition{"SetAppPosition"};
72  static constexpr std::string_view SetAppState{"SetAppState"};
73  }
74 
75  struct FrameSettings {
76  std::pair<color::RGBA,color::RGBA> backgroundPair;
77  std::pair<BorderStyle,BorderStyle> borderStylePair;
78 
79  color::RGBA background(bool invert) {
80  return invert ? backgroundPair.second : backgroundPair.first;
81  }
82 
83  BorderStyle borderStyle(bool invert) {
84  return invert ? borderStylePair.second : borderStylePair.first;
85  }
86  };
87 
94  template <typename T>
95  struct Position {
96  T x{0}, y{0};
97 
98  constexpr Position() noexcept = default;
99 
100  template<typename O>
101  constexpr Position(O X, O Y) noexcept {
102  if constexpr (std::is_same_v<T,O>) {
103  x = X;
104  y = Y;
105  } else if constexpr (std::is_integral_v<T> && std::is_floating_point_v<O>) {
106  x = util::roundToInt(X);
107  y = util::roundToInt(Y);
108  } else {
109  x = static_cast<T>(X);
110  y = static_cast<T>(Y);
111  }
112  }
113 
114  constexpr Position(const Position &p) = default;
115  constexpr Position(Position &&p) noexcept = default;
116  constexpr Position& operator=(const Position &p) = default;
117  constexpr Position& operator=(Position &&p) = default;
118 
119  constexpr explicit Position(T p) noexcept : x(p), y(p) {}
120 
122  template <typename O>
123  constexpr Position operator+(const Position<O> &p) const noexcept {
124  if constexpr (std::is_same_v<T,O>) {
125  return Position{x + p.x, y + p.y};
126  } else if constexpr (std::is_integral_v<T> && std::is_floating_point_v<O>) {
127  return Position{x + util::roundToInt(p.x), y + util::roundToInt(p.y)};
128  } else {
129  return Position{x + static_cast<T>(p.x), y + static_cast<T>(p.y)};
130  }
131  }
132 
134  template <typename O>
135  constexpr Position operator-(const Position<O> &p) const noexcept {
136  if constexpr (std::is_same_v<T,O>) {
137  return Position{x - p.x, y - p.y};
138  } else if constexpr (std::is_integral_v<T> && std::is_floating_point_v<O>) {
139  return Position{x - util::roundToInt(p.x), y - util::roundToInt(p.y)};
140  } else {
141  return Position{x - static_cast<T>(p.x), y - static_cast<T>(p.y)};
142  }
143  }
144 
150  template<typename O>
151  Position<O> as() const {
152  if constexpr (std::is_same_v<T,O>) {
153  return Position<O>{x, y};
154  } else if constexpr (std::is_integral_v<O> && std::is_floating_point_v<T>) {
156  } else {
157  return Position<O>{static_cast<O>(x), static_cast<O>(y)};
158  }
159  }
160 
162  bool operator!=(const Position &other) const noexcept {
163  return x != other.x || y != other.y;
164  }
165 
167  bool operator==(const Position &other) const noexcept {
168  return x == other.x && y == other.y;
169  }
170 
172  bool operator<=(const Position &other) const noexcept {
173  return x <= other.x && y <= other.y;
174  }
175 
177  T& primary(Orientation o) noexcept {
178  return o == Orientation::Horizontal ? x : y;
179  }
180 
182  T& secondary(Orientation o) noexcept {
183  return o == Orientation::Horizontal ? y : x;
184  }
185 
187  [[nodiscard]] constexpr T primary(Orientation o) const noexcept {
188  return o == Orientation::Horizontal ? x : y;
189  }
190 
192  [[nodiscard]] constexpr T secondary(Orientation o) const noexcept {
193  return o == Orientation::Horizontal ? y : x;
194  }
195 
201  [[nodiscard]] constexpr T rSqr(const Position &other) const noexcept {
202  auto dX = other.x - x;
203  auto dY = other.y - y;
204  return dX*dX + dY*dY;
205  }
206 
208  void swap() noexcept {
209  std::swap(x,y);
210  }
211 
213  [[nodiscard]] constexpr Position<T> mirrorX() const noexcept {
214  return Position<T>{-x, y};
215  }
216 
218  [[nodiscard]] constexpr Position<T> mirrorY() const noexcept {
219  return Position<T>{x, -y};
220  }
221  };
222 
223  static constexpr Position<int> UndefinedPosition;
224 
230  struct Size {
231  int w{0}, h{0};
232 
233  constexpr Size() noexcept = default;
234  constexpr Size(int W, int H) noexcept : w(W), h(H) {}
235  constexpr Size(const Size &p) = default;
236  constexpr Size(Size &&p) = default;
237  constexpr Size& operator=(const Size &p) = default;
238  constexpr Size& operator=(Size &&p) = default;
239 
240  constexpr explicit Size(int size) noexcept : w(size), h(size) {}
241 
242  constexpr explicit Size(const std::tuple<int,int> &size) noexcept : Size(std::get<0>(size), std::get<1>(size)) {}
243 
244  constexpr Size& operator=(std::tuple<int,int> &size) noexcept {
245  w = std::get<0>(size);
246  h = std::get<0>(size);
247  return *this;
248  }
249 
250  explicit operator bool() const { return w > 0 && h > 0; }
251 
252  bool operator!=(const Size &other) const noexcept {
253  return w != other.w || h != other.h;
254  }
255 
256  bool operator==(const Size &other) const noexcept {
257  return w == other.w && h == other.h;
258  }
259 
260  bool operator<(const Size &other) const noexcept {
261  return w < other.w && h < other.h;
262  }
263 
264  bool operator<=(const Size &other) const noexcept {
265  return w <= other.w && h <= other.h;
266  }
267 
268  bool operator>=(const Size &other) const noexcept {
269  return !(operator<(other));
270  }
271 
272  Size operator+(const Size &other) const noexcept {
273  return Size{w + other.w, h + other.h};
274  }
275 
276  Size operator-(const Size &other) const noexcept {
277  return Size{w - other.w, h - other.h};
278  }
279 
280  Size operator/(const int divisor) const {
281  return Size{w / divisor, h / divisor};
282  }
283 
284  int& primary(Orientation o) noexcept {
285  return o == Orientation::Horizontal ? w : h;
286  }
287 
288  int& secondary(Orientation o) noexcept {
289  return o == Orientation::Horizontal ? h : w;
290  }
291 
292  [[nodiscard]] constexpr int primary(Orientation o) const noexcept {
293  return o == Orientation::Horizontal ? w : h;
294  }
295 
296  [[nodiscard]] constexpr int secondary(Orientation o) const noexcept {
297  return o == Orientation::Horizontal ? h : w;
298  }
299 
300  static Size Zero;
301  };
302 
307  struct Rectangle {
308  int x{0}, y{0}, w{0}, h{0};
309 
310  constexpr Rectangle() noexcept = default;
311  constexpr Rectangle(int X, int Y, int W, int H) noexcept : x(X), y(Y), w(W), h(H) {}
312  constexpr Rectangle(const Position<int> &p, const Size &s) noexcept : x(p.x), y(p.y), w(s.w), h(s.h) {}
313  constexpr Rectangle(const Rectangle &p) = default;
314  constexpr Rectangle(Rectangle &&p) = default;
315  constexpr Rectangle& operator=(const Rectangle &p) = default;
316  constexpr Rectangle& operator=(Rectangle &&p) = default;
317 
318  constexpr Rectangle& operator=(const Size &s) {
319  w = s.w;
320  h = s.h;
321  return *this;
322  }
323 
324  constexpr Rectangle& operator=(const Position<int> &p) {
325  x = p.x;
326  y = p.y;
327  return *this;
328  }
329 
331  constexpr Rectangle operator + (const Position<int> &p) const noexcept {
332  return Rectangle{x+p.x, y+p.y, w, h};
333  }
334 
336  constexpr Rectangle operator + (const Size &s) const noexcept {
337  return Rectangle{ x, y, w + s.w, h + s.h};
338  }
339 
341  constexpr Rectangle operator - (const Size &s) const noexcept {
342  return Rectangle{ x, y, w - s.w, h - s.h};
343  }
344 
346  [[nodiscard]] Position<int> position() const noexcept {
347  return Position<int>{x,y};
348  }
349 
351  [[nodiscard]] Size size() const noexcept {
352  return Size{w,h};
353  }
354 
356  [[nodiscard]] std::pair<Position<int>,Position<int>> primeCorners() const noexcept {
357  return std::make_pair(Position<int>{x,y}, Position<int>{x+w,y+h});
358  }
359 
361  [[nodiscard]] std::pair<Position<int>,Position<int>> crossCorners() const noexcept {
362  return std::make_pair(Position<int>{x+w,y}, Position<int>{x,y+h});
363  }
364 
366  [[nodiscard]] std::tuple<Position<int>,Position<int>,Position<int>,Position<int>> corners() const noexcept {
367  auto [tl,br] = primeCorners();
368  auto [bl,tr] = crossCorners();
369  return std::make_tuple(tl,tr,bl,br);
370  }
371 
373  [[nodiscard]] constexpr bool contains(Position<int> pos) const noexcept {
374  return pos.x >= x && pos.x < x + w && pos.y >= y && pos.y < y + h;
375  }
376 
382  [[nodiscard]] constexpr bool noOverlap(const Rectangle& o) const noexcept {
383  return x > o.x + o.w || o.x > x + w || y > o.y + o.h || o.y > y + h;
384  }
385 
391  [[nodiscard]] constexpr bool overlap(const Rectangle& o) const noexcept {
392  return !noOverlap(o);
393  }
394 
395  [[nodiscard]] Rectangle intersection(const Rectangle &o) const {
396  // gives bottom-left point
397  // of intersection rectangle
398 
399  auto x5 = std::max(x, o.x);
400  auto y5 = std::max(y, o.y);
401 
402  // gives top-right point
403  // of intersection rectangle
404  auto x6 = std::min(x+w, o.x+o.w);
405  auto y6 = std::min(y+h, o.y+o.h);
406 
407  // no intersection
408  if (x5 > x6 || y5 > y6) {
409  return Rectangle{0,0,0,0};
410  }
411 
412  return Rectangle{x5, y5, x6 - x5, y6 - y5};
413  }
414 
415  int& sizePri(Orientation o) noexcept {
416  return o == Orientation::Horizontal ? w : h;
417  }
418 
419  int& sizeSec(Orientation o) noexcept {
420  return o == Orientation::Horizontal ? h : w;
421  }
422 
423  int& posPri(Orientation o) noexcept {
424  return o == Orientation::Horizontal ? x : y;
425  }
426 
427  int& posSec(Orientation o) noexcept {
428  return o == Orientation::Horizontal ? y : x;
429  }
430 
431  [[nodiscard]] constexpr int sizePri(Orientation o) const noexcept {
432  return o == Orientation::Horizontal ? w : h;
433  }
434 
435  [[nodiscard]] constexpr int sizeSec(Orientation o) const noexcept {
436  return o == Orientation::Horizontal ? h : w;
437  }
438 
439  [[nodiscard]] constexpr int posPri(Orientation o) const noexcept {
440  return o == Orientation::Horizontal ? x : y;
441  }
442 
443  [[nodiscard]] constexpr int posSec(Orientation o) const noexcept {
444  return o == Orientation::Horizontal ? y : x;
445  }
446 
447  static Rectangle Zero;
448  };
449 
454  struct Padding {
455  int t{0}, b{0}, l{0}, r{0};
456 
457  constexpr Padding() noexcept = default;
458 
459  constexpr explicit Padding(int p) noexcept : t(p), b(p), l(p), r(p) {}
460 
461  constexpr Padding(int h, int v) noexcept : t(v), b(v), l(h), r(h) {}
462 
463  constexpr Padding(int top, int bot, int left, int right) noexcept : t(top), b(bot), l(left), r(right) {}
464 
465  [[nodiscard]] constexpr int vertical() const noexcept { return t + b; }
466 
467  [[nodiscard]] constexpr int horizontal() const noexcept { return l + r; }
468 
469  [[nodiscard]] constexpr Position<int> position() const noexcept { return Position<int>{l, t}; }
470 
471  [[nodiscard]] constexpr Size size() const noexcept { return Size{horizontal(), vertical()}; }
472 
473  int& priLead(Orientation o) noexcept {
474  return o == Orientation::Horizontal ? l : t;
475  }
476 
477  int& priLag(Orientation o) noexcept {
478  return o == Orientation::Horizontal ? r : b;
479  }
480 
481  int& secLead(Orientation o) noexcept {
482  return o == Orientation::Horizontal ? t : l;
483  }
484 
485  int& secLag(Orientation o) noexcept {
486  return o == Orientation::Horizontal ? b : r;
487  }
488 
489  [[nodiscard]] constexpr int priLead(Orientation o) const noexcept {
490  return o == Orientation::Horizontal ? l : t;
491  }
492 
493  [[nodiscard]] constexpr int priLag(Orientation o) const noexcept {
494  return o == Orientation::Horizontal ? r : b;
495  }
496 
497  [[nodiscard]] constexpr int secLead(Orientation o) const noexcept {
498  return o == Orientation::Horizontal ? t : l;
499  }
500 
501  [[nodiscard]] constexpr int secLag(Orientation o) const noexcept {
502  return o == Orientation::Horizontal ? b : r;
503  }
504  };
505 
506  std::array<char, 8> utf8(int c);
507 }
508 
510 inline std::ostream& operator<<(std::ostream& strm, const rose::Size &size) {
511  strm << '(' << size.w << ',' << size.h << ')';
512  return strm;
513 }
514 
516 template<typename T>
517 inline std::ostream& operator<<(std::ostream& strm, const rose::Position<T> &pos) {
518  strm << '(' << pos.x << ',' << pos.y << ')';
519  return strm;
520 }
521 
523 inline std::ostream& operator<<(std::ostream& strm, const rose::Rectangle &rec) {
524  strm << '(' << rec.x << ',' << rec.y << ',' << rec.w << ',' << rec.h << ')';
525  return strm;
526 }
527 
529 inline std::ostream& operator<<(std::ostream& strm, const rose::Padding &pad) {
530  strm << '[' << pad.t << ',' << pad.l << ',' << pad.b << ',' << pad.r << ']';
531  return strm;
532 }
std::pair< Position< int >, Position< int > > primeCorners() const noexcept
Get the Positions of top-left and bottom-right corners defined by the Rectangle.
Definition: Types.h:356
std::pair< Position< int >, Position< int > > crossCorners() const noexcept
Get the Positions of the top-right and bottom-left corners defined by the Rectangle.
Definition: Types.h:361
void swap() noexcept
Swap the x and y components.
Definition: Types.h:208
T & secondary(Orientation o) noexcept
Access the secondary component for the given Orientation.
Definition: Types.h:182
int roundToInt(T value, T multiplier=1.)
Round a floating point value to an integer.
Definition: Math.h:34
The renderer uses hardware acceleration.
Definition: Types.h:36
constexpr bool contains(Position< int > pos) const noexcept
Determine if a Rectangle contains a Position.
Definition: Types.h:373
bool operator!=(const Position &other) const noexcept
Inequality operator.
Definition: Types.h:162
constexpr bool noOverlap(const Rectangle &o) const noexcept
Determine if there is no overlap between two Rectangle objects.
Definition: Types.h:382
constexpr T secondary(Orientation o) const noexcept
Return the secondary component for the given Orientation.
Definition: Types.h:192
Red Green Blue Alpha representation of a color.
Definition: Color.h:64
constexpr T rSqr(const Position &other) const noexcept
Compute the distance squared from this position to another.
Definition: Types.h:201
Not set to a valid value.
std::tuple< Position< int >, Position< int >, Position< int >, Position< int > > corners() const noexcept
Get the Positions of all four corners defined by the Rectangle, top to bottom, left to right...
Definition: Types.h:366
The renderer is a software fallback.
Definition: Types.h:35
T & primary(Orientation o) noexcept
Access the primary component for a given Orientation.
Definition: Types.h:177
A notched border that looks like a trench surrounding the frame.
Definition: Frame.h:28
constexpr T primary(Orientation o) const noexcept
Return the primary component for a given Orientation.
Definition: Types.h:187
CornerStyle
Types of corners supported.
Definition: Types.h:63
bool operator==(const Position &other) const noexcept
Equality operator.
Definition: Types.h:167
Present is synchronized with the refresh rate.
Definition: Types.h:37
bool operator<=(const Position &other) const noexcept
Less than or Equal to operator.
Definition: Types.h:172
constexpr Position operator-(const Position< O > &p) const noexcept
Subtract position other from this.
Definition: Types.h:135
constexpr bool overlap(const Rectangle &o) const noexcept
Determine if there is overlap between to Rectangle objects by inverting noOverlap().
Definition: Types.h:391
A position in integer (x, y) co-ordinates.
Definition: Types.h:95
constexpr Position< T > mirrorY() const noexcept
Mirror Position on Y axis.
Definition: Types.h:218
Abstraction of space consumed around an object for space, borders, etc.
Definition: Types.h:454
Definition: SettingsNames.h:13
Position< int > position() const noexcept
Get a Position from a Rectangle.
Definition: Types.h:346
A beveled border that gives the illusion the frame stands up from the display.
Definition: Frame.h:25
constexpr Position< T > mirrorX() const noexcept
Mirror Position on X axis.
Definition: Types.h:213
Orientation
Possible values for Widget orientation.
Definition: Types.h:41
A notched border that looks like a ridge surrounding the frame.
Definition: Frame.h:27
A composite of a Position and a Size.
Definition: Types.h:307
RendererFlags
Flags used when creating a rendering context.
Definition: Types.h:34
GaugeIndex operator+(const GaugeIndex &gaugeIndex, unsigned long increment)
Add an unsigned integer to a GaugeIndex.
Definition: Gauge.h:60
The renderer supports rendering to texture.
Definition: Types.h:38
A size in integer dimensions.
Definition: Types.h:230
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
BorderStyle
The types of border supported.
Definition: Types.h:50
Position< O > as() const
Return this position after converting to type O.
Definition: Types.h:151
Definition: Types.h:75
constexpr Position operator+(const Position< O > &p) const noexcept
Add two positions together.
Definition: Types.h:123
Size size() const noexcept
Get a Size from a Rectangle.
Definition: Types.h:351
A beveled in border.