From 6f9777d35b2099e204da95cad4596da156f594cd Mon Sep 17 00:00:00 2001 From: FrHun <28605587+frhun@users.noreply.github.com> Date: Tue, 28 Jun 2022 17:56:47 +0200 Subject: [PATCH] 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. --- Userland/Libraries/LibGUI/GroupBox.cpp | 2 +- Userland/Libraries/LibGUI/Widget.cpp | 21 ++++++++++++++------- Userland/Libraries/LibGUI/Widget.h | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Userland/Libraries/LibGUI/GroupBox.cpp b/Userland/Libraries/LibGUI/GroupBox.cpp index 31e86f9da7..77c1079f22 100644 --- a/Userland/Libraries/LibGUI/GroupBox.cpp +++ b/Userland/Libraries/LibGUI/GroupBox.cpp @@ -52,7 +52,7 @@ void GroupBox::paint_event(PaintEvent& event) void GroupBox::fonts_change_event(FontsChangeEvent& event) { Widget::fonts_change_event(event); - invalidate_layout(); + layout_relevant_change_occured(); } void GroupBox::set_title(StringView title) diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index e605bfca30..9dc15cc4d5 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -199,6 +199,14 @@ Widget::Widget() 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) { if (event.type() == Event::ChildAdded) { @@ -207,6 +215,7 @@ void Widget::child_event(Core::ChildEvent& event) layout()->insert_widget_before(verify_cast(*event.child()), verify_cast(*event.insertion_before_child())); else layout()->add_widget(verify_cast(*event.child())); + layout_relevant_change_occured(); } if (window() && event.child() && is(*event.child())) window()->did_add_widget({}, verify_cast(*event.child())); @@ -215,8 +224,7 @@ void Widget::child_event(Core::ChildEvent& event) if (layout()) { if (event.child() && is(*event.child())) layout()->remove_widget(verify_cast(*event.child())); - else - invalidate_layout(); + layout_relevant_change_occured(); } if (window() && event.child() && is(*event.child())) window()->did_remove_widget({}, verify_cast(*event.child())); @@ -791,7 +799,7 @@ void Widget::set_min_size(UISize const& size) if (m_min_size == size) return; m_min_size = size; - invalidate_layout(); + layout_relevant_change_occured(); } 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) return; m_max_size = size; - invalidate_layout(); + layout_relevant_change_occured(); } 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) return; m_preferred_size = size; - invalidate_layout(); + layout_relevant_change_occured(); } Optional Widget::calculated_preferred_size() const @@ -840,8 +848,7 @@ void Widget::set_visible(bool visible) if (visible == m_visible) return; m_visible = visible; - if (auto* parent = parent_widget()) - parent->invalidate_layout(); + layout_relevant_change_occured(); if (m_visible) update(); if (!m_visible && is_focused()) diff --git a/Userland/Libraries/LibGUI/Widget.h b/Userland/Libraries/LibGUI/Widget.h index 80706789f9..0f8c8b8e80 100644 --- a/Userland/Libraries/LibGUI/Widget.h +++ b/Userland/Libraries/LibGUI/Widget.h @@ -352,6 +352,7 @@ protected: // This is called after children have been painted. virtual void second_paint_event(PaintEvent&); + virtual void layout_relevant_change_occured(); virtual void custom_layout() { } virtual void did_change_font() { } virtual void did_layout() { }