#337 Min/max window size 4.x-dev

Fri, 29 Oct 2021 07:38:50 +0300

author
cemkalyoncu
date
Fri, 29 Oct 2021 07:38:50 +0300
branch
4.x-dev
changeset 1747
2f9ad833617f
parent 1746
37a08db9a582
child 1748
f965ac36d227

#337 Min/max window size
* SetInteriorWidth/Height

Source/Gorgon/UI/Dimension.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/LayerAdapter.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/LayerAdapter.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Widget.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/WidgetContainer.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Window.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Window.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Composer.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Composer.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Panel.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Panel.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/TabPanel.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Window.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Window.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/UI/Dimension.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/Dimension.h	Fri Oct 29 07:38:50 2021 +0300
@@ -311,17 +311,17 @@
     }
 
     /// Converts the given value to dimension with percentage units
-    inline constexpr DualDimension Percentage(int one, int two) {
+    inline constexpr DualDimension Percent(int one, int two) {
         return {{one, Dimension::Percent}, {two, Dimension::Percent}};
     }
 
     /// Converts the given one, given twoue to dimension with percentage units
-    inline constexpr DualDimension Percentage(double one, double two) {
+    inline constexpr DualDimension Percent(double one, double two) {
         return {{one, Dimension::Percent}, {two, Dimension::Percent}};
     }
 
     /// Converts the given one, given twoue to dimension with percentage units
-    inline constexpr DualDimension Percentage(float one, float two) {
+    inline constexpr DualDimension Percent(float one, float two) {
         return {{one, Dimension::Percent}, {two, Dimension::Percent}};
     }
 
--- a/Source/Gorgon/UI/LayerAdapter.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/LayerAdapter.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -53,6 +53,7 @@
             s = base->GetCalculatedSize();
         }
 
+        interiorsize = size;
         base->Resize(Convert(size, s, GetUnitSize(), GetSpacing(), Widgets::Registry::Active().GetEmSize()));
 
         return true;
--- a/Source/Gorgon/UI/LayerAdapter.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/LayerAdapter.h	Fri Oct 29 07:38:50 2021 +0300
@@ -31,7 +31,15 @@
         }
         
         virtual bool ResizeInterior(const UI::UnitSize &size) override;
-        
+
+        virtual bool SetInteriorWidth(const UI::UnitDimension &size) override {
+            return ResizeInterior({size, interiorsize.Height});
+        }
+
+        virtual bool SetInteriorHeight(const UI::UnitDimension &size) override {
+            return ResizeInterior({interiorsize.Width, size});
+        }
+
         virtual bool IsDisplayed () const override {
             return base->IsVisible();
         }
@@ -115,6 +123,7 @@
         int spacing   = 0;
         int unitsize = 0;
         bool issizesset = false;
+        UnitSize interiorsize;
     };
     
 } }
--- a/Source/Gorgon/UI/Widget.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/Widget.h	Fri Oct 29 07:38:50 2021 +0300
@@ -89,10 +89,10 @@
         int GetCurrentHeight() const { return GetCurrentSize().Height; }
 
         /// Sets the width of the widget
-        void SetWidth(UnitDimension width) { Resize(width, GetHeight()); }
+        virtual void SetWidth(UnitDimension width) { Resize(width, GetHeight()); }
         
         /// Sets the height of the widget
-        void SetHeight(UnitDimension height) { Resize(GetWidth(), height); }
+        virtual void SetHeight(UnitDimension height) { Resize(GetWidth(), height); }
         
         /// Activates the widget. This might perform the action if the
         /// widget is a button, forward the focus if it is a label or
--- a/Source/Gorgon/UI/WidgetContainer.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/WidgetContainer.h	Fri Oct 29 07:38:50 2021 +0300
@@ -291,7 +291,17 @@
         /// If resize operation cannot set the size exactly to the
         /// requested size, this function returns false.
         virtual bool ResizeInterior(const UI::UnitSize &size) = 0;
