#200: Widget widths can be set using units instead of pixels 4.x-dev

Fri, 20 Nov 2020 19:00:36 +0200

author
cemkalyoncu
date
Fri, 20 Nov 2020 19:00:36 +0200
branch
4.x-dev
changeset 1491
6e84dcee7996
parent 1490
b2f4ecae7d7b
child 1492
a7d9f275d5dc

#200: Widget widths can be set using units instead of pixels

Source/Gorgon/UI/ComponentStackWidget.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Organizers/List.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Template.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Generator.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Generator.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/RadioButtons.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Registry.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/UI/ComponentStackWidget.h	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/UI/ComponentStackWidget.h	Fri Nov 20 19:00:36 2020 +0200
@@ -46,6 +46,13 @@
 		virtual Geometry::Size GetSize() const override {
 			return stack.GetSize();
 		}
+		
+		/// Sets the width of the widget in unit widths.
+		void SetWidthInUnits(int n) {
+            int w = stack.GetTemplate().GetUnitWidth();
+            int s = stack.GetTemplate().GetSpacing();
+            SetWidth(w * n + s * (n-1));
+        }
 
         virtual void SetEnabled(bool value) override {
             if(enabled == value)
--- a/Source/Gorgon/UI/Organizers/List.cpp	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/UI/Organizers/List.cpp	Fri Nov 20 19:00:36 2020 +0200
@@ -8,7 +8,7 @@
         int w = GetAttached().GetInteriorSize().Width;
         
         for(auto &widget : GetAttached()) {
-            if(widget.IsVisible()) {
+            if(widget.IsVisible() && !widget.IsFloating()) {
                 widget.Move(0, y);
                 widget.SetWidth(w);
                 
--- a/Source/Gorgon/UI/Template.h	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/UI/Template.h	Fri Nov 20 19:00:36 2020 +0200
@@ -580,6 +580,23 @@
         }
 
 
+        /// Sets the unit width for a widget. This size should be enough to
+        /// have a bordered icon. 
+        void SetUnitWidth(int value) {
+            unitwidth = value;
+            ChangedEvent();
+        }
+        
+        /// Returns the unit width for a widget. This size is enough to
+        /// have a bordered icon. Widgets should be sized according to unit
+        /// width and spacing. A single unit width would be too small for
+        /// most widgets. Multiple units can be calculated by following
+        /// formula: W(n) = n * W(1) + (n-1) * Spacing
+        int GetUnitWidth() const {
+            return unitwidth;
+        }
+
+
         /// This event is fired whenever template or its components are changed.
         Event<Template> ChangedEvent = Event<Template>{*this};
         
@@ -594,6 +611,7 @@
         Geometry::Size size;
         Geometry::Size additional = {0, 0};
         int spacing = 4;
+        int unitwidth = 25;
     };
 
     /// Defines an object according to the Box Model.
--- a/Source/Gorgon/Widgets/Generator.cpp	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/Widgets/Generator.cpp	Fri Nov 20 19:00:36 2020 +0200
@@ -89,6 +89,14 @@
         UpdateBorders();
         UpdateDimensions();
     }
+    
+    UI::Template SimpleGenerator::maketemplate() {
+        UI::Template temp;
+        temp.SetSpacing(Spacing);
+        temp.SetUnitWidth(BorderedWidgetHeight); //BorderedHeight = UnitWidth
+        
+        return temp;
+    }
 
     SimpleGenerator::~SimpleGenerator() {
         if(regularrenderer)
@@ -557,8 +565,7 @@
     UI::Template SimpleGenerator::Button() {
         Geometry::Size defsize = {WidgetWidth, BorderedWidgetHeight};
         
-        UI::Template temp;
-        temp.SetSpacing(Spacing);
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         
@@ -665,7 +672,7 @@
         
         iconsize += Geometry::Size(externalspacing) * 2;
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         
         temp.SetSize(iconsize);
@@ -754,7 +761,7 @@
     UI::Template SimpleGenerator::Checkbox() {
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -871,7 +878,7 @@
     
     UI::Template SimpleGenerator::CheckboxButton() {
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(BorderedWidgetHeight, BorderedWidgetHeight);
         
@@ -968,7 +975,7 @@
     UI::Template SimpleGenerator::RadioButton() {
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1064,7 +1071,7 @@
     UI::Template SimpleGenerator::Label() {
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1098,7 +1105,7 @@
     UI::Template SimpleGenerator::ErrorLabel() {
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, WidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1134,7 +1141,7 @@
             WidgetWidth * 2 + Spacing, 
             BorderedWidgetHeight * 10 + Spacing * 9};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1322,7 +1329,7 @@
     UI::Template SimpleGenerator::Inputbox() {
         Geometry::Size defsize = {WidgetWidth, BorderedWidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1443,7 +1450,7 @@
         int h = std::max(Border.Radius * 2 + Border.Width * 2 + 4, Spacing * 3);
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, h};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
         
@@ -1476,7 +1483,7 @@
     UI::Template SimpleGenerator::BlankLayerbox() {
         Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 3, WidgetHeight * 4 + Spacing * 3};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         
@@ -1498,7 +1505,7 @@
     UI::Template SimpleGenerator::Layerbox() {
         Geometry::Size defsize = {WidgetWidth * 4 + Spacing * 3, WidgetHeight * 4 + Spacing * 3};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         
@@ -1526,7 +1533,7 @@
         
         Geometry::Size defsize = {w, BorderedWidgetHeight * 3 - Border.Width * 2};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         auto &cont = temp.AddContainer(0, UI::ComponentCondition::Always)
@@ -1564,7 +1571,7 @@
         
         Geometry::Size defsize = {WidgetWidth * 2 + Spacing, h};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         auto &cont = temp.AddContainer(0, UI::ComponentCondition::Always)
@@ -1598,7 +1605,7 @@
     UI::Template SimpleGenerator::Listbox() {
         Geometry::Size defsize = {WidgetWidth*2+Spacing, BorderedWidgetHeight*8};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         
         temp.SetSpacing(Spacing);
         temp.SetSize(defsize);
@@ -1748,7 +1755,7 @@
     UI::Template SimpleGenerator::Dropdown() {
         Geometry::Size defsize = {BorderedWidgetHeight * 4 + Spacing * 3, BorderedWidgetHeight};
         
-        UI::Template temp;
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         
@@ -1900,4 +1907,5 @@
         return temp;
         
     }
+    
 }}
--- a/Source/Gorgon/Widgets/Generator.h	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/Widgets/Generator.h	Fri Nov 20 19:00:36 2020 +0200
@@ -202,6 +202,10 @@
         virtual int GetEmSize() const override {
             return lettervsize.first + lettervsize.second;
         }
+        
+        virtual int GetUnitWidth() const override {
+            return BorderedWidgetHeight; //UnitWidth = Bordered height
+        }
 
         Graphics::BitmapRectangleProvider &NormalBorder();
         Graphics::BitmapRectangleProvider &HoverBorder();
@@ -312,6 +316,8 @@
         Graphics::RectangleProvider *makefocusborder();
         UI::Template makepanel(int missingedge, bool scrollers);
         
+        UI::Template maketemplate();
+        
         void setupfocus(UI::GraphicsTemplate &focus);
         
         Graphics::GlyphRenderer *regularrenderer = nullptr;
--- a/Source/Gorgon/Widgets/RadioButtons.h	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/Widgets/RadioButtons.h	Fri Nov 20 19:00:36 2020 +0200
@@ -50,6 +50,13 @@
             
             rearrange();
         }
+        
+        /// Sets the width of the widget in unit widths.
+        void SetWidthInUnits(int n) {
+            int w = temp.GetUnitWidth();
+            int s = temp.GetSpacing();
+            SetWidth(w * n + s * (n-1));
+        }
 
         void Add(const T_ value) {
             Add(value, String::From(value));
--- a/Source/Gorgon/Widgets/Registry.h	Fri Nov 20 04:17:43 2020 +0200
+++ b/Source/Gorgon/Widgets/Registry.h	Fri Nov 20 19:00:36 2020 +0200
@@ -85,13 +85,27 @@
             return *templates[type];
         }
     
-        virtual int GetSpacing()const = 0;
+        /// The spacing should be left between widgets
+        virtual int GetSpacing() const = 0;
 
-        virtual int GetEmSize()const = 0;
+        /// The size of EM space. Roughly the same size as the height of a character.
+        virtual int GetEmSize() const = 0;
+        
+        /// Returns the unit width for a widget. This size is enough to
+        /// have a bordered icon. Widgets should be sized according to unit
+        /// width and spacing. A single unit width would be too small for
+        /// most widgets. Multiple units can be obtained by GetUnitWidth(n)
+        virtual int GetUnitWidth() const = 0;
+        
+        /// Returns the width for a n-sized widget. Generally, 1 is for icons,
+        /// 2 is for numberbox, 3 can be used for buttons, labels, short textboxes
+        /// 4 for textboxes, 6 is for checkboxes. Standard panels can contain
+        /// 6 units and they are less than 7 units wide.
+        int GetUnitWidth(int n) const {
+            return n * GetUnitWidth() + (n-1) * GetSpacing();
+        }
 
     protected:
-
-
         /// This function should return a template for the given type. Due to 
         /// being used in constructors you are not allowed to reject template type.
         /// If the generator is capable of generating a similar template, simply
--- a/Testing/Source/Manual/UI_Generate.cpp	Fri Nov 20 04:17:43 2020 +0200
+++ b/Testing/Source/Manual/UI_Generate.cpp	Fri Nov 20 19:00:36 2020 +0200
@@ -201,6 +201,7 @@
     list.AddToSelection(3);
     list.AddToSelection(1, 4);
     list.InvertSelection();
+    list.SetWidthInUnits(5);
     list.ChangedEvent.Register([&](long index, bool status) {
         std::cout << "Selected items: ";
         for(auto &s : list.Selection) {
@@ -225,7 +226,7 @@
     dlist.SelectionChanged.Register([](long index) {
         std::cout << "Dropdown index: " << index << std::endl;
     });
-    
+   
     app.wind.Add(blank);
     addme(blank, btn);
     addme(blank, icnbtn);

mercurial