浏览代码

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.
FrHun 3 年之前
父节点
当前提交
6f9777d35b
共有 3 个文件被更改,包括 16 次插入8 次删除
  1. 1 1
      Userland/Libraries/LibGUI/GroupBox.cpp
  2. 14 7
      Userland/Libraries/LibGUI/Widget.cpp
  3. 1 0
      Userland/Libraries/LibGUI/Widget.h

+ 1 - 1
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)

+ 14 - 7
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<Widget>(*event.child()), verify_cast<Widget>(*event.insertion_before_child()));
             else
                 layout()->add_widget(verify_cast<Widget>(*event.child()));
+            layout_relevant_change_occured();
         }
         if (window() && event.child() && is<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 (event.child() && is<Widget>(*event.child()))
                 layout()->remove_widget(verify_cast<Widget>(*event.child()));
-            else
-                invalidate_layout();
+            layout_relevant_change_occured();
         }
         if (window() && event.child() && is<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)
         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<UISize> 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())

+ 1 - 0
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() { }