-        
+
+        /// Should resize the interior (usable) size of the container.
+        /// If resize operation cannot set the size exactly to the
+        /// requested size, this function returns false.
+        virtual bool SetInteriorWidth(const UnitDimension &size) = 0;
+
+        /// Should resize the interior (usable) size of the container.
+        /// If resize operation cannot set the size exactly to the
+        /// requested size, this function returns false.
+        virtual bool SetInteriorHeight(const UnitDimension &size) = 0;
+
         /// Check if tab switch is enabled. Tab switch allows user to change
         /// focus to the next widget using tab key. Default is enabled.
         virtual bool IsTabSwitchEnabled() const { return tabswitch; }
--- a/Source/Gorgon/UI/Window.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/Window.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -302,6 +302,8 @@
 
     bool Window::ResizeInterior(const UI::UnitSize &size) {
 
+        interiorsize = size;
+
         const auto &mon = WindowManager::Monitor::FromLocation(GetLocation());
 
         Geometry::Size s = {0, 0};
--- a/Source/Gorgon/UI/Window.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/UI/Window.h	Fri Oct 29 07:38:50 2021 +0300
@@ -162,12 +162,22 @@
         
         virtual void Resize(const Geometry::Size &size) override {
             Gorgon::Window::Resize(size);
+
+            interiorsize = Pixels(size);
             
             distributeparentboundschanged();
         }
         
         virtual bool ResizeInterior(const UI::UnitSize &size) override;
         
+        virtual bool SetInteriorWidth(const UI::UnitDimension &size) override {
+            return ResizeInterior({size, interiorsize.Height});
+        }
+
+        virtual bool SetInteriorHeight(const UI::UnitDimension &size) override {
+            return ResizeInterior({interiorsize.Width, size});
+        }
+
         /// Closes the window, returning the execution to the
         /// point where Run function is called. It allows current
         /// frame to be completed before quiting.
@@ -281,6 +291,8 @@
             }
         }
 
+        UnitSize interiorsize;
+
     private:
         bool quiting = false;
         LayerAdapter extenderadapter, windowadapter, baradapter, dialogadapter, underadapter;
--- a/Source/Gorgon/Widgets/Composer.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Composer.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -161,13 +161,24 @@
     }
 
     void ComponentStackComposer::resize(const Geometry::Size &size) {
-        if(interiorsized) {
-            ComponentStackWidget::resize(size + GetCurrentSize() - GetInteriorSize());
+        if(interiorsized.first || interiorsized.second) {
+            Geometry::Size border = {0, 0};
+
+            auto innersize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
+
+            border = GetCurrentSize() - innersize;
+
+            if(!interiorsized.first)
+                border.Width = 0;
+            if(!interiorsized.second)
+                border.Height = 0;
+
+            ComponentStackWidget::resize(size + border);
         }
         else {
             ComponentStackWidget::resize(size);
         }
-        
+
         if(HasOrganizer())
             GetOrganizer().Reorganize();
         
@@ -216,4 +227,39 @@
         }
     }
 
+    bool ComponentStackComposer::ResizeInterior(const UI::UnitSize &size) {
+        if(interiorsized != std::make_pair(true, true))
+            lsize = {-1, -1};
+        interiorsized = {true, true};
+        ComponentStackWidget::Resize(size);
+
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize() == lsize;
+    }
+
+    bool ComponentStackComposer::SetInteriorWidth(const UI::UnitDimension &size) {
+        if(interiorsized.first != true)
+            lsize = {-1, -1};
+        interiorsized = {true, interiorsized.second};
+        ComponentStackWidget::Resize(size, GetSize().Height);
+
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize().Width == lsize.Width;
+    }
+
+    bool ComponentStackComposer::SetInteriorHeight(const UI::UnitDimension &size) {
+        if(interiorsized.second != true)
+            lsize = {-1, -1};
+        interiorsized = {interiorsized.first, true};
+        ComponentStackWidget::Resize(GetSize().Width, size);
+
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize().Height == lsize.Height;
+    }
+
+
+void ComponentStackComposer::Resize(const UI::UnitSize& size, std::pair< bool, bool > interiorsized) {
+    if(this->interiorsized != interiorsized)
+        lsize = {-1, -1};
+    this->interiorsized = interiorsized;
+    ComponentStackWidget::Resize(size);
+}
+
 } }
