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"
12#include "../geometry/module.hpp"
13#include "../unicode/unicode_bidi_class.hpp"
14#include "../font/module.hpp"
15#include "../GUI/gui_window_size.hpp"
16#include "../GUI/theme.hpp"
18#include "../chrono.hpp"
19#include "../utility/module.hpp"
20
21namespace hi { inline namespace v1 {
22
39public:
44 static constexpr int redraw_overhang = 2;
45
50
53 translate2i to_parent = {};
54
57 translate2i from_parent = {};
58
61 translate2i to_window = {};
62
65 translate2i from_window = {};
66
70
73 float elevation = 0.0f;
74
75 gui_window_size window_size_state = gui_window_size::normal;
76
88
93 extent2 sub_pixel_size = {1.0f, 1.0f};
94
97 utc_nanoseconds display_time_point = {};
98
99 constexpr widget_layout(widget_layout const&) noexcept = default;
100 constexpr widget_layout(widget_layout&&) noexcept = default;
101 constexpr widget_layout& operator=(widget_layout const&) noexcept = default;
102 constexpr widget_layout& operator=(widget_layout&&) noexcept = default;
103 constexpr widget_layout() noexcept = default;
104 [[nodiscard]] constexpr friend bool operator==(widget_layout const&, widget_layout const&) noexcept = default;
105
106 [[nodiscard]] constexpr bool empty() const noexcept
107 {
108 // Theme must always be set if layout is valid.
109 return display_time_point == utc_nanoseconds{};
110 }
111
112 [[nodiscard]] constexpr explicit operator bool() const noexcept
113 {
114 return not empty();
115 }
116
117 [[nodiscard]] constexpr translate3 to_window3() const noexcept
118 {
119 return translate3{narrow_cast<translate2>(to_window), elevation};
120 }
121
127 [[nodiscard]] constexpr bool contains(point3i mouse_position) const noexcept
128 {
129 return rectangle().contains(mouse_position) and clipping_rectangle.contains(mouse_position);
130 }
131
132 [[nodiscard]] constexpr aarectanglei rectangle() const noexcept
133 {
134 return shape.rectangle;
135 }
136
139 [[nodiscard]] constexpr aarectanglei rectangle_on_window() const noexcept
140 {
141 return to_window * rectangle();
142 }
143
146 [[nodiscard]] constexpr aarectanglei clipping_rectangle_on_window() const noexcept
147 {
149 }
150
156 [[nodiscard]] constexpr aarectanglei clipping_rectangle_on_window(aarectanglei narrow_clipping_rectangle) const noexcept
157 {
158 return to_window * intersect(clipping_rectangle, narrow_clipping_rectangle);
159 }
160
161 [[nodiscard]] constexpr int width() const noexcept
162 {
163 return shape.width();
164 }
165
166 [[nodiscard]] constexpr int height() const noexcept
167 {
168 return shape.height();
169 }
170
171 [[nodiscard]] constexpr extent2i size() const noexcept
172 {
173 return shape.size();
174 }
175
178 constexpr widget_layout(
180 gui_window_size window_size_state,
181 hi::subpixel_orientation subpixel_orientation,
182 utc_nanoseconds display_time_point) noexcept :
183 to_parent(),
184 from_parent(),
185 to_window(),
186 from_window(),
189 window_size_state(window_size_state),
191 sub_pixel_size(hi::sub_pixel_size(subpixel_orientation)),
193 {
194 }
195
203 [[nodiscard]] constexpr widget_layout
204 transform(box_shape const& child_shape, float child_elevation, aarectanglei new_clipping_rectangle) const noexcept
205 {
206 widget_layout r = *this;
207 r.shape.rectangle = aarectanglei{child_shape.size()};
208
209 if (child_shape.baseline) {
210 r.shape.baseline = *child_shape.baseline - child_shape.y();
211
212 } else if (r.shape.baseline) {
213 // Use the baseline of the current layout and translate it.
214 *r.shape.baseline -= child_shape.y();
215 }
216
217 if (child_shape.centerline) {
218 r.shape.centerline = *child_shape.centerline - child_shape.x();
219
220 } else if (r.shape.centerline) {
221 // Use the baseline of the current layout and translate it.
222 *r.shape.centerline -= child_shape.x();
223 }
224
225 r.to_parent = translate2i{child_shape.x(), child_shape.y()};
226 r.from_parent = ~r.to_parent;
227 r.to_window = r.to_parent * this->to_window;
228 r.from_window = r.from_parent * this->from_window;
229 r.clipping_rectangle = r.from_parent * intersect(this->clipping_rectangle, new_clipping_rectangle);
230 r.elevation += child_elevation;
231 return r;
232 }
233
240 [[nodiscard]] constexpr widget_layout transform(box_shape const& child_shape, float child_elevation = 1.0f) const noexcept
241 {
242 return transform(child_shape, child_elevation, child_shape.rectangle + redraw_overhang);
243 }
244
250 [[nodiscard]] constexpr widget_layout override_clip(aarectanglei new_clipping_rectangle) const noexcept
251 {
252 auto r = *this;
253 r.clipping_rectangle = new_clipping_rectangle;
254 return r;
255 }
256};
257
258}} // namespace hi::v1
geo::extent< int, 2 > extent2i
A 2D extent.
Definition extent.hpp:512
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
constexpr extent< value_type, 2 > size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:182
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:264
Definition box_shape.hpp:15
The layout of a widget.
Definition widget_layout.hpp:38
extent2i window_size
Size of the window.
Definition widget_layout.hpp:69
utc_nanoseconds display_time_point
The layout created for displaying at this time point.
Definition widget_layout.hpp:97
constexpr widget_layout override_clip(aarectanglei new_clipping_rectangle) const noexcept
Override e context with the new clipping rectangle.
Definition widget_layout.hpp:250
translate2i to_parent
This matrix transforms local coordinates to the coordinates of the parent widget.
Definition widget_layout.hpp:53
translate2i from_parent
This matrix transforms parent widget's coordinates to local coordinates.
Definition widget_layout.hpp:57
translate2i from_window
This matrix transforms window coordinates to local coordinates.
Definition widget_layout.hpp:65
constexpr bool contains(point3i mouse_position) const noexcept
Check if the mouse position is inside the widget.
Definition widget_layout.hpp:127
float elevation
The elevation of the widget above the window.
Definition widget_layout.hpp:73
extent2 sub_pixel_size
The size of a sub-pixel.
Definition widget_layout.hpp:93
constexpr aarectanglei rectangle_on_window() const noexcept
Get the rectangle in window coordinate system.
Definition widget_layout.hpp:139
static constexpr int redraw_overhang
The amount of pixels that the redraw request will overhang the widget.
Definition widget_layout.hpp:44
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:204
constexpr aarectanglei clipping_rectangle_on_window() const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:146
box_shape shape
Shape of the widget.
Definition widget_layout.hpp:49
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:178
translate2i to_window
This matrix transforms local coordinates to window coordinates.
Definition widget_layout.hpp:61
constexpr aarectanglei clipping_rectangle_on_window(aarectanglei narrow_clipping_rectangle) const noexcept
Get the clipping rectangle in window coordinate system.
Definition widget_layout.hpp:156
aarectanglei clipping_rectangle
The clipping rectangle.
Definition widget_layout.hpp:87
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:240