Revision: 4608
          http://sourceforge.net/p/vexi/code/4608
Author:   clrg
Date:     2013-12-03 01:52:09 +0000 (Tue, 03 Dec 2013)
Log Message:
-----------
Completes the grid overhaul; now works in all known cases

Modified Paths:
--------------
    branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t
    branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve1.t
    branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve2.t

Modified: 
branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t
===================================================================
--- branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t    
2013-11-29 16:03:37 UTC (rev 4607)
+++ branches/vexi3/org.vexi-vexi.widgets/src_main/org/vexi/lib/layout/grid.t    
2013-12-03 01:52:09 UTC (rev 4608)
@@ -70,6 +70,18 @@
         const byCol = {};
         const byRow = {};
         
+        /* PLACING
+         *
+         * The effect of each child is measured against the region it
+         * occupies - the row/column boundary it is pushing.  If this
+         * region changes then boxes in subsequent regions shift over.
+         *
+         * Note 1: (case solve2)
+         * There is a corner case where a spanning box occupies the
+         * end of an axis, pushing the next box into a region which
+         * has an origin with no matching frontier; so use origin-1.
+         */
+        
         const placeRegions = function(axis, fullreach, gridsize, shrink, 
contentdim, mindim, maxdim, dim, pos) {
             const regions = axis.regions;
             const frontiers = axis.frontiers;
@@ -93,10 +105,15 @@
                 
                 const origin = region.origin;
                 const frontier = region.frontier;
-                const priorMin = origin>0 ? frontierMin[origin] : 0;
-                const priorMax = origin>0 ? frontierMax[origin] : 0;
-                const currentMin = frontierMin[region.frontier];
-                const currentMax = frontierMax[region.frontier];
+                // see place note (1)
+                var priorMin = origin>0 ? frontierMin[origin] : 0;
+                if (priorMin == null)
+                    priorMin = frontierMin[origin-1];
+                var priorMax = origin>0 ? frontierMax[origin] : 0;
+                if (priorMax == null)
+                    priorMax = frontierMax[origin-1];
+                const currentMin = frontierMin[frontier];
+                const currentMax = frontierMax[frontier];
                 
                 if (currentMin == null or priorMin + minsize > currentMin) {
                     contentMin = max(priorMin + minsize, contentMin);
@@ -106,7 +123,9 @@
                     if (contentMax != vexi.ui.maxdim) {
                         contentMax = min(vexi.ui.maxdim, max(priorMax + 
maxsize, contentMax));
                         frontierMax[frontier] = priorMax + maxsize;
-                    } else frontierMax[frontier] = min(vexi.ui.maxdim, 
priorMax + maxsize);
+                    } else {
+                        frontierMax[frontier] = min(vexi.ui.maxdim, priorMax + 
maxsize);
+                    }
                 }
             }
             // by now we know our minimum/maximum size
@@ -114,10 +133,14 @@
             $content[maxdim] = contentMax;
             
             // PHASE 2: place wrapper boxes in accordance with region/frontier 