--- a/Source/Gorgon/Widgets/Composer.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Composer.h	Fri Oct 29 07:38:50 2021 +0300
@@ -47,6 +47,16 @@
             return true;
         }
 
+        virtual bool SetInteriorWidth(const UI::UnitDimension &size) override {
+            SetWidth(size);
+            return true;
+        }
+
+        virtual bool SetInteriorHeight(const UI::UnitDimension &size) override {
+            SetHeight(size);
+            return true;
+        }
+
         virtual Geometry::Point GetCurrentLocation() const override {
             return base.GetLocation();
         }
@@ -220,13 +230,6 @@
             return stack.GetSize();
         }
 
-        virtual bool ResizeInterior(const UI::UnitSize &size) override {
-            interiorsized = true;
-            Resize(size);
-            
-            return GetInteriorSize() == lsize;
-        }
-        
         virtual void SetVisible(bool value) override {
             ComponentStackWidget::SetVisible(value);
             distributeparentboundschanged();
@@ -258,13 +261,15 @@
         virtual bool CharacterPressed(Char c) override { return distributecharevent(c); }
 
         virtual void Resize(const UI::UnitSize &size) override {
-            interiorsized = false;
-            ComponentStackWidget::Resize(size);
+            Resize(size, {false, false});
         }
 
+        void Resize(const UI::UnitSize &size, std::pair<bool, bool> interiorsized);
+
+
     protected:
 
-        bool interiorsized = false;
+        std::pair<bool, bool> interiorsized = {false, false};
 
         //ensure this object is derived
         ComponentStackComposer(const UI::Template &temp, std::map<UI::ComponentTemplate::Tag, std::function<Widget *(const UI::Template &)>> generators = {}) :
@@ -323,6 +328,14 @@
             return true;
         }
         
+
+        virtual bool ResizeInterior(const UI::UnitSize &size) override;
+
+        virtual bool SetInteriorWidth(const UI::UnitDimension &size) override;
+
+        virtual bool SetInteriorHeight(const UI::UnitDimension &size) override;
+
+
         virtual Geometry::Size GetInteriorSize() const override {
             return stack.GetLayerOf(stack.IndexOfTag(UI::ComponentTemplate::ContentsTag)).GetSize();
         }
--- a/Source/Gorgon/Widgets/Panel.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Panel.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -107,20 +107,47 @@
     }
 
     bool Panel::ResizeInterior(const UI::UnitSize &size) {
-        interiorsized = true;
+        if(interiorsized != std::make_pair(true, true))
+            lsize = {-1, -1};
+
+        interiorsized = {true, true};
         ComponentStackWidget::Resize(size);
 
-        return stack.TagBounds(UI::ComponentTemplate::ContentsTag).GetSize() == lsize;
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize() == lsize;
+    }
+
+    bool Panel::SetInteriorWidth(const UI::UnitDimension &size) {
+        if(interiorsized.first != true)
+            lsize = {-1, -1};
+
+        interiorsized = {true, interiorsized.second};
+        ComponentStackWidget::Resize({size, GetSize().Height});
+
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize().Width == lsize.Width;
     }
-    
+
+    bool Panel::SetInteriorHeight(const UI::UnitDimension &size) {
+         if(interiorsized.second != true)
+            lsize = {-1, -1};
+
+       interiorsized = {interiorsized.first, true};
+        ComponentStackWidget::Resize({GetSize().Width, size});
+
+        return stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize().Height == lsize.Height;
+    }
+
     void Panel::resize(const Geometry::Size &size) {
-        if(interiorsized) {
+        if(interiorsized.first || interiorsized.second) {
             Geometry::Size border = {0, 0};
 
             auto innersize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
 
-            if(innersize.Area() != 0)
-                border = GetCurrentSize() - innersize;
+            border = GetCurrentSize() - innersize;
+
+            if(!interiorsized.first)
+                border.Width = 0;
+            if(!interiorsized.second)
+                border.Height = 0;
 
             ComponentStackWidget::resize(size + border);
         }
@@ -270,5 +297,13 @@
         }
     }
 
