HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
widget_layout.hpp
Go to the documentation of this file.
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 "../layout/box_shape.hpp"
14#include "../geometry/transform.hpp"
15#include "../geometry/translate.hpp"
16#include "../unicode/unicode_bidi_class.hpp"
17#include "../text/font_book.hpp"
18#include "../GUI/gui_window_size.hpp"
19#include "../GUI/theme.hpp"
21#include "../chrono.hpp"
22#include "../math.hpp"
23
24namespace hi { inline namespace v1 {
25
42public:
47 static constexpr int redraw_overhang = 2;
48
53
56 translate2i to_parent = {};
57
60 translate2i from_parent = {};
61
64 translate2i to_window = {};
65
68 translate2i from_window = {};
69
73
76 float elevation = 0.0f;
77
78 gui_window_size window_size_state = gui_window_size::normal;
79
91
96 extent2 sub_pixel_size = {1.0f, 1.0f};
97
100 utc_nanoseconds display_time_point = {};
101
102 constexpr widget_layout(widget_layout const&) noexcept = default;
103 constexpr widget_layout(widget_layout&&) noexcept = default;
104 constexpr widget_layout& operator=(widget_layout const&) noexcept = default;
105 constexpr widget_layout& operator=(widget_layout&&) noexcept = default;
106 constexpr widget_layout() noexcept = default;
107 [[nodiscard]] constexpr friend bool operator==(widget_layout const&, widget_layout const&) noexcept = default;
108
109 [[nodiscard]] constexpr bool empty() const noexcept
110 {
111 // Theme must always be set if layout is valid.
112 return display_time_point == utc_nanoseconds{};
113 }
114
115 [[nodiscard]] constexpr explicit operator bool() const noexcept
116 {
117 return not empty();
118 }
119
120 [[nodiscard]] constexpr translate3 to_window3() const noexcept
121 {
122 return translate3{narrow_cast<translate2>(to_window), elevation};
123 }
124
130 [[nodiscard]] constexpr bool contains(point3i mouse_position) const noexcept
131 {
132 return rectangle().contains(mouse_position) and clipping_rectangle.contains(mouse_position);
133 }
134
135 [[nodiscard]] constexpr aarectanglei rectangle() const noexcept
136 {
137 return shape.rectangle;
138 }
139
142 [[nodiscard]] constexpr aarectanglei rectangle_on_window() const noexcept
143 {
144 return to_window * rectangle();
145 }
146
149 [[nodiscard]] constexpr aarectanglei clipping_rectangle_on_window() const noexcept
150 {
152 }
153
159 [[nodiscard]] constexpr aarectanglei clipping_rectangle_on_window(aarectanglei narrow_clipping_rectangle) const noexcept
160 {
161 return to_window * intersect(clipping_rectangle, narrow_clipping_rectangle);
162 }
163
164 [[nodiscard]] constexpr int width() const noexcept
165 {
166 return shape.width();
167 }
168
169 [[nodiscard]] constexpr int height() const noexcept
170 {
171 return shape.height();
172 }
173
174 [[nodiscard]] constexpr extent2i size() const noexcept
175 {
176 return shape.size();
177 }
178
181 constexpr widget_layout(
183 gui_window_size window_size_state,
184 hi::subpixel_orientation subpixel_orientation,
185 utc_nanoseconds display_time_point) noexcept :
186 to_parent(),
187 from_parent(),
188 to_window(),
189 from_window(),
192 window_size_state(window_size_state),
194 sub_pixel_size(hi::sub_pixel_size(subpixel_orientation)),
196 {
197 }
198
206 [[nodiscard]] constexpr widget_layout
207 transform(box_shape const& child_shape, float child_elevation, aarectanglei new_clipping_rectangle) const noexcept
208 {
209 widget_layout r = *this;
210 r.shape.rectangle = aarectanglei{child_shape.size()};
211
212 if (child_shape.baseline) {
213 r.shape.baseline = *child_shape.baseline - child_shape.y();
214
215 } else if (r.shape.baseline) {
216 // Use the baseline of the current layout and translate it.
217 *r.shape.baseline -= child_shape.y();
218 }
219
220 if (child_shape.centerline) {
221 r.shape.centerline = *child_shape.centerline - child_shape.x();
222
223 } else if (r.shape.centerline) {
224 // Use the baseline of the current layout and translate it.
225 *r.shape.centerline -= child_shape.x();
226 }
227
228 r.to_parent = translate2i{child_shape.x(), child_shape.y()};
229 r.from_parent = ~r.to_parent;
230 r.to_window = r.to_parent * this->to_window;
231 r.from_window = r.from_parent * this->from_window;
232 r.clipping_rectangle = r.from_parent * intersect(this->clipping_rectangle, new_clipping_rectangle);
233 r.elevation += child_elevation;
234 return r;
235 }
236
243 [[nodiscard]] constexpr widget_layout transform(box_shape const& child_shape, float child_elevation = 1.0f) const noexcept
244 {
245 return transform(child_shape, child_elevation, child_shape.rectangle + redraw_overhang);
246 }
247
253 [[nodiscard]] constexpr widget_layout override_clip(aarectanglei new_clipping_rectangle) const noexcept
254 {
255 auto r = *this;
256 r.clipping_rectangle = new_clipping_rectangle;
257 return r;
258 }
259};
260
261}} // namespace hi::v1
Miscellaneous math functions.
Defines geo::matrix, matrix2 and matrix3.
geo::extent< int, 2 > extent2i
A 2D extent.
Definition extent.hpp:513
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
constexpr extent< value_type, 2 > size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:184
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:266
Definition box_shape.hpp:15
The layout of a widget.
Definition widget_layout.hpp:41
extent2i window_size
Size of the window.
Definition widget_layout.hpp:72
utc_nanoseconds display_time_point
The layout created for displaying at this time point.
Definition widget_layout.hpp:100
constexpr widget_layout override_clip(aarectanglei new_clipping_rectangle) const noexcept
Override e context with the new clipping rectangle.
Definition widget_layout.hpp:253
translate2i to_parent
This matrix transforms local coordinates to the coordinates of the parent widget.
Definition widget_layout.hpp:56
translate2i from_parent
This matrix transforms parent widget's coordinates to local coordinates.
Definition widget_layout.hpp:60
translate2i from_window
This matrix transforms window coordinates to local coordinates.
Definition widget_layout.hpp:68
constexpr bool contains(point3i mouse_position) const noexcept
Check if the mouse position is inside the widget.
Definition widget_layout.hpp:130
float elevation
The elevation of the widget above the window.
Definition widget_layout.hpp:76
extent2 sub_pixel_size
The size of a sub-pixel.
Definition widget_layout.hpp:96
constexpr aarectanglei rectangle_on_window() const noexcept
Get the rectangle in window coordinate system.
Definition widget_layout.hpp:142
static constexpr int redraw_overhang
The amount of pixels that the redraw request will overhang the widget.
Definition widget_layout.hpp:47
constexpr widget_layout transform(box_shape const &child_shape, float child_elevation, aarectanglei new_clipping_rectangle) const noexcept
Create a new widget_layout for the child widget.
Definition widget_layout.hpp:207
constexpr aarectanglei clipping_rectangle_on_window() const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:149
box_shape shape
Shape of the widget.
Definition widget_layout.hpp:52
constexpr widget_layout(extent2i 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:181
translate2i to_window
This matrix transforms local coordinates to window coordinates.
Definition widget_layout.hpp:64
constexpr aarectanglei clipping_rectangle_on_window(aarectanglei narrow_clipping_rectangle) const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:159
aarectanglei clipping_rectangle
The clipping rectangle.
Definition widget_layout.hpp:90
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:243