min/max sizes
-            if (thisbox[shrink] or $content[mindim] >= gridsize) {
+            if (thisbox[shrink] or contentMin >= gridsize) {
                 // honor min sizes
                 for (var i,region in regions.list) {
-                    const regionPos = region.origin>0 ? 
frontierMin[region.origin] : 0; 
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = origin>0 ? frontierMin[origin] : 0;
+                    if (regionPos == null)
+                        regionPos = frontierMin[origin-1]; 
                     const regionDim = frontierMin[region.frontier] - regionPos;
                     for (var j,box in region.boxes) {
                         box[pos] = regionPos;
@@ -125,10 +148,14 @@
                     }
                 }
             } else
-            if (gridsize >= $content[maxdim]) {
+            if (gridsize >= contentMax) {
                 // honor max sizes
                 for (var i,region in regions.list) {
-                    const regionPos = region.origin>0 ? 
frontierMax[region.origin] : 0; 
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = origin>0 ? frontierMax[origin] : 0;
+                    if (regionPos == null)
+                        regionPos = frontierMax[origin-1];
                     const regionDim = frontierMax[region.frontier] - regionPos;
                     for (var j,box in region.boxes) {
                         box[pos] = regionPos;
@@ -173,7 +200,10 @@
                             target = minsize;
                         } else {
                             target = targetSize * reach;
-                            const o_index = f2i[origin];
+                            // see place note (1)
+                            var o_index = f2i[origin];
+                            if (o_index == null)
+                                o_index = f2i[origin-1];
                             
                             if (target > minsize)
                                 for (var i=f_index; i>o_index; i--)
@@ -186,7 +216,11 @@
                             else target = maxsize;
                         }
                         
-                        const frontierPush = frontierDim[origin] + target;
+                        var originDim = frontierDim[origin];
+                        // see place note (1)
+                        if (originDim == null)
+                            originDim = frontierDim[origin-1];
+                        const frontierPush = originDim + target;
                         if (frontier!=lastFrontier or frontierPush > 
frontierDim[frontier])
                             frontierDim[frontier] = frontierPush;
                         lastFrontier = frontier;
@@ -210,8 +244,9 @@
                             // no rows to be further decreased in size
                             throw "Should not be possible";
                         }
+                        var ts = targetSize;
                         // else adjust targetRowSize according to target-total 
deficit
-                        targetSize += ((totalSize-gridsize) / reachDown);
+                        targetSize -= ((totalSize-gridsize) / reachDown);
                         
                     } else {
                         // too small; adjust up
@@ -224,12 +259,14 @@
                             // no rows to be further increased in size
                             throw "Should not be possible";
                         }
+                        var ts = targetSize;
                         // adjust targetRowSize according to target-total 
deficit
                         targetSize += ((gridsize-totalSize) / reachUp);
                     }
+                    
                     if (i>=99) {
                         // infinite loop prevention
-                        vexi.log.warn("failed to solve grid "+dim+" 
"+fullreach);
+                        vexi.log.warn("failed to solve grid "+dim+" 
"+thisbox[dim]+" with rows/cols:"+fullreach);
                     }
                 }
                 
@@ -238,25 +275,21 @@
                 
                 // place our boxes
                 for (var i,region in regions.list) {
-                    const regionPos = round(frontierDim[region.origin]);
-                    const targetDim = round(frontierDim[region.frontier]) - 
regionPos;
-                    const regionDim = min(region.maxsize, max(region.minsize, 
targetDim));
+                    const origin = region.origin;
+                    // see place note (1)
+                    var regionPos = frontierDim[origin];
+                    if (regionPos == null)
+                        regionPos = frontierDim[origin-1];
+                    const roundPos = round(regionPos);
+                    const roundDim = round(frontierDim[region.frontier]) - 
roundPos;
                     for (var j,box in region.boxes) {
-                        box[pos] = regionPos;
-                        box[dim] = regionDim;
+                        box[pos] = roundPos;
+                        box[dim] = roundDim;
                     }
                 }
             }
         }
         
-        /*
-         * PLACING
-         *
-         * The effect of each child is measured against the region it
-         * occupies - the row/column boundary it is pushing.  If this
-         * region changes then boxes in subsequent regions shift over.
-         */
-        
         const place = function() {
             if (!numcols or !numrows) {
                 // not yet initialized
@@ -272,14 +305,13 @@
             }
         }
         
-        /* 
-         * PACKING
+        /* PACKING
          *
          * Here we pack the child boxes as close together as their row-
-         * and col-span will allow.  The packing is done according to
-         * the setting of the user - if they set rows then we pack the
+         * and col-span will allow. The packing approach is determined
+         * by which grid property is the set - if 'rows' then pack the
          * children down the number of rows and accomodate children by
-         * adding extra columns.
+         * adding extra columns, and vice versa for 'cols'.
          */
         
         /** establish an ordered list of frontiers for placing */
@@ -314,17 +346,16 @@
             establishFrontier(byRow.frontiers, rowfrontier);
         }
         
