mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-22 12:06:00 +00:00
menu_view: defer geometry animation to layout step
The box-layout widget used to trigger the geometry animation of its children immediately when updating the widget from the XML model (by calling 'child->Widget::geometry'). This caused layout inconsistencies in situations where the box layout is defined not by the constraints of the child widgets but from the outside (the parent calls Widget::size). Since the final layout is not known before the parent defines the actual size, this patch moves the trigger point for the geometry animation to 'Widget::size'.
This commit is contained in:
parent
05b0010281
commit
3065cceb73
@ -75,7 +75,7 @@ class Menu_view::Animated_rect : public Rect, Animator::Item, Noncopyable
|
||||
Point(_p2.x(), _p2.y()));
|
||||
|
||||
/* schedule / de-schedule animation */
|
||||
animated(_p1.animated() || _p2.animated());
|
||||
Animator::Item::animated(_p1.animated() || _p2.animated());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,6 +91,8 @@ class Menu_view::Animated_rect : public Rect, Animator::Item, Noncopyable
|
||||
_p2.move_to(rect.p2(), steps);
|
||||
animate();
|
||||
}
|
||||
|
||||
bool animated() const { return Animator::Item::animated(); }
|
||||
};
|
||||
|
||||
#endif /* _ANIMATED_GEOMETRY_H_ */
|
||||
|
@ -55,20 +55,22 @@ struct Menu_view::Box_layout_widget : Widget
|
||||
|
||||
Area const child_min_size = w.min_size();
|
||||
|
||||
w.position(position);
|
||||
|
||||
if (_direction == VERTICAL) {
|
||||
w.geometry(Rect(position, Area(largest_size, child_min_size.h())));
|
||||
unsigned const next_top_margin = w.next() ? w.next()->margin.top : 0;
|
||||
unsigned const dy = child_min_size.h() - min(w.margin.bottom, next_top_margin);
|
||||
position = position + Point(0, dy);
|
||||
} else {
|
||||
w.geometry(Rect(position, Area(child_min_size.w(), largest_size)));
|
||||
unsigned const next_left_margin = w.next() ? w.next()->margin.left : 0;
|
||||
unsigned const dx = child_min_size.w() - min(w.margin.right, next_left_margin);
|
||||
position = position + Point(dx, 0);
|
||||
}
|
||||
|
||||
_min_size = Area(w.geometry().x2() + 1, w.geometry().y2() + 1);
|
||||
});
|
||||
|
||||
_min_size = (_direction == VERTICAL)
|
||||
? Area(largest_size, position.y())
|
||||
: Area(position.x(), largest_size);
|
||||
}
|
||||
|
||||
Area min_size() const override
|
||||
|
@ -52,9 +52,6 @@ struct Menu_view::Root_widget : Widget
|
||||
}
|
||||
|
||||
_update_children(node);
|
||||
|
||||
_children.for_each([&] (Widget &child) {
|
||||
child.geometry(Rect(Point(0, 0), child.min_size())); });
|
||||
}
|
||||
|
||||
Area min_size() const override
|
||||
|
@ -160,6 +160,16 @@ class Menu_view::Widget : public List_model<Widget>::Element
|
||||
|
||||
Animated_rect _animated_geometry { _factory.animator };
|
||||
|
||||
void _trigger_geometry_animation()
|
||||
{
|
||||
if (_animated_geometry.animated())
|
||||
return;
|
||||
|
||||
if (_geometry.p1() != _animated_geometry.p1()
|
||||
|| _geometry.p2() != _animated_geometry.p2())
|
||||
_animated_geometry.move_to(_geometry, Animated_rect::Steps{60});
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Margin margin { 0, 0, 0, 0 };
|
||||
@ -167,7 +177,7 @@ class Menu_view::Widget : public List_model<Widget>::Element
|
||||
void geometry(Rect geometry)
|
||||
{
|
||||
_geometry = geometry;
|
||||
_animated_geometry.move_to(_geometry, Animated_rect::Steps{60});
|
||||
_trigger_geometry_animation();
|
||||
}
|
||||
|
||||
Rect geometry() const { return _geometry; }
|
||||
@ -213,6 +223,8 @@ class Menu_view::Widget : public List_model<Widget>::Element
|
||||
_geometry = Rect(_geometry.p1(), size);
|
||||
|
||||
_layout();
|
||||
|
||||
_trigger_geometry_animation();
|
||||
}
|
||||
|
||||
void position(Point position)
|
||||
|
Loading…
x
Reference in New Issue
Block a user