39 static_assert(Axis == axis::horizontal or Axis == axis::vertical);
43 static constexpr hi::axis axis = Axis;
47 if (
auto delegate = _delegate.lock()) {
48 delegate->deinit(*
this);
60 super(window, parent), _delegate(
std::move(delegate))
62 hi_axiom(is_gui_thread());
67 if (
auto d = _delegate.lock()) {
84 template<
typename Widget,
typename... Args>
87 auto tmp = std::make_unique<Widget>(window,
this, std::forward<Args>(args)...);
90 request_reconstrain();
98 hi_axiom(is_gui_thread());
100 request_reconstrain();
106 for (
hilet &child : _children) {
107 co_yield child.get();
111 widget_constraints
const &set_constraints() noexcept
override
117 auto minimum_thickness = 0.0f;
118 auto preferred_thickness = 0.0f;
119 auto maximum_thickness = 0.0f;
120 float margin_before_thickness = 0.0f;
121 float margin_after_thickness = 0.0f;
123 _grid_layout.clear();
124 for (
hilet &child : _children) {
125 update_constraints_for_child(*child, index++, minimum_thickness, preferred_thickness, maximum_thickness, margin_before_thickness, margin_after_thickness);
127 _grid_layout.commit_constraints();
129 hi_axiom(index == ssize(_children));
131 if constexpr (axis == axis::row) {
132 return _constraints = {
133 {_grid_layout.minimum(), minimum_thickness},
134 {_grid_layout.preferred(), preferred_thickness},
135 {_grid_layout.maximum(), maximum_thickness},
136 {_grid_layout.margin_before(), margin_before_thickness, _grid_layout.margin_after(), margin_after_thickness}};
138 return _constraints = {
139 {minimum_thickness, _grid_layout.minimum()},
140 {preferred_thickness, _grid_layout.preferred()},
141 {maximum_thickness, _grid_layout.maximum()},
142 {margin_before_thickness, _grid_layout.margin_before(), margin_after_thickness, _grid_layout.margin_after()}};
146 void set_layout(widget_layout
const &layout)
noexcept override
148 if (compare_store(_layout, layout)) {
149 _grid_layout.layout(axis == axis::row ? layout.width() : layout.height());
153 for (
hilet &child : _children) {
154 update_layout_for_child(*child, index++, layout);
157 hi_axiom(index == ssize(_children));
160 void draw(draw_context
const &context)
noexcept override
163 for (
hilet &child : _children) {
164 child->draw(context);
169 hitbox hitbox_test(point3 position)
const noexcept override
171 hi_axiom(is_gui_thread());
173 if (*visible and *enabled) {
175 for (
hilet &child : _children) {
176 r = child->hitbox_test_from_parent(position, r);
187 grid_layout _grid_layout;
189 void update_constraints_for_child(
192 float &minimum_thickness,
193 float &preferred_thickness,
194 float &maximum_thickness,
195 float &margin_before_thickness,
196 float &margin_after_thickness)
noexcept
198 hi_axiom(is_gui_thread());
200 hilet &child_constraints = child.set_constraints();
201 if (axis == axis::row) {
202 _grid_layout.add_constraint(
204 child_constraints.minimum.width(),
205 child_constraints.preferred.width(),
206 child_constraints.maximum.width(),
207 child_constraints.margins.left(),
208 child_constraints.margins.right());
210 inplace_max(minimum_thickness, child_constraints.minimum.height());
211 inplace_max(preferred_thickness, child_constraints.preferred.height());
212 inplace_max(maximum_thickness, child_constraints.maximum.height());
213 inplace_max(margin_before_thickness, child_constraints.margins.top());
214 inplace_max(margin_after_thickness, child_constraints.margins.bottom());
217 _grid_layout.add_constraint(
219 child_constraints.minimum.height(),
220 child_constraints.preferred.height(),
221 child_constraints.maximum.height(),
222 child_constraints.margins.top(),
223 child_constraints.margins.bottom());
225 inplace_max(minimum_thickness, child_constraints.minimum.width());
226 inplace_max(preferred_thickness, child_constraints.preferred.width());
227 inplace_max(maximum_thickness, child_constraints.maximum.width());
228 inplace_max(margin_before_thickness, child_constraints.margins.left());
229 inplace_max(margin_after_thickness, child_constraints.margins.right());
233 void update_layout_for_child(widget &child, ssize_t index, widget_layout
const &context)
const noexcept
235 hi_axiom(is_gui_thread());
237 hilet[child_position, child_length] = _grid_layout.get_position_and_size(index);
239 hilet child_rectangle = axis == axis::row ?
240 aarectangle{child_position, 0.0f, child_length, layout().height()} :
241 aarectangle{0.0f, layout().height() - child_position - child_length, layout().width(), child_length};
243 child.set_layout(context.transform(child_rectangle, 0.0f));