#340 Flow organizer now processes every line fraction separately 4.x-dev

Fri, 05 Nov 2021 10:13:45 +0200

author
cemkalyoncu
date
Fri, 05 Nov 2021 10:13:45 +0200
branch
4.x-dev
changeset 1759
2caac41d4418
parent 1758
185ba7aa8284
child 1760
33598e9edccd

#340 Flow organizer now processes every line fraction separately

Source/Gorgon/UI/Dialog.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Dialog.h 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/Widget.cpp file | annotate | diff | comparison | revisions
Source/Gorgon/UI/Widget.h file | annotate | diff | comparison | revisions
Testing/Source/Manual/UI_Generate.cpp file | annotate | diff | comparison | revisions
--- a/Source/Gorgon/UI/Dialog.cpp	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Dialog.cpp	Fri Nov 05 10:13:45 2021 +0200
@@ -98,11 +98,11 @@
         for(int i=0; i<5; i++) { //maximum 5 iterations
             sz = text->GetCurrentSize();
 
-            if(!allowshrink)
+            if(!allowshrink && sz.Width < diag->GetInteriorSize().Width)
                 sz.Width = diag->GetInteriorSize().Width;
 
             if(sz.Width < diag->GetUnitSize() * 6) {
-                //too small, use 4units at least
+                //too small, use 6units at least
                 sz.Width = diag->GetUnitSize() * 6;
                 break;
             }
--- a/Source/Gorgon/UI/Dialog.h	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Dialog.h	Fri Nov 05 10:13:45 2021 +0200
@@ -374,7 +374,7 @@
             }
         );
         
-        diag->ResizeInterior(negotiatesize(diag, text, false));
+        diag->ResizeInterior(Pixels(negotiatesize(diag, text, false)));
         if(l) {
             l->Move(Pixels(text->GetCurrentLocation().X, text->GetBounds().Bottom + text->GetCurrentLocation().Y));
             l->SetHeight(inp->GetHeight());
--- a/Source/Gorgon/UI/Organizers/Base.h	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Organizers/Base.h	Fri Nov 05 10:13:45 2021 +0200
@@ -59,6 +59,11 @@
             
             /// Adds the given text as a label to the attached container
             virtual Base &Add (const std::string &title);
+            
+            /// Returns if the organizer is currently working
+            bool IsReorganizing() const {
+                return organizing;
+            }
         
         protected:
             /// Called when the attachment of the organizer is changed
--- a/Source/Gorgon/UI/Organizers/Flow.cpp	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Organizers/Flow.cpp	Fri Nov 05 10:13:45 2021 +0200
@@ -21,7 +21,6 @@
             Utils::NotImplemented("Tight organization is not implemented yet.");
         }
         else {
-            int uw = GetAttached().GetUnitSize();
             int y = 0;
             int maxy = 0;
             int rowc = 0;
@@ -29,6 +28,8 @@
             int indent = 0;
             int breaks = 0;
             int breakspace = 0;
+            int fractions = 0;
+            int fractionals = 0;
             int xoff;
             auto align = defaultalign;
             auto nextalign = defaultalign;
@@ -38,18 +39,24 @@
             
             auto dorow = [&]{
                 if(maxy == 0)
-                    maxy = uw;
+                    maxy = usize;
                 
                 y += maxy + s;
                 
                 if(breaks > 0)
-                    y += (breaks-1) * (uw + s) + breakspace;
+                    y += (breaks-1) * (usize + s) + breakspace;
                 
                 int w = 0;
-                if(row.GetCount())
-                    w = row.Last()->GetBounds().Right;
+                if(row.GetCount()) {
+                    if(row.Last()->GetWidth().GetUnit() == Dimension::Fractions) {
+                        w = row.Last()->GetBounds().Left + usize;
+                    }
+                    else {
+                        w = row.Last()->GetBounds().Right;
+                    }
+                }
                 
-                int off = 0;
+                float off = 0;
                 
                 if(align == Graphics::TextAlignment::Center) {
                     off = (width - w) / 2;
@@ -58,16 +65,28 @@
                     off = width - w;
                 }
                 
+                float perfraction = 0;
+                if(fractionals) {
+                    perfraction = float(width - w + fractionals * (usize+s)) / fractions;
+                    off = 0;
+                }
+                
                 for(auto &cell : row) {
                     cell.Move(Pixels(
                         cell.GetCurrentLocation() +
-                        Geometry::Point{off, (maxy - cell.GetCurrentHeight())/2}
+                        Geometry::Point{(int)std::round(off), (maxy - cell.GetCurrentHeight())/2}
                     ));
+                    if(cell.GetWidth().GetUnit() == Dimension::Fractions) {
+                        cell.setwidthperfraction(perfraction);
+                        off += perfraction * cell.GetWidth().GetValue() - usize - s;
+                    }
                 }
                 
                 x = 0;
                 rowc = 0;
                 maxy = 0;
+                fractions = 0;
+                fractionals = 0;
                 row.Clear();
                 breakspace = 0;
             };
@@ -105,7 +124,14 @@
                     continue;
                 }
                 
