39 static_assert(Axis == axis::horizontal or Axis == axis::vertical);
43 static constexpr tt::axis axis = Axis;
55 tt_axiom(is_gui_thread());
74 template<
typename Widget,
typename... Args>
77 return super::make_widget<Widget>(std::forward<Args>(args)...);
81 void init() noexcept
override
84 if (
auto delegate = _delegate.lock()) {
85 delegate->init(*
this);
89 void deinit() noexcept
override
91 if (
auto delegate = _delegate.lock()) {
92 delegate->deinit(*
this);
96 [[nodiscard]]
float margin() const noexcept
override
101 [[nodiscard]]
bool constrain(utc_nanoseconds display_time_point,
bool need_reconstrain)
noexcept override
103 tt_axiom(is_gui_thread());
107 _layout.
reserve(std::ssize(_children));
111 auto minimum_thickness = 0.0f;
112 auto preferred_thickness = 0.0f;
113 auto maximum_thickness = 0.0f;
114 for (ttlet &child : _children) {
115 update_constraints_for_child(*child, index++, minimum_thickness, preferred_thickness, maximum_thickness);
118 tt_axiom(index == std::ssize(_children));
120 if constexpr (axis == axis::row) {
121 _minimum_size = {_layout.minimum_size(), minimum_thickness};
122 _preferred_size = {_layout.preferred_size(), preferred_thickness};
123 _maximum_size = {_layout.maximum_size(), maximum_thickness};
125 _minimum_size = {minimum_thickness, _layout.minimum_size()};
126 _preferred_size = {preferred_thickness, _layout.preferred_size()};
127 _maximum_size = {maximum_thickness, _layout.maximum_size()};
129 tt_axiom(_minimum_size <= _preferred_size && _preferred_size <= _maximum_size);
136 [[nodiscard]]
void layout(utc_nanoseconds display_time_point,
bool need_layout)
noexcept override
138 tt_axiom(is_gui_thread());
140 need_layout |= _request_layout.exchange(
false);
145 for (ttlet &child : _children) {
146 update_layout_for_child(*child, index++);
149 tt_axiom(index == std::ssize(_children));
158 void update_constraints_for_child(
161 float &minimum_thickness,
162 float &preferred_thickness,
163 float &maximum_thickness)
noexcept
165 tt_axiom(is_gui_thread());
167 if (axis == axis::row) {
168 ttlet minimum_length = child.minimum_size().width();
169 ttlet preferred_length = child.preferred_size().width();
170 ttlet maximum_length = child.maximum_size().width();
171 _layout.update(index, minimum_length, preferred_length, maximum_length, child.margin());
173 minimum_thickness =
std::max(minimum_thickness, child.minimum_size().height() + child.margin() * 2.0f);
174 preferred_thickness =
std::max(preferred_thickness, child.preferred_size().height() + child.margin() * 2.0f);
175 maximum_thickness =
std::max(maximum_thickness, child.maximum_size().height() + child.margin() * 2.0f);
178 ttlet minimum_length = child.minimum_size().height();
179 ttlet preferred_length = child.preferred_size().height();
180 ttlet maximum_length = child.maximum_size().height();
181 _layout.update(index, minimum_length, preferred_length, maximum_length, child.margin());
183 minimum_thickness =
std::max(minimum_thickness, child.minimum_size().width() + child.margin() * 2.0f);
184 preferred_thickness =
std::max(preferred_thickness, child.preferred_size().width() + child.margin() * 2.0f);
185 maximum_thickness =
std::max(maximum_thickness, child.maximum_size().width() + child.margin() * 2.0f);
189 void update_layout_for_child(
widget &child, ssize_t index)
const noexcept
191 tt_axiom(is_gui_thread());
193 ttlet[child_offset, child_length] = _layout.get_offset_and_size(index++);
195 ttlet child_rectangle = axis == axis::row ?
200 rectangle().height() - child.margin() * 2.0f} :
203 rectangle().top() - child_offset - child_length,
204 rectangle().width() - child.margin() * 2.0f,
207 child.set_layout_parameters_from_parent(child_rectangle);