diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index 7f32b79e08..3c8a8262b3 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -809,6 +809,24 @@ void Widget::set_preferred_size(UISize const& size) invalidate_layout(); } +Optional Widget::calculated_preferred_size() const +{ + if (layout()) + return { layout()->preferred_size() }; + return {}; +} + +Optional Widget::calculated_min_size() const +{ + if (layout()) + return { layout()->min_size() }; + // Fall back to at least displaying the margins, so the Widget is not 0 size. + auto m = content_margins(); + if (!m.is_null()) + return UISize { m.left() + m.right(), m.top() + m.bottom() }; + return {}; +} + void Widget::invalidate_layout() { if (window()) diff --git a/Userland/Libraries/LibGUI/Widget.h b/Userland/Libraries/LibGUI/Widget.h index 6a49f2153b..80706789f9 100644 --- a/Userland/Libraries/LibGUI/Widget.h +++ b/Userland/Libraries/LibGUI/Widget.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,28 @@ public: UIDimension preferred_height() const { return m_preferred_size.height(); } void set_preferred_width(UIDimension width) { set_preferred_size(width, preferred_height()); } void set_preferred_height(UIDimension height) { set_preferred_size(preferred_width(), height); } + + virtual Optional calculated_preferred_size() const; + virtual Optional calculated_min_size() const; + + UISize effective_preferred_size() const + { + auto effective_preferred_size = preferred_size(); + if (effective_preferred_size.either_is(SpecialDimension::Shrink)) + effective_preferred_size.replace_component_if_matching_with(SpecialDimension::Shrink, effective_min_size()); + if (effective_preferred_size.either_is(SpecialDimension::Fit) && calculated_preferred_size().has_value()) + effective_preferred_size.replace_component_if_matching_with(SpecialDimension::Fit, calculated_preferred_size().value()); + return effective_preferred_size; + } + + UISize effective_min_size() const + { + auto effective_min_size = min_size(); + if (effective_min_size.either_is(SpecialDimension::Shrink) && calculated_min_size().has_value()) + effective_min_size.replace_component_if_matching_with(SpecialDimension::Shrink, calculated_min_size().value()); + return effective_min_size; + } + void set_fixed_size(UISize const& size) { VERIFY(size.has_only_int_values());