#203: All organizers are able to stream widgets and text 4.x-dev

Sat, 21 Nov 2020 22:22:35 +0200

author
cemkalyoncu
date
Sat, 21 Nov 2020 22:22:35 +0200
branch
4.x-dev
changeset 1494
33abdc8b5e5b
parent 1493
b50cb1ee1caf
child 1495
3a06f30f2749

#203: All organizers are able to stream widgets and text
Flow organizer can stream std::endl, ::Break, and integers for unit width

Source/Gorgon/UI/ComponentStackWidget.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Organizers/Base.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Organizers/Base.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Organizers/Flow.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Organizers/Flow.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Widget.h file | annotate | diff | comparison | revisions
Source/Gorgon/UI/WidgetContainer.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/WidgetContainer.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Composer.h file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/Generator.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/Widgets/RadioButtons.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/UI/ComponentStackWidget.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/ComponentStackWidget.h	Sat Nov 21 22:22:35 2020 +0200
@@ -48,7 +48,7 @@
 		}
 		
 		/// Sets the width of the widget in unit widths.
-		void SetWidthInUnits(int n) {
+		virtual void SetWidthInUnits(int n) override {
             int w, s;
             if(HasParent()) {
                 w = GetParent().GetUnitWidth();
--- a/Source/Gorgon/UI/Organizers/Base.cpp	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/Organizers/Base.cpp	Sat Nov 21 22:22:35 2020 +0200
@@ -1,5 +1,6 @@
 #include "Base.h"
 #include "../WidgetContainer.h"
+#include "../../Widgets/Label.h"
 
 namespace Gorgon { namespace UI { namespace Organizers {
     
@@ -39,4 +40,27 @@
             organizing = false;
         }
     }
+    
+    
+
+    Base &Base::operator<< (Widget &widget) {
+        GetAttached().Add(widget);
+
+        return *this;
+    }
+
+    Base &Base::operator<< (const std::string &title) {
+        if(!IsAttached()) {
+            throw std::runtime_error("This organizer is not attached to a container");
+        }
+        
+        auto &l = *new Widgets::Label(title);
+        
+        operator <<(l);
+        GetAttached().Own(l);
+
+        return *this;
+    }
+    
+    
 } } }
--- a/Source/Gorgon/UI/Organizers/Base.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/Organizers/Base.h	Sat Nov 21 22:22:35 2020 +0200
@@ -6,6 +6,8 @@
 namespace Gorgon { namespace UI {
     
     class WidgetContainer;
+
+    class Widget;
     
     /**
      * This namespace contains organizers that manage the location of the widgets
@@ -45,6 +47,12 @@
             /// Reorganizes the widgets that are organized by this organizer
             void Reorganize();
             
+            /// Adds the given widget to the attached container.
+            virtual Base &operator << (Widget &widget);
+            
+            /// Adds the given text as a label to the attached container
+            virtual Base &operator << (const std::string &title);
+        
         protected:
             /// Called when the attachment of the organizer is changed
             virtual void attachmentchanged() { }
--- a/Source/Gorgon/UI/Organizers/Flow.cpp	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/Organizers/Flow.cpp	Sat Nov 21 22:22:35 2020 +0200
@@ -2,6 +2,8 @@
 #include "../WidgetContainer.h"
 #include "../../Widgets/Registry.h"
 
+#include <iostream>
+
 namespace Gorgon { namespace UI { namespace Organizers {
     
     void Flow::reorganize() {
@@ -21,6 +23,9 @@
             int ind = -1;
             int breaks = BreakCount(-1);
             
+            //to valign
+            Containers::Collection<Widget> row;
+            
             for(auto &widget : att)  {
                 ind++;
                 
@@ -31,7 +36,8 @@
                 
                 int w = widget.GetWidth();
                 
-                breaks += (x + w > width && rowc > 0) ? 1 : 0;
+                if((x + w > width && rowc > 0) && breaks == 0)
+                    breaks = 1;
                 
                 if(breaks) {
                     if(maxy == 0)
@@ -42,9 +48,15 @@
                     if(breaks > 0)
                         y += (breaks-1) * (uw + s);
                     
+                    for(auto &cell : row) {
+                        if(maxy - cell.GetHeight() > 0)
+                            cell.Move(cell.GetLocation() + Geometry::Point{0, (maxy - cell.GetHeight())/2});
+                    }
+                    
                     x = 0;
                     rowc = 0;
                     maxy = 0;
+                    row.Clear();
                 }
                 
                 int h = widget.GetHeight();
@@ -56,6 +68,7 @@
                 x += w + s;
                 rowc++;
                 breaks = BreakCount(ind);
+                row.Push(widget);
             }
         }
     }
@@ -94,5 +107,30 @@
         if(order != -1)
             InsertBreak(order);
     }
+    
+    Flow &Flow::operator<< (std::ostream &(*fn)(std::ostream &)) {
+        if(fn == &std::endl<char, std::char_traits<char>>) {
+            InsertBreak();
+        }
+        else {
+            throw std::runtime_error("Unsupported manipulator, only std::endl is supported");
+        }
+        
+        return *this;
+    }
+
+    Organizers::Flow &Flow::operator<< (Widget &widget) {
+        Base::operator << (widget);
+
+        if(nextsize != -1) {
+            widget.SetWidthInUnits(nextsize);
+            nextsize = -1;
+        }
+
+        return *this;
+    }
+    
+    Flow::BreakTag Flow::Break;
+
 
 } } }
--- a/Source/Gorgon/UI/Organizers/Flow.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/Organizers/Flow.h	Sat Nov 21 22:22:35 2020 +0200
@@ -2,6 +2,7 @@
 
 #include "Base.h"
 
+#include <iosfwd>
 #include <unordered_set>
 
 namespace Gorgon { namespace UI { 
@@ -24,6 +25,9 @@
      */
     class Flow : public Base {
     public:
+        class BreakTag {
+        };
+        
         /// Constructs a new flow organizer specifying spacing between widgets
         explicit Flow(int spacing) : usedefaultspacing(false), spacing(spacing) {
         }
@@ -108,12 +112,43 @@
             Reorganize();
         }
         
+        /// Adds the given widget to the attached container.
+        virtual Flow &operator << (Widget &widget) override;
+        
+        /// Adds the given text as a label to the attached container
+        virtual Flow &operator << (const std::string &title) override {
+            Base::operator <<(title);
+            
+            return *this;
+        }
+        
+        /// When supplied with std::endl, inserts a line break.
+        Flow &operator << (std::ostream &(*fn)(std::ostream &));
+        
+        /// When supplied with std::endl, inserts a line break.
+        Flow &operator << (BreakTag) {
+            InsertBreak();
+            
+            return *this;
+        }
+        
+        /// Sets the size of the next widget in unit sizes
+        Flow &operator << (int unitsize) {
+            nextsize = unitsize;
+            
+            return *this;
+        }
+        
+        
+        static BreakTag Break;
+        
     protected:
         virtual void reorganize() override;
         
         bool usedefaultspacing = true;
         int spacing = 0;
         bool tight = false;
+        int nextsize = -1;
         std::unordered_multiset<int> breaks;
     };
     
--- a/Source/Gorgon/UI/Widget.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/Widget.h	Sat Nov 21 22:22:35 2020 +0200
@@ -71,6 +71,9 @@
         /// Sets the width of the widget
         void SetWidth(int width) { Resize(width, GetHeight()); }
         
+        /// Sets the width of the widget in unit widths.
+        virtual void SetWidthInUnits(int n) = 0;
+        
         /// Sets the height of the widget
         void SetHeight(int height) { Resize(GetWidth(), height); }
         
--- a/Source/Gorgon/UI/WidgetContainer.cpp	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/WidgetContainer.cpp	Sat Nov 21 22:22:35 2020 +0200
@@ -466,6 +466,7 @@
     WidgetContainer::~WidgetContainer() { 
         if(ownorganizer)
             delete organizer;
+        owned.Destroy();
     }
 
     void WidgetContainer::Displaced() {
--- a/Source/Gorgon/UI/WidgetContainer.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/UI/WidgetContainer.h	Sat Nov 21 22:22:35 2020 +0200
@@ -379,6 +379,16 @@
         
         /// Call this function if the container or widgets in it is moved without move function is called.
         void Displaced();
+        
+        /// This container will own the given widget.
+        void Own(const Widget &widget) {
+            owned.Add(widget);
+        }
+        
+        /// Removes the ownership of the given widget, if it is not owned nothing happens.
+        void Disown(const Widget &widget) {
+            owned.Remove(widget);
+        }
 
         /// This function should be called whenever a key is pressed or released.
         virtual bool KeyEvent(Input::Key key, float state) { return distributekeyevent(key, state, true); }
@@ -455,6 +465,7 @@
         int focusindex	            = -1;
         Organizers::Base *organizer = nullptr;
         bool ownorganizer           = false;
+        Containers::Collection<const Widget> owned;
 
         FocusStrategy focusmode = Inherit;
     };
--- a/Source/Gorgon/Widgets/Composer.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/Widgets/Composer.h	Sat Nov 21 22:22:35 2020 +0200
@@ -73,7 +73,7 @@
         }
 
 		/// Sets the width of the widget in unit widths.
-		void SetWidthInUnits(int n);
+		void SetWidthInUnits(int n) override;
         
         /// This function should be called whenever a key is pressed or released.
         virtual bool KeyEvent(Input::Key key, float state) override { return distributekeyevent(key, state, true); }
--- a/Source/Gorgon/Widgets/Generator.cpp	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/Widgets/Generator.cpp	Sat Nov 21 22:22:35 2020 +0200
@@ -1219,8 +1219,7 @@
             defsize.Width = WidgetWidth * 2 + Spacing + Border.Width + Spacing * 2;
         }
         
