HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
widget_layout.hpp
1// Copyright Take Vos 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 "gui_window_size.hpp"
12#include "../layout/box_shape.hpp"
13#include "../geometry/module.hpp"
14#include "../unicode/module.hpp"
15#include "../font/module.hpp"
16#include "../GFX/module.hpp"
17#include "../chrono.hpp"
18#include "../utility/module.hpp"
19
20namespace hi { inline namespace v1 {
21
38public:
43 static constexpr float redraw_overhang = 2;
44
49
52 translate2 to_parent = {};
53
56 translate2 from_parent = {};
57
60 translate2 to_window = {};
61
64 translate2 from_window = {};
65
69
72 float elevation = 0.0f;
73
74 gui_window_size window_size_state = gui_window_size::normal;
75
87
92 extent2 sub_pixel_size = {1.0f, 1.0f};
93
96 utc_nanoseconds display_time_point = {};
97
98 constexpr widget_layout(widget_layout const&) noexcept = default;
99 constexpr widget_layout(widget_layout&&) noexcept = default;
100 constexpr widget_layout& operator=(widget_layout const&) noexcept = default;
101 constexpr widget_layout& operator=(widget_layout&&) noexcept = default;
102 constexpr widget_layout() noexcept = default;
103 [[nodiscard]] constexpr friend bool operator==(widget_layout const&, widget_layout const&) noexcept = default;
104
105 [[nodiscard]] constexpr bool empty() const noexcept
106 {
107 // Theme must always be set if layout is valid.
108 return display_time_point == utc_nanoseconds{};
109 }
110
111 [[nodiscard]] constexpr explicit operator bool() const noexcept
112 {
113 return not empty();
114 }
115
116 [[nodiscard]] constexpr translate3 to_window3() const noexcept
117 {
118 return translate3{narrow_cast<translate2>(to_window), elevation};
119 }
120
126 [[nodiscard]] constexpr bool contains(point3 mouse_position) const noexcept
127 {
128 return rectangle().contains(mouse_position) and clipping_rectangle.contains(mouse_position);
129 }
130
131 [[nodiscard]] constexpr aarectangle rectangle() const noexcept
132 {
133 return shape.rectangle;
134 }
135
138 [[nodiscard]] constexpr aarectangle rectangle_on_window() const noexcept
139 {
140 return to_window * rectangle();
141 }
142
145 [[nodiscard]] constexpr aarectangle clipping_rectangle_on_window() const noexcept
146 {
148 }
149
155 [[nodiscard]] constexpr aarectangle clipping_rectangle_on_window(aarectangle narrow_clipping_rectangle) const noexcept
156 {
157 return to_window * intersect(clipping_rectangle, narrow_clipping_rectangle);
158 }
159
160 [[nodiscard]] constexpr float width() const noexcept
161 {
162 return shape.width();
163 }
164
165 [[nodiscard]] constexpr float height() const noexcept
166 {
167 return shape.height();
168 }
169
170 [[nodiscard]] constexpr extent2 size() const noexcept
171 {
172 return shape.size();
173 }
174
177 constexpr widget_layout(
179 gui_window_size window_size_state,
180 hi::subpixel_orientation subpixel_orientation,
181 utc_nanoseconds display_time_point) noexcept :
182 to_parent(),
183 from_parent(),
184 to_window(),
185 from_window(),
188 window_size_state(window_size_state),
190 sub_pixel_size(hi::sub_pixel_size(subpixel_orientation)),
192 {
193 }
194
202 [[nodiscard]] constexpr widget_layout
203 transform(box_shape const& child_shape, float child_elevation, aarectangle new_clipping_rectangle) const noexcept
204 {
205 widget_layout r = *this;
206 r.shape.rectangle = aarectangle{child_shape.size()};
207
208 if (child_shape.baseline) {
209 r.shape.baseline = *child_shape.baseline - child_shape.y();
210
211 } else if (r.shape.baseline) {
212 // Use the baseline of the current layout and translate it.
213 *r.shape.baseline -= child_shape.y();
214 }
215
216 if (child_shape.centerline) {
217 r.shape.centerline = *child_shape.centerline - child_shape.x();
218
219 } else if (r.shape.centerline) {
220 // Use the baseline of the current layout and translate it.
221 *r.shape.centerline -= child_shape.x();
222 }
223
224 r.to_parent = translate2{child_shape.x(), child_shape.y()};
225 r.from_parent = ~r.to_parent;
226 r.to_window = r.to_parent * this->to_window;
227 r.from_window = r.from_parent * this->from_window;
228 r.clipping_rectangle = r.from_parent * intersect(this->clipping_rectangle, new_clipping_rectangle);
229 r.elevation += child_elevation;
230 return r;
231 }
232
239 [[nodiscard]] constexpr widget_layout transform(box_shape const& child_shape, float child_elevation = 1.0f) const noexcept
240 {
241 return transform(child_shape, child_elevation, child_shape.rectangle + redraw_overhang);
242 }
243
249 [[nodiscard]] constexpr widget_layout override_clip(aarectangle new_clipping_rectangle) const noexcept
250 {
251 auto r = *this;
252 r.clipping_rectangle = new_clipping_rectangle;
253 return r;
254 }
255};
256
257}} // namespace hi::v1
geo::extent< float, 2 > extent2
A 2D extent.
Definition extent.hpp:502
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:27
constexpr bool contains(point< value_type, 2 > const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:265
constexpr extent< value_type, 2 > size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:183
The layout of a widget.
Definition widget_layout.hpp:37
translate2 to_parent
This matrix transforms local coordinates to the coordinates of the parent widget.
Definition widget_layout.hpp:52
utc_nanoseconds display_time_point
The layout created for displaying at this time point.
Definition widget_layout.hpp:96
constexpr aarectangle clipping_rectangle_on_window() const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:145
translate2 from_parent
This matrix transforms parent widget's coordinates to local coordinates.
Definition widget_layout.hpp:56
aarectangle clipping_rectangle
The clipping rectangle.
Definition widget_layout.hpp:86
constexpr bool contains(point3 mouse_position) const noexcept
Check if the mouse position is inside the widget.
Definition widget_layout.hpp:126
float elevation
The elevation of the widget above the window.
Definition widget_layout.hpp:72
constexpr aarectangle clipping_rectangle_on_window(aarectangle narrow_clipping_rectangle) const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:155
translate2 to_window
This matrix transforms local coordinates to window coordinates.
Definition widget_layout.hpp:60
static constexpr float redraw_overhang
The amount of pixels that the redraw request will overhang the widget.
Definition widget_layout.hpp:43
extent2 sub_pixel_size
The size of a sub-pixel.
Definition widget_layout.hpp:92
translate2 from_window
This matrix transforms window coordinates to local coordinates.
Definition widget_layout.hpp:64
constexpr widget_layout override_clip(aarectangle new_clipping_rectangle) const noexcept
Override e context with the new clipping rectangle.
Definition widget_layout.hpp:249
extent2 window_size
Size of the window.
Definition widget_layout.hpp:68
box_shape shape
Shape of the widget.
Definition widget_layout.hpp:48
constexpr aarectangle rectangle_on_window() const noexcept
Get the rectangle in window coordinate system.
Definition widget_layout.hpp:138
constexpr widget_layout transform(box_shape const &child_shape, float child_elevation, aarectangle new_clipping_rectangle) const noexcept
Create a new widget_layout for the child widget.
Definition widget_layout.hpp:203
constexpr widget_layout(extent2 window_size, gui_window_size window_size_state, hi::subpixel_orientation subpixel_orientation, utc_nanoseconds display_time_point) noexcept
Construct a widget_layout from inside the window.
Definition widget_layout.hpp:177
constexpr widget_layout transform(box_shape const &child_shape, float child_elevation=1.0f) const noexcept
Create a new widget_layout for the child widget.
Definition widget_layout.hpp:239
Definition box_shape.hpp:15