-        /** pack by column first, expanding rows as required */
-        const packByCol = function() {
-            const frontier = new .vector();
-            var nextcol = 0;  // the next available col
-            var nextrow = 0;  // the next available row
-            var minrows = 0;  // the minimum row past a frontier box
-            var c, c0; var f, f0;
+        /** pack by primary axis (e.g. column) first, expanding secondary axis 
(e.g. rows) as required */
+        const packAxis = function(mainAxis, mainSpan, v_mainAxis, growAxis, 
growSpan, v_growAxis) {
+            const frontier = new vexi.js.ProxyList();
+            var nextMain = 0;  // the next available col
+            var nextGrow = 0;  // the next available row
+            var minFront = 0;  // the minimum row past a frontier box
             
             // assign col/row values to packed children
             for (var i,c in $content) {
-                c0 = c[0];
+                const c0 = c[0];
                 
                 if (!c0.display) {
                     // disregard hidden children
@@ -334,176 +365,80 @@
                     c.display = true;
                 }
                 
-                if (nextcol!=0 and nextcol+c0.colspan > setsize) {
+                if ((nextMain!=0) and (nextMain+c0[mainSpan] > setsize)) {
                     // if we don't fit on the row, jump to the next
-                    nextcol=0;
-                    nextrow++;
+                    nextMain=0;
+                    nextGrow++;
                 }
                 
                 // check to see if we are making a full pass at the row
-                const fullpass = nextcol==0;
+                const fullpass = nextMain==0;
                 
                 // work through frontier boxes until a suitable position is 
found
                 PACKME: while (frontier.length>0) {
-                    f = frontier.first;
-                    while (f != null) {
-                        f0 = f[0];
-                        if (nextrow >= f0.v_row+f0.rowspan) {
+                    var fKey = 0;
+                    var f0 = frontier[fKey];
+                    while (f0 != null) {
+                        if (nextGrow >= f0[v_growAxis]+f0[growSpan]) {
                             // reduce frontier by removing boxes not affecting 
the frontier row
-                            f0 = frontier.after(f);
-                            frontier.remove(f);
-                            f = f0;
+                            frontier[fKey] = null;
+                            f0 = frontier[fKey];
                             continue;
                         }
-                        if (f0.v_col+f0.colspan > nextcol and 
nextcol+c0.colspan > f0.v_col) {
-                            // frontier not accomdating current child, look 
further
+                        if ((f0[v_mainAxis] + f0[mainSpan] > nextMain) and
+                                (nextMain + c0[mainSpan] > f0[v_mainAxis])) {
+                            // frontier not accomodating current child, look 
further
                             
                             // establish next available col
-                            nextcol = f0.v_col+f0.colspan;
+                            nextMain = f0[v_mainAxis] + f0[mainSpan];
                             // establish next available row
-                            minrows = (minrows == 0) ? f0.v_row+f0.rowspan : 
min(minrows, f0.v_row+f0.rowspan);
+                            minFront = (minFront == 0) ? f0[v_growAxis] + 
f0[growSpan]
+                                : min(minFront, f0[v_growAxis] + f0[growSpan]);
                             
-                            if (nextcol+c0.colspan > setsize) {
-                                // c will not fit on nextrow
+                            if (nextMain + c0[mainSpan] > setsize) {
+                                // c will not fit on nextsec
                                 if (!fullpass) {
                                     // if not a full pass, try next immediate 
row
-                                    nextrow++;
-                                    nextcol=0;
-                                    minrows=0;
+                                    nextGrow++;
+                                    nextMain = 0;
+                                    minFront = 0;
                                 } else {
                                     // try c on next available row
-                                    nextcol=0;
-                                    nextrow=minrows;
-                                    minrows=0;
+                                    nextMain = 0;
+                                    nextGrow = minFront;
+                                    minFront = 0;
                                 }
                                 // try frontier again
                                 continue PACKME;
                             }
-                        } else if (f0.v_col >= nextcol+c0.colspan) {
+                        } else if (f0[v_mainAxis] >= nextMain + c0[mainSpan]) {
                             // fit between previous frontier and this frontier
                             break PACKME;
                         }
                         // next frontier
-                        f = frontier.after(f);
+                        f0 = frontier[++fKey];
                     }
-                    if (setsize >= nextcol+c0.colspan) {
+                    if (setsize >= nextMain + c0[mainSpan]) {
                         // fits in the col after frontier
                         break;
                     }
                 }
-                if (c0.rowspan>1) {
+                if (c0[growSpan] > 1) {
                     // add to frontier if we affect the frontier
-                    if (f) {
-                        f = frontier.before(f);
-                        if (f) {
-                            frontier.insert(c, f);
-                        } else {
-                            frontier.unshift(c);
-                        }
+                    if (f0) {
+                        frontier[fKey] = c0;
                     } else {
-                        frontier.push(c);
+                        frontier[frontier.length] = c0;
                     }
                 }
                 // place packed child
-                assignSlot(c, nextcol, nextrow);
+                assignSlot(c, nextMain, nextGrow);
                 // prepare for next iteration
-                minrows = 0;            // reset minrows
-                nextcol += c0.colspan;  // bump up nextcol
-                // update the number of rows
-                numrows = max(numrows, c0.v_row+c0.rowspan);
+                minFront = 0;             // reset minFront
+                nextMain += c0[mainSpan]; // bump up nextMain
             }
         }
         
-        /** pack by row first - for comments see packByCol **/
-        var packByRow = function() {
-            var frontier = new .vector();
-            var nextrow = 0;  // the next available row
-            var nextcol = 0;  // the next available col
-            var mincols = 0;  // the minimum col past a frontier box
-            var c, c0; var f, f0;
-            
-            // assign row/col values to packed children
-            for (var i,c in $content) {
-                c0 = c[0];
-                // disregard hidden children
-                if (!c0.display) {
-                    c.display = false;
-                    continue;
-                } else {
-                    c.display = true;
-                }
-                if (nextrow!=0 and nextrow+c0.rowspan > setsize) {
-                    // does not fit in the column, jump to next row
-                    nextrow=0;
-                    nextcol++;
-                }
-                
-                // check to see if we are making a full pass at the col
-                const fullpass = nextrow==0;
-                
-                // work through frontier boxes until a suitable position is 
found
-                PACKME: while (frontier.length>0) {
-                    f = frontier.first;
-                    while (f != null) {
-                        f0 = f[0];
-                        if (nextcol >= f0.v_col+f0.colspan) {
-                            // reduce frontier by removing boxes not affecting 
the frontier col
-                            f0 = frontier.after(f);
-                            frontier.remove(f);
-                            f = f0;
-                            continue;
-                        }
-                        if (nextrow+c0.rowspan > f0.v_row and 
f0.v_row+f0.rowspan > nextrow) {
-                            // frontier not accomdating current child, look 
further
-                            
-                            // establish next available row
-                            nextrow = f0.v_row+f0.rowspan;
-                            // establish next available col
-                            mincols = (mincols == 0) ? f0.v_col+f0.colspan : 
min(mincols, f0.v_col+f0.colspan);
-                            
-                            if (nextrow+c0.rowspan > setsize) {
-                                // c will not fit on nextcol
-                                if (!fullpass) {
-                                    // if not a full pass, try next immediate 
col
-                                    nextrow++; nextcol=0; minrows=0;
-                                } else {
-                                    // try c on next available col
-                                    nextrow=0; nextcol=mincols; mincols=0;
-                                }
-                                // try frontier again
-                                continue PACKME;
-                            }
-                        } else if (f0.v_row >= nextrow+c0.rowspan) {
-                            // fit between previous frontier and this frontier
-                            break PACKME;
-                        }
-                        // next frontier
-                        f = frontier.after(f);
-                    }
-                    if (setsize >= nextrow+c0.rowspan) {
-                        // fits on this row after frontier
-                        break;
-                    }
-                }
-                if (c0.colspan>1) {
-                    // add to frontier if we affect the frontier
-                    if (f) {
-                        f = frontier.before(f);
-                        if (f) {
-                            frontier.insert(c, f);
-                        } else {
-                            frontier.unshift(c);
-                        }
-                    } else frontier.push(c);
-                }
-                // place packed child
-                assignSlot(c, nextcol, nextrow);
-                // prepare for next iteration
-                mincols = 0;            // reset mincols
-                nextrow += c0.rowspan;  // bump up nextrow
-            }
-        }
-        
         const getIndice = function(axis) {
             const f2i = {};
             for (var i,f in axis.frontiers)
@@ -525,7 +460,9 @@
             byRow.regions = new Regions();
             byRow.frontiers = [];
             // pack!
-            userows ? packByRow() : packByCol();
+            if (userows)
+                packAxis("row", "rowspan", "v_row", "col", "colspan", "v_col");
+            else packAxis("col", "colspan", "v_col", "row", "rowspan", 
"v_row");
             getIndice(byCol);
             getIndice(byRow);
             pack_children = false;

Modified: 
branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve1.t
===================================================================
--- branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve1.t     
2013-11-29 16:03:37 UTC (rev 4607)
+++ branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve1.t     
2013-12-03 01:52:09 UTC (rev 4608)
@@ -3,24 +3,28 @@
         <grid id="grid" cols="6" width="766" height="250">
             <ui:box colspan="1" minwidth="35" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="59" hshrink="false" minheight="26" 
vshrink="true" />
-            <ui:box colspan="1" minwidth="40" hshrink="true"  
minheight="26"vshrink="true" />
+            <ui:box colspan="1" minwidth="40" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="128" hshrink="true" minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="41" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="73" hshrink="true"  minheight="26" 
vshrink="true" />
+            
             <ui:box colspan="1" minwidth="51" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="59" hshrink="false" minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="67" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="3" minwidth="59" hshrink="false" minheight="26" 
vshrink="true" />
+            
             <ui:box colspan="1" minwidth="60" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="17" hshrink="false" minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="41" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="17" hshrink="false" minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="36" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="17" hshrink="false" minheight="26" 
vshrink="true" />
+            
             <ui:box colspan="1" minwidth="38" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="39" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="1" minwidth="0" hshrink="true"   minheight="26" 
vshrink="true" />
             <ui:box colspan="3" minwidth="0" hshrink="true"   minheight="26" 
vshrink="true" />
+            
             <ui:box colspan="1" minwidth="45" hshrink="true"  minheight="26" 
vshrink="true" />
             <ui:box colspan="5" minwidth="57" hshrink="false" minheight="26" 
vshrink="false" />
         </grid>

Modified: 
branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve2.t
===================================================================
--- branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve2.t     
2013-11-29 16:03:37 UTC (rev 4607)
+++ branches/vexi3/org.vexi-vexi.widgets/src_test/test/layout/grid/solve2.t     
2013-12-03 01:52:09 UTC (rev 4608)
@@ -34,7 +34,8 @@
             
             <ui:box text="9" />
             <wi:textfield text="9" />
-            <ui:box text="10" rowspan="4" />
+            
+            <ui:box text="10" rowspan="4" fill="red" />
             <wi:textarea text="10" colspan="3" rowspan="4" />
             
             <ui:box text="11" />

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to