+
+void Panel::Resize(const UI::UnitSize& size, std::pair< bool, bool > interiorsized) {
+    if(this->interiorsized != interiorsized)
+        lsize = {-1, -1};
+    this->interiorsized = interiorsized;
+    ComponentStackWidget::Resize(size);
+}
+
 } }
 
--- a/Source/Gorgon/Widgets/Panel.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Panel.h	Fri Oct 29 07:38:50 2021 +0300
@@ -31,7 +31,6 @@
             distributeparentboundschanged();
         }
 
-
         virtual bool KeyPressed(Input::Key, float) override;
 
 
@@ -43,9 +42,16 @@
 
         virtual Geometry::Size GetInteriorSize() const override;
 
+        UI::UnitSize GetCalculatedInteriorSize(UI::Dimension::Unit unit) {
+            return Convert(unit, UI::Pixels(GetInteriorSize()));
+        }
 
         virtual bool ResizeInterior(const UI::UnitSize &size) override;
-        
+
+        virtual bool SetInteriorWidth(const UI::UnitDimension &size) override;
+
+        virtual bool SetInteriorHeight(const UI::UnitDimension &size) override;
+
         /// Controls whether scrolling will be enabled vertically or horizontally.
         /// It is possible to use ScrollTo function without enabling scrolling but
         /// the user will not be able to scroll in this case. Enabling scrolling
@@ -64,6 +70,12 @@
             return hscroll;
         }
         
+        /// Sets the width of the widget
+        virtual void SetWidth(UnitDimension width) override { Resize({width, GetHeight()}, {false, interiorsized.second}); }
+
+        /// Sets the height of the widget
+        virtual void SetHeight(UnitDimension height) override { Resize({GetWidth(), height}, {interiorsized.first, false}); }
+
         
         virtual bool Done() override {
             if(HasFocusedWidget())
@@ -198,10 +210,11 @@
         using ComponentStackWidget::Resize;
 
         virtual void Resize(const UI::UnitSize &size) override {
-            interiorsized = false;
-            ComponentStackWidget::Resize(size);
+            Resize(size, {false, false});
         }
 
+        void Resize(const UI::UnitSize &size, std::pair<bool, bool> interiorsized);
+
         
     protected:
         virtual bool allowfocus() const override;
@@ -224,10 +237,6 @@
         
         virtual void moved() override { distributeparentboundschanged(); }
         
-        bool updaterequired = false;
-        
-        Input::KeyRepeater repeater;
-        
         FocusStrategy getparentfocusstrategy() const override {
             if(HasParent())
                 return GetParent().CurrentFocusStrategy();
@@ -243,16 +252,20 @@
             else if(state && IsEnabled())
                 distributeparentenabled(state);
         }
-        
-        int spacing   = 0;
-        int unitwidth = 0;
-        bool issizesset = false;
                 
         virtual void resize(const Geometry::Size &size) override;
         
         virtual void move(const Geometry::Point &location) override;
 
-        bool interiorsized = false;
+        bool updaterequired = false;
+
+        Input::KeyRepeater repeater;
+
+        int spacing   = 0;
+        int unitwidth = 0;
+        bool issizesset = false;
+
+        std::pair<bool, bool> interiorsized = {false, false};
 
     private:
 
--- a/Source/Gorgon/Widgets/TabPanel.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/TabPanel.h	Fri Oct 29 07:38:50 2021 +0300
@@ -59,6 +59,8 @@
      * a container, its members are. Each tab is associated with a key.
      * Creating another with the same key will erase the tab, removing its
      * contents.
+     *
+     * TODO: InteriorSizing
      */
     template <class Key_>
     class basic_TabPanel : public ComponentStackComposer {
--- a/Source/Gorgon/Widgets/Window.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Window.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -46,8 +46,6 @@
             
             Center();
         }
-        
-        minsize = GetCurrentSize() - GetInteriorSize() + Geometry::Size(stack.GetTemplate().GetUnitSize()*2, stack.GetTemplate().GetUnitSize());
     }
     
     Window::Window(const UI::Template &temp, const std::string &title, const UI::UnitSize size, bool autoplace) :
