48 hi_axiom(loop::main().on_thread());
49 _children.push_back(std::make_unique<spacer_widget>(
this));
70 auto widget = std::make_unique<Widget>(
this, std::forward<Args>(args)...);
75 [[nodiscard]] generator<widget_intf &> children(
bool include_invisible)
noexcept override
77 for (
auto const& child : _children) {
78 co_yield *child.value;
82 [[nodiscard]] box_constraints update_constraints() noexcept
override
86 for (
auto& child : _children) {
87 child.set_constraints(child.value->update_constraints());
90 auto r = _children.constraints(os_settings::left_to_right());
91 _child_height_adjustment = -r.margins.top();
93 r.minimum.height() += r.margins.top();
94 r.preferred.height() += r.margins.top();
95 r.maximum.height() += r.margins.top();
100 void set_layout(widget_layout
const& context)
noexcept override
104 auto shape = context.shape;
105 shape.rectangle = aarectangle{shape.x(), shape.y(), shape.width(), shape.height() + _child_height_adjustment};
106 _children.set_layout(shape, theme().baseline_adjustment());
109 auto const overhang = context.redraw_overhang;
111 for (
auto const& child : _children) {
112 auto const child_clipping_rectangle =
113 aarectangle{child.shape.x() - overhang, 0, child.shape.width() + overhang * 2, context.height() + overhang * 2};
118 void draw(draw_context
const& context)
noexcept override
121 if (overlaps(context,
layout())) {
122 context.draw_box(
layout(),
layout().
rectangle(), theme().color(semantic_color::fill, _layout.layer));
124 if (tab_button_has_focus()) {
127 auto const focus_rectangle = aarectangle{0.0f, 0.0f,
layout().rectangle().width(), theme().border_width()};
128 context.draw_box(
layout(), translate3{0.0f, 0.0f, 1.5f} * focus_rectangle, focus_color());
132 for (
auto const& child : _children) {
133 hi_assert_not_null(child.value);
134 child.value->draw(context);
138 hitbox hitbox_test(point2 position)
const noexcept override
140 hi_axiom(loop::main().on_thread());
144 auto r =
layout().
contains(position) ? hitbox{
id, _layout.elevation, hitbox_type::move_area} : hitbox{};
146 for (
auto const& child : _children) {
147 hi_assert_not_null(child.value);
148 r = child.value->hitbox_test_from_parent(position, r);
156 [[nodiscard]] color focus_color() const noexcept
override
159 return theme().color(semantic_color::accent);
161 return theme().color(semantic_color::border, _layout.layer - 1);
166 mutable row_layout<std::unique_ptr<widget>> _children;
167 mutable float _child_height_adjustment = 0.0f;
168 size_t _spacer_index = 0;
170 void update_layout_for_child(
widget& child,
ssize_t index, widget_layout
const& context)
const noexcept;
180 _children.insert(_children.cbegin() + _spacer_index,
std::move(
widget));
184 _children.insert(_children.cbegin() + _spacer_index + 1,
std::move(
widget));
197 bool tab_button_has_focus() const noexcept
199 for (
auto const& cell : _children) {
200 if (
auto const *
const c =
dynamic_cast<toolbar_tab_button_widget *
>(cell.value.get())) {
201 if (c->focus() and c->value() == widget_value::on) {