1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 16:47:41 +00:00

LibGUI: Add layout change propagation to Widget

This function is intended to propagate layout changes upwards in the
widget hierarchy. Widgets that can know what to do with this
information without causing a full layout invalidation (i.e. just
because one of their child widgets changed layout/size, doesn't
necessairily mean that they have to change their layout/size) can
override this and prevent a full relayout and redraw.
This commit is contained in:
FrHun 2022-06-28 17:56:47 +02:00 committed by Andreas Kling
parent f59c167bb0
commit 6f9777d35b
3 changed files with 16 additions and 8 deletions

View file

@ -52,7 +52,7 @@ void GroupBox::paint_event(PaintEvent& event)
void GroupBox::fonts_change_event(FontsChangeEvent& event) void GroupBox::fonts_change_event(FontsChangeEvent& event)
{ {
Widget::fonts_change_event(event); Widget::fonts_change_event(event);
invalidate_layout(); layout_relevant_change_occured();
} }
void GroupBox::set_title(StringView title) void GroupBox::set_title(StringView title)

View file

@ -199,6 +199,14 @@ Widget::Widget()
Widget::~Widget() = default; Widget::~Widget() = default;
void Widget::layout_relevant_change_occured()
{
if (auto* parent = parent_widget())
parent->layout_relevant_change_occured();
else
invalidate_layout();
}
void Widget::child_event(Core::ChildEvent& event) void Widget::child_event(Core::ChildEvent& event)
{ {
if (event.type() == Event::ChildAdded) { if (event.type() == Event::ChildAdded) {
@ -207,6 +215,7 @@ void Widget::child_event(Core::ChildEvent& event)
layout()->insert_widget_before(verify_cast<Widget>(*event.child()), verify_cast<Widget>(*event.insertion_before_child())); layout()->insert_widget_before(verify_cast<Widget>(*event.child()), verify_cast<Widget>(*event.insertion_before_child()));
else else
layout()->add_widget(verify_cast<Widget>(*event.child())); layout()->add_widget(verify_cast<Widget>(*event.child()));
layout_relevant_change_occured();
} }
if (window() && event.child() && is<Widget>(*event.child())) if (window() && event.child() && is<Widget>(*event.child()))
window()->did_add_widget({}, verify_cast<Widget>(*event.child())); window()->did_add_widget({}, verify_cast<Widget>(*event.child()));
@ -215,8 +224,7 @@ void Widget::child_event(Core::ChildEvent& event)
if (layout()) { if (layout()) {
if (event.child() && is<Widget>(*event.child())) if (event.child() && is<Widget>(*event.child()))
layout()->remove_widget(verify_cast<Widget>(*event.child())); layout()->remove_widget(verify_cast<Widget>(*event.child()));
else layout_relevant_change_occured();
invalidate_layout();
} }
if (window() && event.child() && is<Widget>(*event.child())) if (window() && event.child() && is<Widget>(*event.child()))
window()->did_remove_widget({}, verify_cast<Widget>(*event.child())); window()->did_remove_widget({}, verify_cast<Widget>(*event.child()));
@ -791,7 +799,7 @@ void Widget::set_min_size(UISize const& size)
if (m_min_size == size) if (m_min_size == size)
return; return;
m_min_size = size; m_min_size = size;
invalidate_layout(); layout_relevant_change_occured();
} }
void Widget::set_max_size(UISize const& size) void Widget::set_max_size(UISize const& size)
@ -800,7 +808,7 @@ void Widget::set_max_size(UISize const& size)
if (m_max_size == size) if (m_max_size == size)
return; return;
m_max_size = size; m_max_size = size;
invalidate_layout(); layout_relevant_change_occured();
} }
void Widget::set_preferred_size(UISize const& size) void Widget::set_preferred_size(UISize const& size)
@ -808,7 +816,7 @@ void Widget::set_preferred_size(UISize const& size)
if (m_preferred_size == size) if (m_preferred_size == size)
return; return;
m_preferred_size = size; m_preferred_size = size;
invalidate_layout(); layout_relevant_change_occured();
} }
Optional<UISize> Widget::calculated_preferred_size() const Optional<UISize> Widget::calculated_preferred_size() const
@ -840,8 +848,7 @@ void Widget::set_visible(bool visible)
if (visible == m_visible) if (visible == m_visible)
return; return;
m_visible = visible; m_visible = visible;
if (auto* parent = parent_widget()) layout_relevant_change_occured();
parent->invalidate_layout();
if (m_visible) if (m_visible)
update(); update();
if (!m_visible && is_focused()) if (!m_visible && is_focused())

View file

@ -352,6 +352,7 @@ protected:
// This is called after children have been painted. // This is called after children have been painted.
virtual void second_paint_event(PaintEvent&); virtual void second_paint_event(PaintEvent&);
virtual void layout_relevant_change_occured();
virtual void custom_layout() { } virtual void custom_layout() { }
virtual void did_change_font() { } virtual void did_change_font() { }
virtual void did_layout() { } virtual void did_layout() { }