@@ -149,17 +147,38 @@
     void Window::updatescrollvisibility() {
         auto val = stack.GetTargetValue();
         
+        bool changed = false;
         if(val[2] == 1 || val[2] == 0 || !hscroll) {
-            stack.RemoveCondition(UI::ComponentCondition::HScroll);
+            if(hscrollon) {
+                stack.RemoveCondition(UI::ComponentCondition::HScroll);
+                changed = true;
+                hscrollon = false;
+            }
         }
         else {
-            stack.AddCondition(UI::ComponentCondition::HScroll);
+            if(!hscrollon) {
+                stack.AddCondition(UI::ComponentCondition::HScroll);
+                changed = true;
+                hscrollon = true;
+            }
         }
         if(val[3] == 1 || val[3] == 0 || !vscroll) {
-            stack.RemoveCondition(UI::ComponentCondition::VScroll);
+            if(vscrollon) {
+                stack.RemoveCondition(UI::ComponentCondition::VScroll);
+                changed = true;
+                vscrollon = false;
+            }
         }
         else {
-            stack.AddCondition(UI::ComponentCondition::VScroll);
+            if(!vscrollon) {
+                stack.AddCondition(UI::ComponentCondition::VScroll);
+                changed = true;
+                vscrollon = true;
+            }
+        }
+
+        if(changed) {
+            Panel::resize(lsize);
         }
     }
     
@@ -231,6 +250,7 @@
         if(button == Input::Mouse::Button::Left) {
             moving = false;
             resizing = none;
+            pointertoken.Revert();
         }
     }
     
@@ -374,7 +394,8 @@
             int h = ch + location.Y - dragoffset.Y;
             
             if(HasParent()) {
-                FitInto(h, minsize.Height, std::min((GetParent().GetInteriorSize().Height - GetCurrentLocation().Y) * 2, GetParent().GetInteriorSize().Height));
+                FitInto(h, minsizepx.Height, std::min((GetParent().GetInteriorSize().Height - GetCurrentLocation().Y) * 2, maxsizepx.Height));
+                std::cout << h << std::endl;
             }
             
             SetHeight(Pixels(h));
@@ -388,7 +409,7 @@
             int h = ch - location.Y + dragoffset.Y;
             
             if(HasParent()) {
-                FitInto(h, minsize.Height, GetCurrentHeight()+GetCurrentLocation().Y);
+                FitInto(h, minsizepx.Height, std::min(GetCurrentHeight()+GetCurrentLocation().Y, maxsizepx.Height));
             }
             
             SetHeight(Pixels(h));
@@ -410,7 +431,7 @@
             int w = cw + location.X - dragoffset.X;
             
             if(HasParent()) {
-                FitInto(w, minsize.Width, std::min((GetParent().GetInteriorSize().Width - GetCurrentLocation().X) * 2, GetParent().GetInteriorSize().Width));
+                FitInto(w, minsizepx.Width, std::min((GetParent().GetInteriorSize().Width - GetCurrentLocation().X) * 2, maxsizepx.Width));
             }
             
             SetWidth(Pixels(w));
@@ -425,7 +446,7 @@
             int w = cw - location.X + dragoffset.X;
             
             if(HasParent()) {
-                FitInto(w, minsize.Width, GetCurrentWidth()+GetCurrentLocation().X);
+                FitInto(w, minsizepx.Width, std::min(GetCurrentWidth()+GetCurrentLocation().X, maxsizepx.Width));
             }
             
             SetWidth(Pixels(w));
@@ -528,6 +549,63 @@
         return true;
     }
 