-                int w = widget.GetCurrentWidth();
+                int w = usize;
+                if(widget.GetWidth().GetUnit() == Dimension::Fractions) {
+                    fractions += widget.GetWidth().GetValue();
+                    fractionals++;
+                }
+                else {
+                    w = widget.GetCurrentWidth();
+                }
                 
                 if(x + w + xoff > width && rowc > 0 && breaks == 0) {
                     breaks = 1;
--- a/Source/Gorgon/UI/Widget.cpp	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Widget.cpp	Fri Nov 05 10:13:45 2021 +0200
@@ -90,6 +90,8 @@
         if(!parent)
             return;
         
+        widthperfraction = -1;
+        
         parent->childboundschanged(this);
         
         if(parent && parent->GetHoveredWidget() == this)
@@ -172,6 +174,10 @@
             fr
         );
 
+        if(size.Width.GetUnit() == Dimension::Fractions && widthperfraction != -1) {
+            s.Width = (int)std::round(size.Width.GetValue() * widthperfraction);
+        }
+
         if(size.Width.IsRelative()) {
             s.Width -= spacing;
         }
@@ -237,6 +243,10 @@
         int px = val(vertical ? sz.Height : sz.Width, unitsize, spacing, em, fr, size);
 
         if(size && val.IsRelative()) {
+            if(val.GetUnit() == Dimension::Fractions && !vertical && widthperfraction != -1) {
+                px = (int)std::round(val.GetValue() * widthperfraction);
+            }
+            
             px -= spacing;
         }
 
@@ -256,7 +266,10 @@
             else
                 return {(float)px/(unitsize+size*spacing), target};
         case Dimension::Fractions:
-                return {(int)std::round((float)fr * (px+size*spacing) / (vertical ? sz.Height : sz.Width)), target};
+            if(size && !vertical && widthperfraction != -1)
+                return (int)std::round((px+spacing)/widthperfraction);
+            else
+                return {(int)std::round((float)fr * (px+spacing*size) / (vertical ? sz.Height : sz.Width)), target};
         case Dimension::EM:
             return {(float)px/em, Dimension::EM};
         }
@@ -280,6 +293,10 @@
         int em = Widgets::Registry::Active().GetEmSize();
 
         auto px = UI::Convert(val, sz, unitsize, spacing, em, fr);
+        
+        if(val.Width.GetUnit() == Dimension::Fractions && widthperfraction != -1) {
+            px.Width = (int)std::round(val.Width.GetValue() * widthperfraction);
+        }
 
         if(val.Width.IsRelative()) {
             px.Width -= spacing;
@@ -301,10 +318,18 @@
         case Dimension::MilliUnitSize:
             return {{(float)(px.Width+spacing)/(unitsize+spacing), target}, {(float)(px.Height+spacing)/(unitsize+spacing), target}};
         case Dimension::Fractions:
+            if(widthperfraction != -1) {
+                return {
+                    {(int)std::round((float)(px.Width+spacing) / widthperfraction), target},
+                    {(int)std::round((float)fr * (px.Height+spacing) / sz.Height), target},
+                };
+            }
+            else {
                 return {
                     {(int)std::round((float)fr * (px.Width+spacing) / sz.Width), target},
                     {(int)std::round((float)fr * (px.Height+spacing) / sz.Height), target},
                 };
+            }
         case Dimension::EM:
             return {{(float)px.Width/em, Dimension::EM}, {(float)px.Height/em, Dimension::EM}};;
         }
--- a/Source/Gorgon/UI/Widget.h	Thu Nov 04 20:10:48 2021 +0200
+++ b/Source/Gorgon/UI/Widget.h	Fri Nov 05 10:13:45 2021 +0200
@@ -265,6 +265,12 @@
 #endif
         }
         
+        /// Is designed to be used by organizers
+        void setwidthperfraction(float value) {
+            widthperfraction = value;
+            calculatebounds();
+        }
+        
 #ifndef NDEBUG
     std::string dbgname;
 #endif
@@ -355,6 +361,8 @@
         bool focus   = false;
         bool floating= false;
         
+        float widthperfraction = -1;
+        
         /// Never call this function
         virtual void hide() = 0;
         
--- a/Testing/Source/Manual/UI_Generate.cpp	Thu Nov 04 20:10:48 2021 +0200
+++ b/Testing/Source/Manual/UI_Generate.cpp	Fri Nov 05 10:13:45 2021 +0200
@@ -303,12 +303,12 @@
     Widgets::ColorPlane plane;
     
     org << 100_perc << plane << org.Break
-        << 2 << "Label" << 2 << "" << Coffee << l2
+        << chkbutton << 1_fr << input << org.Break
+        << 2 << "Label" << 4_spcs << "" << 1_fr << Coffee << org.Break << l2
         << list << 5_perc << org.Break
+        << chk << chk2
         << icnbtn2 << icnbtn3 << dlist
         <<  radio << icnbtn << 5 << "Hello"
-        << chk << chk2 << chkbutton
-        << input
         << bar
         << scroll1 << scroll2
         << colorin

mercurial