HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
alignment.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2019, 2021-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
9#pragma once
10
11#include "../utility/module.hpp"
12#include <optional>
13
14namespace hi { inline namespace v1 {
15
19enum class vertical_alignment : uint8_t {
22 none = 0,
23
26 top = 1,
27
30 middle = 2,
31
34 bottom = 3
35};
36
57[[nodiscard]] constexpr std::optional<float> make_guideline(
59 float bottom,
60 float top,
61 float padding_bottom,
62 float padding_top,
63 float guideline_width)
64{
66 hi_axiom(guideline_width >= 0.0f);
67
68 hilet guideline_bottom = bottom + padding_bottom;
69 hilet guideline_top = top - padding_top - guideline_width;
70 hilet guideline_middle = (bottom + top - guideline_width) / 2.0f;
71
72 switch (alignment) {
74 return {};
76 if (guideline_bottom <= top) {
77 return guideline_top;
78 } else {
79 return {};
80 }
82 if (guideline_top >= bottom) {
83 return guideline_top;
84 } else {
85 return {};
86 }
88 if (guideline_bottom <= guideline_top) {
89 return std::clamp(guideline_middle, guideline_bottom, guideline_top);
90 } else {
91 return {};
92 }
93 }
95}
96
100enum class horizontal_alignment : uint8_t {
103 none = 0,
104
110 flush = 1,
111
116 left = 2,
117
122 center = 3,
123
128 justified = 4,
129
134 right = 5,
135};
136
158[[nodiscard]] constexpr std::optional<float> make_guideline(
160 float left,
161 float right,
162 float padding_left,
163 float padding_right,
164 float guideline_width = 0.0f)
165{
166 hi_axiom(left <= right);
167 hi_axiom(guideline_width >= 0.0f);
168
169 hilet guideline_left = left + padding_left;
170 hilet guideline_right = right - padding_right - guideline_width;
171 hilet guideline_center = (left + right - guideline_width) / 2.0f;
172
173 switch (alignment) {
175 return {};
177 if (guideline_left <= right) {
178 return guideline_left;
179 } else {
180 return {};
181 }
183 if (guideline_right >= left) {
184 return guideline_right;
185 } else {
186 return {};
187 }
189 if (guideline_left <= guideline_right) {
190 return std::clamp(guideline_center, guideline_left, guideline_right);
191 } else {
192 return {};
193 }
194 }
196}
197
200[[nodiscard]] constexpr horizontal_alignment mirror(horizontal_alignment const& rhs) noexcept
201{
202 if (rhs == horizontal_alignment::left) {
204 } else if (rhs == horizontal_alignment::right) {
206 } else {
207 return rhs;
208 }
209}
210
213[[nodiscard]] constexpr horizontal_alignment mirror(horizontal_alignment const& rhs, bool left_to_right) noexcept
214{
215 if (left_to_right) {
216 return rhs;
217 } else {
218 return mirror(rhs);
219 }
220}
221
222[[nodiscard]] constexpr horizontal_alignment resolve(horizontal_alignment const& rhs, bool left_to_right) noexcept
223{
226 } else {
227 return rhs;
228 }
229}
230
231[[nodiscard]] constexpr horizontal_alignment resolve_mirror(horizontal_alignment const& rhs, bool left_to_right) noexcept
232{
233 return resolve(mirror(rhs, left_to_right), left_to_right);
234}
235
240public:
241 constexpr alignment() noexcept : _value(0) {}
242 constexpr alignment(alignment const&) noexcept = default;
243 constexpr alignment(alignment&&) noexcept = default;
244 constexpr alignment& operator=(alignment const&) noexcept = default;
245 constexpr alignment& operator=(alignment&&) noexcept = default;
246
247 constexpr explicit alignment(uint8_t value) noexcept : _value(value) {}
248
250 _value((std::to_underlying(v) << 4) | std::to_underlying(t))
251 {
252 hi_axiom(std::to_underlying(v) <= 0xf);
253 hi_axiom(std::to_underlying(t) <= 0xf);
254 }
255
257 _value((std::to_underlying(v) << 4) | std::to_underlying(h))
258 {
259 hi_axiom(std::to_underlying(v) <= 0xf);
260 hi_axiom(std::to_underlying(h) <= 0xf);
261 }
262
263 [[nodiscard]] static constexpr alignment top_flush() noexcept
264 {
266 }
267
268 [[nodiscard]] static constexpr alignment top_left() noexcept
269 {
271 }
272
273 [[nodiscard]] static constexpr alignment top_center() noexcept
274 {
276 }
277
278 [[nodiscard]] static constexpr alignment top_justified() noexcept
279 {
281 }
282
283 [[nodiscard]] static constexpr alignment top_right() noexcept
284 {
286 }
287
288 [[nodiscard]] static constexpr alignment middle_flush() noexcept
289 {
291 }
292
293 [[nodiscard]] static constexpr alignment middle_left() noexcept
294 {
296 }
297
298 [[nodiscard]] static constexpr alignment middle_center() noexcept
299 {
301 }
302
303 [[nodiscard]] static constexpr alignment middle_justified() noexcept
304 {
306 }
307
308 [[nodiscard]] static constexpr alignment middle_right() noexcept
309 {
311 }
312
313 [[nodiscard]] static constexpr alignment bottom_left() noexcept
314 {
316 }
317
318 [[nodiscard]] static constexpr alignment bottom_center() noexcept
319 {
321 }
322
323 [[nodiscard]] static constexpr alignment bottom_right() noexcept
324 {
326 }
327
328 [[nodiscard]] constexpr horizontal_alignment horizontal() const noexcept
329 {
330 return static_cast<horizontal_alignment>(_value & 0xf);
331 }
332
333 [[nodiscard]] constexpr vertical_alignment vertical() const noexcept
334 {
335 return static_cast<vertical_alignment>(_value >> 4);
336 }
337
338 [[nodiscard]] constexpr friend bool operator==(alignment const& lhs, alignment const& rhs) noexcept = default;
339
340 [[nodiscard]] constexpr friend bool operator==(alignment const& lhs, horizontal_alignment const& rhs) noexcept
341 {
342 return lhs.horizontal() == rhs;
343 }
344
345 [[nodiscard]] constexpr friend bool operator==(horizontal_alignment const& lhs, alignment const& rhs) noexcept
346 {
347 return lhs == rhs.horizontal();
348 }
349
350 [[nodiscard]] constexpr friend bool operator==(alignment const& lhs, vertical_alignment const& rhs) noexcept
351 {
352 return lhs.vertical() == rhs;
353 }
354
355 [[nodiscard]] constexpr friend bool operator==(vertical_alignment const& lhs, alignment const& rhs) noexcept
356 {
357 return lhs == rhs.vertical();
358 }
359
360 [[nodiscard]] constexpr friend alignment mirror(alignment const& rhs) noexcept
361 {
362 return alignment{mirror(rhs.horizontal()), rhs.vertical()};
363 }
364
365 [[nodiscard]] constexpr friend alignment mirror(alignment const& rhs, bool left_to_right) noexcept
366 {
367 return alignment{mirror(rhs.horizontal(), left_to_right), rhs.vertical()};
368 }
369
370 [[nodiscard]] constexpr friend alignment resolve(alignment const& rhs, bool left_to_right) noexcept
371 {
372 return alignment{resolve(rhs.horizontal(), left_to_right), rhs.vertical()};
373 }
374
375 [[nodiscard]] constexpr friend alignment resolve_mirror(alignment const& rhs, bool left_to_right) noexcept
376 {
377 return alignment{resolve_mirror(rhs.horizontal(), left_to_right), rhs.vertical()};
378 }
379
380private:
386 uint8_t _value;
387};
388
395constexpr alignment operator|(horizontal_alignment lhs, vertical_alignment rhs) noexcept
396{
397 return alignment{lhs, rhs};
398}
399
406constexpr alignment operator|(vertical_alignment lhs, horizontal_alignment rhs) noexcept
407{
408 return alignment{lhs, rhs};
409}
410
411}} // namespace hi::v1
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
vertical_alignment
Vertical alignment.
Definition alignment.hpp:19
constexpr std::optional< float > make_guideline(vertical_alignment alignment, float bottom, float top, float padding_bottom, float padding_top, float guideline_width)
Create a guideline between two points.
Definition alignment.hpp:57
horizontal_alignment
Horizontal alignment.
Definition alignment.hpp:100
@ middle
Align to the vertical-middle.
@ bottom
Align to the bottom.
@ top
Align to the top.
@ right
Align the text to the right side.
@ left
Align the text to the left side.
@ flush
Align the text naturally based on the writing direction of each paragraph.
@ justified
Stretch the text to be flush to both sides.
@ center
Align the text in the center.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
constexpr horizontal_alignment mirror(horizontal_alignment const &rhs) noexcept
Mirror the horizontal alignment.
Definition alignment.hpp:200
Horizontal/Vertical alignment combination.
Definition alignment.hpp:239