52 static constexpr hi::axis axis = Axis;
53 static constexpr bool controls_window = ControlsWindow;
64 hi_axiom(is_gui_thread());
70 _aperture = std::make_unique<scroll_aperture_widget>(
window,
this);
71 _horizontal_scroll_bar = std::make_unique<horizontal_scroll_bar_widget>(
72 window,
this, _aperture->content_width, _aperture->aperture_width, _aperture->offset_x);
73 _vertical_scroll_bar = std::make_unique<vertical_scroll_bar_widget>(
74 window,
this, _aperture->content_height, _aperture->aperture_height, _aperture->offset_y);
86 template<
typename Widget,
typename... Args>
89 return _aperture->make_widget<Widget>(std::forward<Args>(args)...);
93 [[nodiscard]] generator<widget *> children() const noexcept
override
95 co_yield _aperture.get();
96 co_yield _vertical_scroll_bar.get();
97 co_yield _horizontal_scroll_bar.get();
103 hilet aperture_constraints = _aperture->set_constraints();
104 hilet horizontal_constraints = _horizontal_scroll_bar->set_constraints();
105 hilet vertical_constraints = _vertical_scroll_bar->set_constraints();
107 _constraints = aperture_constraints;
111 if constexpr (any(axis & axis::horizontal)) {
112 _constraints.minimum.width() = horizontal_constraints.minimum.width();
113 inplace_max(_constraints.preferred.width(), horizontal_constraints.minimum.width());
114 inplace_max(_constraints.maximum.width(), horizontal_constraints.minimum.width());
116 if constexpr (any(axis & axis::vertical)) {
117 _constraints.minimum.height() = vertical_constraints.minimum.height();
118 inplace_max(_constraints.preferred.height(), vertical_constraints.minimum.height());
119 inplace_max(_constraints.maximum.height(), vertical_constraints.minimum.height());
123 if constexpr (any(axis & axis::horizontal)) {
124 _constraints.minimum.height() += horizontal_constraints.preferred.height();
125 _constraints.preferred.height() += horizontal_constraints.preferred.height();
126 _constraints.maximum.height() += horizontal_constraints.preferred.height();
128 if constexpr (any(axis & axis::vertical)) {
129 _constraints.minimum.width() += vertical_constraints.preferred.width();
130 _constraints.preferred.width() += vertical_constraints.preferred.width();
131 _constraints.maximum.width() += vertical_constraints.preferred.width();
136 void set_layout(widget_layout
const&
layout)
noexcept override
139 hilet horizontal_visible = _aperture->x_axis_scrolls() and any(axis & axis::horizontal);
140 hilet vertical_visible = _aperture->y_axis_scrolls() and any(axis & axis::vertical);
141 hilet both_visible = horizontal_visible and vertical_visible;
146 hilet vertical_scroll_bar_width = _vertical_scroll_bar->constraints().preferred.width();
147 hilet horizontal_scroll_bar_height = _horizontal_scroll_bar->constraints().preferred.height();
150 hilet aperture_size = extent2{
151 vertical_visible ?
layout.width() - vertical_scroll_bar_width :
layout.width(),
152 horizontal_visible ?
layout.height() - horizontal_scroll_bar_height :
layout.height()};
153 hilet aperture_offset = point2{0.0f, horizontal_visible ? horizontal_scroll_bar_height : 0.0f};
154 _aperture_rectangle = aarectangle{aperture_offset, aperture_size};
158 hilet horizontal_scroll_bar_size =
159 extent2{both_visible ? aperture_size.
width() :
layout.width(), horizontal_scroll_bar_height};
160 hilet vertical_scroll_bar_size =
161 extent2{vertical_scroll_bar_width, both_visible ? aperture_size.
height() :
layout.height()};
163 _vertical_scroll_bar_rectangle = aarectangle{
164 point2{
layout.width() - vertical_scroll_bar_size.width(),
layout.height() - vertical_scroll_bar_size.height()},
165 vertical_scroll_bar_size};
167 _horizontal_scroll_bar_rectangle = aarectangle{point2{0.0f, 0.0f}, horizontal_scroll_bar_size};
169 if constexpr (controls_window) {
170 window.set_resize_border_priority(
true, not vertical_visible, not horizontal_visible,
true);
176 _vertical_scroll_bar->set_layout(
layout.
transform(_vertical_scroll_bar_rectangle));
179 _horizontal_scroll_bar->set_layout(
layout.
transform(_horizontal_scroll_bar_rectangle));
183 void draw(draw_context
const& context)
noexcept
186 _vertical_scroll_bar->draw(context);
187 _horizontal_scroll_bar->draw(context);
188 _aperture->draw(context);
192 [[nodiscard]] hitbox hitbox_test(point3 position)
const noexcept override
194 hi_axiom(is_gui_thread());
197 auto r = _aperture->hitbox_test_from_parent(position);
198 r = _horizontal_scroll_bar->hitbox_test_from_parent(position, r);
199 r = _vertical_scroll_bar->hitbox_test_from_parent(position, r);
201 if (
layout().contains(position)) {
202 r =
std::max(r, hitbox{
this, position});
212 aarectangle _aperture_rectangle;
215 aarectangle _horizontal_scroll_bar_rectangle;
218 aarectangle _vertical_scroll_bar_rectangle;