-        UI::Template temp;
-        temp.SetSpacing(Spacing);
+        UI::Template temp = maketemplate();
         temp.SetSize(defsize);
         
         
--- a/Source/Gorgon/Widgets/RadioButtons.h	Sat Nov 21 18:47:12 2020 +0200
+++ b/Source/Gorgon/Widgets/RadioButtons.h	Sat Nov 21 22:22:35 2020 +0200
@@ -53,7 +53,7 @@
         }
         
         /// Sets the width of the widget in unit widths.
-        void SetWidthInUnits(int n) {
+        void SetWidthInUnits(int n) override {
             int w, s;
             if(HasParent()) {
                 w = GetParent().GetUnitWidth();
--- a/Testing/Source/Manual/UI_Generate.cpp	Sat Nov 21 18:47:12 2020 +0200
+++ b/Testing/Source/Manual/UI_Generate.cpp	Sat Nov 21 22:22:35 2020 +0200
@@ -279,31 +279,20 @@
     }
     
     app.wind.Add(blank);
-    addme(blank, Coffee);
-    addme(blank, btn);
-    addme(blank, list);
-    addme(blank, icnbtn);
-    addme(blank, icnbtn2);
-    addme(blank, dlist);
-    addme(blank, icnbtn3);
-    addme(blank, l);
-    addme(blank, radio);
-    addme(blank, l2);
-    addme(blank, input);
-    addme(blank, chk);
-    addme(blank, chk2);
-    addme(blank, chkbutton);
-    addme(blank, bar);
-    addme(blank, scroll1);
-    addme(blank, scroll2);
-    addme(blank, sizef);
+    
     auto &org = blank.CreateOrganizer<UI::Organizers::Flow>();
-    org.InsertBreak(-1);
-    org.InsertBreak(list);
-    org.InsertBreak(list);
     
-    
-    
+    org << std::endl << 2 << "Label" << Coffee
+        << btn
+        << list << org.Break << UI::Organizers::Flow::Break
+        << icnbtn << icnbtn2 << dlist
+        << icnbtn3 << l << radio << l2
+        << input
+        << chk << chk2 << chkbutton
+        << bar
+        << scroll1 << scroll2
+        << sizef
+    ;
 
     /*Widgets::Progressor<std::string, StringDiv, StringVal, Gorgon::TextualProperty> bar2;
     bar2.Maximum = "Hello world";

mercurial