HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
box_constraints.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../geometry/module.hpp"
8#include "../utility/module.hpp"
9#include <cstdint>
10#include <limits>
11#include <concepts>
12
13namespace hi { inline namespace v1 {
14
23 extent2 minimum = {};
24 extent2 preferred = {};
25 extent2 maximum = {};
27 hi::margins padding = {};
28
30
31 constexpr box_constraints() noexcept = default;
32 constexpr box_constraints(box_constraints const&) noexcept = default;
33 constexpr box_constraints(box_constraints&&) noexcept = default;
34 constexpr box_constraints& operator=(box_constraints const&) noexcept = default;
35 constexpr box_constraints& operator=(box_constraints&&) noexcept = default;
36 [[nodiscard]] constexpr friend bool operator==(box_constraints const&, box_constraints const&) noexcept = default;
37
38 constexpr box_constraints(
39 extent2 minimum,
40 extent2 preferred,
41 extent2 maximum,
44 hi::margins padding = hi::margins{}) noexcept :
45 minimum(minimum), preferred(preferred), maximum(maximum), margins(margins), padding(padding), alignment(alignment)
46 {
47 hi_axiom(holds_invariant());
48 }
49
50 [[nodiscard]] constexpr box_constraints internalize_margins() const noexcept
51 {
52 auto r = *this;
53 r.padding += r.margins;
54
55 r.minimum.width() += r.margins.left() + r.margins.right();
56 r.preferred.width() += r.margins.left() + r.margins.right();
57 r.maximum.width() += r.margins.left() + r.margins.right();
58
59 r.minimum.height() += r.margins.bottom() + r.margins.top();
60 r.preferred.height() += r.margins.bottom() + r.margins.top();
61 r.maximum.height() += r.margins.bottom() + r.margins.top();
62
63 r.margins = 0;
64 hi_axiom(r.holds_invariant());
65 return r;
66 }
67
68 [[nodiscard]] constexpr box_constraints constrain(extent2 new_minimum, extent2 new_maximum) const noexcept
69 {
70 hi_assert(new_minimum <= new_maximum);
71
72 auto r = *this;
73
74 inplace_max(r.minimum, new_minimum);
75 inplace_min(r.maximum, new_maximum);
76
77 inplace_max(r.preferred, r.minimum);
78 inplace_max(r.maximum, r.preferred);
79 hi_axiom(r.holds_invariant());
80 return r;
81 }
82
83 constexpr box_constraints& operator+=(extent2 const& rhs) noexcept
84 {
85 minimum.width() += rhs.width();
86 preferred.width() += rhs.width();
87 maximum.width() += rhs.width();
88 minimum.height() += rhs.height();
89 preferred.height() += rhs.height();
90 maximum.height() += rhs.height();
91
92 hi_axiom(holds_invariant());
93 return *this;
94 }
95
96 [[nodiscard]] constexpr box_constraints operator+(extent2 const& rhs) const noexcept
97 {
98 auto r = *this;
99 r += rhs;
100 return r;
101 }
102
103 [[nodiscard]] constexpr bool holds_invariant() const noexcept
104 {
106 return false;
107 }
108 if (minimum > preferred or preferred > maximum) {
109 return false;
110 }
111 return true;
112 }
113
114 [[nodiscard]] friend constexpr box_constraints max(box_constraints const& lhs, extent2 const& rhs) noexcept
115 {
116 auto r = lhs;
117 inplace_max(r.minimum, rhs);
118 inplace_max(r.preferred, rhs);
119 inplace_max(r.maximum, rhs);
120
121 hi_axiom(r.holds_invariant());
122 return r;
123 }
124
132 [[nodiscard]] friend constexpr box_constraints max(box_constraints const& lhs, box_constraints const& rhs) noexcept
133 {
134 auto r = lhs;
135 inplace_max(r.minimum, rhs.minimum);
136 inplace_max(r.preferred, rhs.preferred);
137 inplace_max(r.maximum, rhs.maximum);
138 inplace_max(r.margins, rhs.margins);
139 inplace_max(r.padding, rhs.padding);
140
141 hi_axiom(r.holds_invariant());
142 return r;
143 }
144
145 template<std::convertible_to<box_constraints>... Args>
146 [[nodiscard]] friend constexpr box_constraints
147 max(box_constraints const& first, box_constraints const& second, box_constraints const& third, Args const&...args) noexcept
148 {
149 return max(first, max(second, third, args...));
150 }
151};
152
153}} // namespace hi::v1
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:199
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
@ flush
Align the text naturally based on the writing direction of each paragraph.
@ justified
Stretch the text to be flush to both sides.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Horizontal/Vertical alignment combination.
Definition alignment.hpp:239
A high-level geometric extent.
Definition extent2.hpp:26
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent2.hpp:101
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent2.hpp:112
The left, bottom, right and top margins.
Definition margins.hpp:20
2D constraints.
Definition box_constraints.hpp:22
friend constexpr box_constraints max(box_constraints const &lhs, box_constraints const &rhs) noexcept
Makes a constraint that encompasses both given constraints.
Definition box_constraints.hpp:132