Rose
ScreenMetrics.h
Go to the documentation of this file.
1 
8 #pragma once
9 
10 #include <array>
11 #include <iostream>
12 #include <iomanip>
13 #include <tuple>
14 #include <SDL.h>
15 #include "Constants.h"
16 #include "Utilities.h"
17 
18 namespace rose {
19 
24  class Size : public std::array<int, 2> {
25  public:
26 
27  static const Size Zero;
28 
30  constexpr explicit Size(std::array<int, 2> value) noexcept: std::array<int, 2>(value) {}
31 
33  constexpr explicit Size(int value = 0) noexcept: Size(std::array<int, 2>({value, value})) {}
34 
36  constexpr Size(int width, int height) noexcept: Size(std::array<int, 2>({width, height})) {}
37 
39  constexpr Size(const Size &) = default;
40 
42  constexpr Size(Size &&) = default;
43 
45  constexpr Size& operator=(const Size &) = default;
46 
48  constexpr Size& operator=(Size &&) = default;
49 
50  constexpr explicit Size(const std::tuple<int,int> &t) noexcept
51  : Size(std::get<0>(t), std::get<1>(t)) {}
52 
54  constexpr Size& operator=(const std::tuple<int,int> t) noexcept {
55  width() = std::get<0>(t);
56  height() = std::get<1>(t);
57  return *this;
58  }
59 
61  constexpr int &width() { return operator[](0); }
62 
64  [[nodiscard]] constexpr int width() const noexcept { return operator[](0); }
65 
67  constexpr int &height() { return operator[](1); }
68 
70  [[nodiscard]] constexpr int height() const noexcept { return operator[](1); }
71 
76  int &primary(Orientation orientation) {
77  switch (orientation) {
78  case Orientation::Unset:
79  case Orientation::Both:
80  case Orientation::Horizontal:
81  break;
82  case Orientation::Vertical:
83  return height();
84  }
85  return width();
86  }
87 
92  [[nodiscard]] constexpr int primary(Orientation orientation) const noexcept {
93  switch (orientation) {
94  case Orientation::Unset:
95  case Orientation::Both:
96  case Orientation::Horizontal:
97  return width();
98  case Orientation::Vertical:
99  return height();
100  }
101  }
102 
107  int &secondary(Orientation orientation) {
108  switch (orientation) {
109  case Orientation::Unset:
110  case Orientation::Both:
111  case Orientation::Horizontal:
112  return height();
113  case Orientation::Vertical:
114  return width();
115  }
116  return height();
117  }
118 
123  [[nodiscard]] constexpr int secondary(Orientation orientation) const noexcept {
124  switch (orientation) {
125  case Orientation::Unset:
126  case Orientation::Both:
127  case Orientation::Horizontal:
128  return height();
129  case Orientation::Vertical:
130  return width();
131  }
132  return height();
133  }
134 
136  constexpr Size operator+(const Size &size) const noexcept {
137  return Size{width() + size.width(), height() + size.height()};
138  }
139 
141  constexpr Size operator-(const Size &size) const noexcept {
142  return Size{width() - size.width(), height() - size.height()};
143  }
144  };
145 
150  class Position : public std::array<int, 2> {
151  public:
152 
153  static const Position Zero;
154 
156  constexpr explicit Position(std::array<int, 2> value) noexcept: std::array<int, 2>(value) {}
157 
159  constexpr explicit Position(int value = 0) noexcept: Position(std::array<int, 2>({value, value})) {}
160 
162  constexpr Position(int x, int y) noexcept: Position(std::array<int, 2>({x, y})) {}
163 
165  constexpr Position(const Position &) = default;
166 
168  constexpr Position(Position &&) = default;
169 
171  constexpr Position& operator=(const Position &) = default;
172 
174  constexpr Position& operator=(Position &&) = default;
175 
177  constexpr int &x() { return operator[](0); }
178 
180  [[nodiscard]] constexpr int x() const noexcept { return operator[](0); }
181 
183  constexpr int &y() { return operator[](1); }
184 
186  [[nodiscard]] constexpr int y() const noexcept { return operator[](1); }
187 
192  int &primary(Orientation orientation) {
193  switch (orientation) {
194  case Orientation::Unset:
195  case Orientation::Both:
196  case Orientation::Horizontal:
197  return x();
198  case Orientation::Vertical:
199  return y();
200  }
201  return x();
202  }
203 
208  [[nodiscard]] constexpr int primary(Orientation orientation) const noexcept {
209  switch (orientation) {
210  case Orientation::Unset:
211  case Orientation::Both:
212  case Orientation::Horizontal:
213  return x();
214  case Orientation::Vertical:
215  return y();
216  }
217  }
218 
223  int &secondary(Orientation orientation) {
224  switch (orientation) {
225  case Orientation::Unset:
226  case Orientation::Both:
227  case Orientation::Horizontal:
228  return y();
229  case Orientation::Vertical:
230  return x();
231  }
232  return y();
233  }
234 
239  [[nodiscard]] constexpr int secondary(Orientation orientation) const noexcept {
240  switch (orientation) {
241  case Orientation::Unset:
242  case Orientation::Both:
243  case Orientation::Horizontal:
244  return y();
245  case Orientation::Vertical:
246  return x();
247  }
248  return y();
249  }
250 
252  constexpr Position operator+(const Position &position) const noexcept {
253  return Position{x() + position.x(), y() + position.y()};
254  }
255 
257  constexpr Position operator-(const Position &position) const noexcept {
258  return Position{x() - position.x(), y() - position.y()};
259  }
260 
267  [[nodiscard]] constexpr int abs() const noexcept {
268  return x() * x() + y() * y();
269  }
270  };
271 
276  class Rectangle : public std::array<int, 4> {
277  public:
278  static const Rectangle Zero;
279 
281  constexpr explicit Rectangle(std::array<int, 4> value) noexcept: std::array<int, 4>(value) {}
282 
284  constexpr explicit Rectangle(int value = 0) noexcept: Rectangle(
285  std::array<int, 4>({value, value, value, value})) {}
286 
288  constexpr Rectangle(int x, int y, int width, int height) noexcept: Rectangle(
289  std::array<int, 4>({x, y, width, height})) {}
290 
292  constexpr Rectangle(const Rectangle &) = default;
293 
295  constexpr Rectangle(Rectangle &&) = default;
296 
298  constexpr Rectangle &operator=(const Rectangle &) = default;
299 
301  constexpr Rectangle &operator=(Rectangle &&) = default;
302 
304  constexpr Rectangle(const Position &pos, const Size &size) : Rectangle(pos.x(), pos.y(), size.width(),
305  size.height()) {}
306 
308  constexpr Rectangle(const std::optional<Position> &pos, const std::optional<Size> &size) : Rectangle() {
309  if (pos) {
310  x() = pos->x();
311  y() = pos->y();
312  }
313  if (size) {
314  width() = size->width();
315  height() = size->height();
316  }
317  }
318 
320  constexpr int &x() { return operator[](0); }
321 
323  [[nodiscard]] constexpr int x() const noexcept { return operator[](0); }
324 
326  constexpr int &y() { return operator[](1); }
327 
329  [[nodiscard]] constexpr int y() const noexcept { return operator[](1); }
330 
332  constexpr int &width() { return operator[](2); }
333 
335  [[nodiscard]] constexpr int width() const noexcept { return operator[](2); }
336 
338  constexpr int &height() { return operator[](3); }
339 
341  [[nodiscard]] constexpr int height() const noexcept { return operator[](3); }
342 
343  constexpr int &positionPrimary(Orientation orientation) {
344  if (orientation == Orientation::Horizontal)
345  return operator[](0);
346  else
347  return operator[](1);
348  }
349 
350  constexpr int &positionSecondary(Orientation orientation) {
351  if (orientation == Orientation::Horizontal)
352  return operator[](1);
353  else
354  return operator[](0);
355  }
356 
357  constexpr int &sizePrimary(Orientation orientation) {
358  if (orientation == Orientation::Horizontal)
359  return operator[](2);
360  else
361  return operator[](3);
362  }
363 
364  constexpr int &sizeSecondary(Orientation orientation) {
365  if (orientation == Orientation::Horizontal)
366  return operator[](3);
367  else
368  return operator[](2);
369  }
370 
372  [[nodiscard]] constexpr Size getSize() const noexcept {
373  return Size{width(), height()};
374  }
375 
377  [[nodiscard]] constexpr Position getPosition() const noexcept {
378  return Position{x(), y()};
379  }
380 
381  [[nodiscard]] constexpr SDL_Rect toSdlRect() const noexcept {
382  SDL_Rect rect{};
383  rect.x = x();
384  rect.y = y();
385  rect.w = width();
386  rect.h = height();
387  return rect;
388  }
389 
391  constexpr Rectangle &operator=(const Size &size) {
392  width() = size.width();
393  height() = size.height();
394  return *this;
395  }
396 
398  constexpr Rectangle &operator=(const Position &position) {
399  x() = position.x();
400  y() = position.y();
401  return *this;
402  }
403 
405  constexpr Rectangle &operator+=(const Position &deltaPos) {
406  x() += deltaPos.x();
407  y() += deltaPos.y();
408  return *this;
409  }
410 
412  constexpr Rectangle operator+(const Position &deltaPos) {
413  Rectangle r{*this};
414  r.x() += deltaPos.x();
415  r.y() += deltaPos.y();
416  return r;
417  }
418 
420  [[nodiscard]] constexpr Rectangle moveOrigin(const std::optional<Position> &deltaPos) const {
421  Rectangle r{*this};
422  if (deltaPos) {
423  r += deltaPos.value();
424  r.width() -= deltaPos->x();
425  r.height() -= deltaPos->y();
426  }
427  return r;
428  }
429 
431  [[nodiscard]] constexpr bool contains(Position pos) const noexcept {
432  return pos.x() >= x() && pos.x() < x() + width() && pos.y() >= y() && pos.y() < y() + height();
433  }
434 
440  [[nodiscard]] constexpr bool noOverlap(const Rectangle& o) const noexcept {
441  return x() > o.x() + o.width() ||
442  o.x() > x() + width() ||
443  y() > o.y() + o.height() ||
444  o.y() > y() + height();
445  }
446 
452  [[nodiscard]] constexpr bool overlap(const Rectangle& o) const noexcept {
453  return !noOverlap(o);
454  }
455 
456  [[nodiscard]] Rectangle intersection(const Rectangle &o) const {
457  // gives bottom-left point
458  // of intersection rectangle
459 
460  auto x5 = std::max(x(), o.x());
461  auto y5 = std::max(y(), o.y());
462 
463  // gives top-right point
464  // of intersection rectangle
465  auto x6 = std::min(x()+width(), o.x()+o.width());
466  auto y6 = std::min(y()+height(), o.y()+o.height());
467 
468  // no intersection
469  if (x5 > x6 || y5 > y6) {
470  return Rectangle{0,0,0,0};
471  }
472 
473  return Rectangle{x5, y5, x6 - x5, y6 - y5};
474  }
475  };
476 
481  class Padding : public std::array<int,4> {
482  public:
483  static const Padding Zero;
484 
486  constexpr explicit Padding(std::array<int, 4> value) noexcept: std::array<int, 4>(value) {}
487 
489  constexpr explicit Padding(int value = 0) noexcept: Padding(
490  std::array<int, 4>({value, value, value, value})) {}
491 
493  constexpr Padding(int left, int top, int right, int bottom) noexcept: Padding(
494  std::array<int, 4>({left, top, right, bottom})) {}
495 
496 
497  [[nodiscard]] constexpr int left() const noexcept { return (*this)[0]; }
498  [[nodiscard]] constexpr int right() const noexcept { return (*this)[1]; }
499  [[nodiscard]] constexpr int top() const noexcept { return (*this)[2]; }
500  [[nodiscard]] constexpr int bottom() const noexcept { return (*this)[3]; }
501  [[nodiscard]] constexpr int width() const noexcept { return left() + right(); }
502  [[nodiscard]] constexpr int height() const noexcept { return top() + bottom(); }
503 
505  [[nodiscard]] constexpr Size padSize() const noexcept { return Size{width(),height()}; }
507  [[nodiscard]] constexpr Position padPos() const noexcept { return Position{left(), top()}; }
508 
509  int& left() noexcept { return (*this)[0]; }
510  int& right() noexcept { return (*this)[1]; }
511  int& top() noexcept { return (*this)[2]; }
512  int& bottom() noexcept { return (*this)[3]; }
513 
514  Padding& operator=(const Padding& other) noexcept {
515  std::copy(other.cbegin(), other.cend(), this->begin());
516  return *this;
517  }
518 
519  constexpr Padding& operator=(int value) noexcept {
520  for (auto &v : *this) {
521  v = value;
522  }
523  return *this;
524  }
525  };
526 
531  class Line {
532  protected:
535 
536  public:
540  constexpr Line() noexcept : mPoint0(), mPoint1() {}
541 
547  constexpr Line(const Position &p0, const Position &p1) : mPoint0(p0), mPoint1(p1) {}
548 
550  constexpr Line(const Line &) = default;
551 
553  constexpr Line(Line &&) = default;
554 
556  constexpr Line& operator=(const Line &) = default;
557 
559  constexpr Line &operator=(Line &&) = default;
560 
561  };
562 }
563 
572 template<typename T, size_t N>
573 inline std::ostream &operator<<(std::ostream &strm, const std::array<T, N> &array) {
574  return rose::util::printScreenMetric<T, N>(strm, array);
575 }
576 
584 template<typename T>
585 inline std::ostream &operator<<(std::ostream &strm, const std::optional<T> &opt) {
586  if (opt) {
587  if constexpr (std::is_same_v<T, rose::Rectangle>)
588  rose::util::printScreenMetric<int, 4>(strm, opt.value());
589  if constexpr (std::is_same_v<T, rose::Position> || std::is_same_v<T, rose::Size>)
590  rose::util::printScreenMetric<int,2>(strm, opt.value());
591  } else
592  strm << "(empty)";
593  return strm;
594 }
595 
constexpr Size & operator=(const std::tuple< int, int > t) noexcept
Copy assign tuple.
Definition: ScreenMetrics.h:54
constexpr int secondary(Orientation orientation) const noexcept
Value for secondary axis value.
Definition: ScreenMetrics.h:123
constexpr Rectangle(const std::optional< Position > &pos, const std::optional< Size > &size)
Constructor initialize to the value of std::optional Position and Size.
Definition: ScreenMetrics.h:308
constexpr Size(int width, int height) noexcept
Constructor sets value to descrete values.
Definition: ScreenMetrics.h:36
constexpr Rectangle & operator=(const Position &position)
Assign a Position to a Rectangle.
Definition: ScreenMetrics.h:398
constexpr Rectangle moveOrigin(const std::optional< Position > &deltaPos) const
Move the origin of a Rectangle by an optional deltaPos and reduce the size of the rectangle by a corr...
Definition: ScreenMetrics.h:420
constexpr bool noOverlap(const Rectangle &o) const noexcept
Determine if there is no overlap between two Rectangle objects.
Definition: ScreenMetrics.h:440
static const Position Zero
A zero position.
Definition: ScreenMetrics.h:153
constexpr int height() const noexcept
Value access to height.
Definition: ScreenMetrics.h:341
constexpr int height() const noexcept
Value accessor for height.
Definition: ScreenMetrics.h:70
static const Rectangle Zero
A rectangle with position and size of zero.
Definition: ScreenMetrics.h:278
Not set to a valid value.
constexpr int primary(Orientation orientation) const noexcept
Value for primary axis value.
Definition: ScreenMetrics.h:208
constexpr int primary(Orientation orientation) const noexcept
Value for primary axis value.
Definition: ScreenMetrics.h:92
int & primary(Orientation orientation)
Reference for primary axis value.
Definition: ScreenMetrics.h:76
constexpr Rectangle(const Position &pos, const Size &size)
Constructor initialize to the value of a Position and Size.
Definition: ScreenMetrics.h:304
constexpr int secondary(Orientation orientation) const noexcept
Value for secondary axis value.
Definition: ScreenMetrics.h:239
constexpr Rectangle operator+(const Position &deltaPos)
Add a Position to a Rectangle.
Definition: ScreenMetrics.h:412
constexpr int abs() const noexcept
Compute the square of the scalar distance of a position from the origin.
Definition: ScreenMetrics.h:267
constexpr Position padPos() const noexcept
Get the position of the padding.
Definition: ScreenMetrics.h:507
constexpr int & x()
Reference access to x.
Definition: ScreenMetrics.h:320
constexpr Line() noexcept
Construct line of zero length.
Definition: ScreenMetrics.h:540
constexpr int bottom() const noexcept
Get the bottom padding.
Definition: ScreenMetrics.h:500
constexpr Size padSize() const noexcept
Get the total size of the padding.
Definition: ScreenMetrics.h:505
An abstraction of a line defined by two end points.
Definition: ScreenMetrics.h:531
constexpr Size operator-(const Size &size) const noexcept
Subtraction operator.
Definition: ScreenMetrics.h:141
constexpr int & width()
Reference accessor for width.
Definition: ScreenMetrics.h:61
constexpr bool overlap(const Rectangle &o) const noexcept
Determine if there is overlap between to Rectangle objects by inverting noOverlap().
Definition: ScreenMetrics.h:452
constexpr int left() const noexcept
Get the left padding.
Definition: ScreenMetrics.h:497
A position in integer (x, y) co-ordinates.
Definition: Types.h:95
constexpr int width() const noexcept
Value accessor for width.
Definition: ScreenMetrics.h:64
Both axis – for Elastic.
Constants and Enumerations.
Abstraction of space consumed around an object for space, borders, etc.
Definition: Types.h:454
constexpr int & width()
Reference access to width.
Definition: ScreenMetrics.h:332
constexpr Position operator+(const Position &position) const noexcept
Addition operator.
Definition: ScreenMetrics.h:252
constexpr Padding(int left, int top, int right, int bottom) noexcept
Constructor initialize to descrete x, y, width, and height values.
Definition: ScreenMetrics.h:493
constexpr Line(const Position &p0, const Position &p1)
Construct a line from p0 to p1.
Definition: ScreenMetrics.h:547
constexpr Rectangle(std::array< int, 4 > value) noexcept
Constructor initialize to the value of an array.
Definition: ScreenMetrics.h:281
int & secondary(Orientation orientation)
Reference for secondary axis value.
Definition: ScreenMetrics.h:223
constexpr Position operator-(const Position &position) const noexcept
Subtraction operator.
Definition: ScreenMetrics.h:257
constexpr Rectangle & operator=(const Size &size)
Assign a Size to a Rectangle.
Definition: ScreenMetrics.h:391
int & secondary(Orientation orientation)
Reference for secondary axis value.
Definition: ScreenMetrics.h:107
constexpr Size getSize() const noexcept
Get the Size of a Rectangle.
Definition: ScreenMetrics.h:372
constexpr Position getPosition() const noexcept
Get the Position of a Rectangle.
Definition: ScreenMetrics.h:377
constexpr int x() const noexcept
Value access to x.
Definition: ScreenMetrics.h:180
constexpr Rectangle(int value=0) noexcept
Default constructor initializes x and y to 0 or to a specified value.
Definition: ScreenMetrics.h:284
constexpr bool contains(Position pos) const noexcept
Determine if a Rectangle contains a Position.
Definition: ScreenMetrics.h:431
constexpr int top() const noexcept
Get the top padding.
Definition: ScreenMetrics.h:499
Position mPoint1
The other endpoint of the line.
Definition: ScreenMetrics.h:534
constexpr int & y()
Reference access to y.
Definition: ScreenMetrics.h:326
Orientation
Possible values for Widget orientation.
Definition: Types.h:41
int & bottom() noexcept
Access the bottom padding.
Definition: ScreenMetrics.h:512
constexpr int height() const noexcept
Get the height of the padding.
Definition: ScreenMetrics.h:502
constexpr int y() const noexcept
Value access to y.
Definition: ScreenMetrics.h:329
constexpr int width() const noexcept
Value access to width.
Definition: ScreenMetrics.h:335
constexpr int right() const noexcept
Get the right padding.
Definition: ScreenMetrics.h:498
constexpr Rectangle(int x, int y, int width, int height) noexcept
Constructor initialize to descrete x, y, width, and height values.
Definition: ScreenMetrics.h:288
A composite of a Position and a Size.
Definition: Types.h:307
static const Size Zero
A zero size.
Definition: ScreenMetrics.h:27
int & primary(Orientation orientation)
Reference for primary axis value.
Definition: ScreenMetrics.h:192
int & left() noexcept
Access the left padding.
Definition: ScreenMetrics.h:509
constexpr Rectangle & operator+=(const Position &deltaPos)
Move a Rectangle by a delta Position.
Definition: ScreenMetrics.h:405
int & top() noexcept
Access the top padding.
Definition: ScreenMetrics.h:511
static const Padding Zero
A rectangle with position and size of zero.
Definition: ScreenMetrics.h:483
constexpr Position(int x, int y) noexcept
Constructor initialize to descrete x and y values.
Definition: ScreenMetrics.h:162
A size in integer dimensions.
Definition: Types.h:230
constexpr int width() const noexcept
Get the width of the padding.
Definition: ScreenMetrics.h:501
Position mPoint0
One endpoint of the line.
Definition: ScreenMetrics.h:533
constexpr Size operator+(const Size &size) const noexcept
Addition operator.
Definition: ScreenMetrics.h:136
constexpr Padding(std::array< int, 4 > value) noexcept
Constructor initialize to the value of an array.
Definition: ScreenMetrics.h:486
constexpr Padding(int value=0) noexcept
Default constructor initializes x and y to 0 or to a specified value.
Definition: ScreenMetrics.h:489
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
constexpr int & x()
Reference access to x.
Definition: ScreenMetrics.h:177
int & right() noexcept
Access the right padding.
Definition: ScreenMetrics.h:510
constexpr Position(int value=0) noexcept
Default constructor initializes x and y to 0 or to a specified value.
Definition: ScreenMetrics.h:159
constexpr Size(int value=0) noexcept
Default constructor initializes width and height to 0 or to a specified value.
Definition: ScreenMetrics.h:33
constexpr int y() const noexcept
Value access to y.
Definition: ScreenMetrics.h:186
constexpr int x() const noexcept
Value access to x.
Definition: ScreenMetrics.h:323
constexpr Size(std::array< int, 2 > value) noexcept
Constructor sets value to contents of an array.
Definition: ScreenMetrics.h:30
constexpr Position(std::array< int, 2 > value) noexcept
Constructor initialize to the value of an array.
Definition: ScreenMetrics.h:156
constexpr int & height()
Reference access to height.
Definition: ScreenMetrics.h:338
constexpr int & height()
Reference accessor for height.
Definition: ScreenMetrics.h:67
constexpr int & y()
Reference access to y.
Definition: ScreenMetrics.h:183