+    void Window::resize(const Geometry::Size& size) {
+        Panel::resize(size);
+
+        //prevent recursion if there is a problem with min-max sizing
+        if(!updatingminmax) {
+            updatingminmax = true;
+            minsizepx = Convert(minsize);
+            maxsizepx = Convert(maxsize);
+            auto sz = GetInteriorSize();
+
+            if(sz.Width < minsizepx.Width && sz.Height < minsizepx.Height) {
+                ResizeInterior(minsize);
+            }
+            else if(sz.Width < minsizepx.Width) {
+                SetInteriorWidth(minsize.Width);
+            }
+            else if(sz.Height < minsizepx.Height) {
+                SetInteriorHeight(minsize.Height);
+            }
+
+            sz = GetCurrentSize();
+            if(sz.Width > maxsizepx.Width && sz.Height > maxsizepx.Height) {
+                Resize(maxsize);
+            }
+            else if(sz.Width > maxsizepx.Width) {
+                SetWidth(maxsize.Width);
+            }
+            else if(sz.Height > maxsizepx.Height) {
+                SetHeight(maxsize.Height);
+            }
+
+            Geometry::Size border = {0, 0};
+
+            auto innersize = stack.TagBounds(UI::ComponentTemplate::ViewPortTag).GetSize();
+
+            border = GetCurrentSize() - innersize;
+
+            minsizepx += border;
 
 
+            updatingminmax = false;
+        }
+    }
+
+    void Window::SetMinSize(const UI::UnitSize& value) {
+        minsize = value;
+
+        lsize = {-1, -1}; //force update
+        Resize(GetSize(), interiorsized);
+    }
+
+
+    void Window::SetMaxSize(const UI::UnitSize& value) {
+        maxsize = value;
+
+        lsize = {-1, -1}; //force update
+        Resize(GetSize(), interiorsized);
+    }
+
 } }
--- a/Source/Gorgon/Widgets/Window.h	Thu Oct 28 06:53:24 2021 +0300
+++ b/Source/Gorgon/Widgets/Window.h	Fri Oct 29 07:38:50 2021 +0300
@@ -197,6 +197,22 @@
         void Center();
         
         virtual void EnableScroll(bool vertical, bool horizontal) override;
+
+        /// Sets minimum internal size of the widget, default value is 2x1 units.
+        void SetMinSize(const UI::UnitSize &value);
+
+        /// Returns minimum internal size of the widget
+        UI::UnitSize GetMinSize() const {
+            return minsize;
+        }
+
+        /// Sets maximum external size of the widget, default value is 100%, 100%
+        void SetMaxSize(const UI::UnitSize &value);
+
+        /// Sets maximum external size of the widget
+        UI::UnitSize GetMaxSize() const {
+            return maxsize;
+        }
         
         /// Window title
         TextualProperty<Window, std::string, &Window::GetTitle, &Window::SetTitle> Title;
@@ -239,6 +255,8 @@
         
         void mouse_click(UI::ComponentTemplate::Tag tag, Geometry::Point location, Input::Mouse::Button button);
 
+        void resize(const Geometry::Size &size) override;
+
     private:
         enum resizedir {
             none,
@@ -264,8 +282,11 @@
         Geometry::Point dragoffset;
         resizedir resizing = none;
         bool allowresize = false;
-        Geometry::Size minsize;
+        Geometry::Size minsizepx, maxsizepx;
+        UI::UnitSize minsize = UI::Units(2, 1), maxsize = UI::Percent(100, 100);
         Graphics::PointerStack::Token pointertoken;
+        bool hscrollon = false, vscrollon = true;
+        bool updatingminmax = false;
     };
     
 } }
--- a/Testing/Source/Manual/UI_Generate.cpp	Thu Oct 28 06:53:24 2021 +0300
+++ b/Testing/Source/Manual/UI_Generate.cpp	Fri Oct 29 07:38:50 2021 +0300
@@ -320,6 +320,8 @@
     Widgets::DialogWindow wind("My window", {6, 6});
     wind.Add(btn);
     wind.Add(btn2);
+    wind.SetMinSize({6,1});
+    wind.SetMaxSize({50_perc,8});
     btn.Move(Pixels(0,0));
     btn.Disable();
     wind.OwnIcon(icon.CreateAnimation());
@@ -331,7 +333,7 @@
     });
     Widgets::Checkbox enableclosebtn("Enable close button", true);
     enableclosebtn.SetWidth(6_u);
-    enableclosebtn.SetAutosize(Gorgon::UI::Autosize::Unit, Gorgon::UI::Autosize::Automatic);
+    //enableclosebtn.SetAutosize(Gorgon::UI::Autosize::Unit, Gorgon::UI::Autosize::Automatic);
     enableclosebtn.ChangedEvent.Register([&] { wind.SetCloseButtonEnabled(bool(enableclosebtn)); });
     wind.AddUnder(enableclosebtn);
     wind.AddUnder("Try resize");

mercurial