Revision: 3832 http://vexi.svn.sourceforge.net/vexi/?rev=3832&view=rev Author: clrg Date: 2010-04-08 02:55:58 +0000 (Thu, 08 Apr 2010)
Log Message: ----------- Smarten up grid code + fix broken grids caused by colspan/rowspan as strings Modified Paths: -------------- trunk/widgets/org.vexi.widgets/src/org/vexi/lib/layout/grid.t Modified: trunk/widgets/org.vexi.widgets/src/org/vexi/lib/layout/grid.t =================================================================== --- trunk/widgets/org.vexi.widgets/src/org/vexi/lib/layout/grid.t 2010-04-07 16:39:52 UTC (rev 3831) +++ trunk/widgets/org.vexi.widgets/src/org/vexi/lib/layout/grid.t 2010-04-08 02:55:58 UTC (rev 3832) @@ -60,7 +60,9 @@ } var place = function(findwidths, findheights) { - if (!activegrid or !numcols or !numrows) return; + if (!activegrid or !numcols or !numrows) { + return; + } // honor min/max sizes for boxes in order of region var n = $content.numchildren; var c, c0; @@ -90,8 +92,8 @@ c0 = c[0]; r1 = rindmap[c0.v_col]; r2 = rindmap[c0.v_col+c0.colspan]; - // first to affect this region if (r2 == null) { + // first to affect this region r2 = regmark; regions[r2] = c0.v_col+c0.colspan; rindmap[regions[r2]] = r2; @@ -101,22 +103,28 @@ content += minsizes[regmark-1]; regmark++; } - // affect single region if (r2-r1 == 1) { + // affect single region minsizes[r2] = max(c0.contentwidth, minsizes[r2]); maxsizes[r2] = max((c0.hshrink ? c0.contentwidth : c0.maxwidth), maxsizes[r2]); - // affect multiple regions } else { + // affect multiple regions mindim = c0.contentwidth; maxdim = c0.hshrink ? c0.contentwidth : c0.maxwidth; // work out the minimum size of this box's region // the box affects c.v_col+1 -> c.v_col+c.colspan - for (var r=r1+1; r2>r; r++) mindim -= minsizes[r]; + for (var r=r1+1; r2>r; r++) { + mindim -= minsizes[r]; + } minsizes[r2] = max(mindim, minsizes[r2]); // work out the maximum size of this box's region for (var r=r1+1; r2>r; r++) { - if (maxdim > maxsizes[r]) maxdim -= maxsizes[r]; - else { maxdim = 0; break; } + if (maxdim > maxsizes[r]) { + maxdim -= maxsizes[r]; + } else { + maxdim = 0; + break; + } } maxsizes[r2] = max(maxdim, maxsizes[r2]); } @@ -140,7 +148,7 @@ // reset markers r1 = 0; mincols=0; maxcols=0; // calculate size for each region based on targetColumnSize - for(var r=1; regmark>r; r++) { + for (var r=1; regmark>r; r++) { r2 = regions[r]; // honor maxwidths then minwidths diff = max(minsizes[r], min(maxsizes[r], targetColumnSize * (r2-r1))); @@ -152,21 +160,30 @@ } // our current size size = sizes[regmark-1]; - // break if we were close to the target - if (0.5 > size-target and size-target >= -0.5) break; - // not at the target size, adjust accordingly + if (0.5 > size-target and size-target >= -0.5) { + // break if we were close to the target + break; + } if (size > target) { - // no cols to be further decreased in size - if (mincols == 0) break; + // not at the target size, adjust accordingly + if (mincols == 0) { + // no cols to be further decreased in size + break; + } // else adjust targetColumnSize according to target-total deficit targetColumnSize += ((target-size) / mincols); } else { - // no cols to be further increased in size - if (maxcols == 0) break; + if (maxcols == 0) { + // no cols to be further increased in size + break; + } // adjust targetColumnSize according to target-total deficit targetColumnSize += ((target-size) / maxcols); } - if (i==99) vexi.log.warn("failed to solve grid"); + if (i>=99) { + // infinite loop prevention + vexi.log.warn("failed to solve grid"); + } } // place our boxes @@ -180,7 +197,9 @@ c.width = c0.hshrink ? c0.contentwidth : min(c0.maxwidth, r2-r1); c.x = (c.width == r2-r1) ? r1 : fromHAlign(c0.align, r1, r2-r1-c.width); c = colregions.next(); - if (c) c0 = c[0]; + if (c) { + c0 = c[0]; + } } } @@ -220,22 +239,28 @@ content += minsizes[regmark-1]; regmark++; } - // affect single region if (r2-r1 == 1) { + // affect single region minsizes[r2] = max(c0.contentheight, minsizes[r2]); maxsizes[r2] = max((c0.vshrink ? c0.contentheight : c0.maxheight), maxsizes[r2]); - // affect multiple regions } else { + // affect multiple regions mindim = c0.contentheight; maxdim = c0.vshrink ? c0.contentheight : c0.maxheight; // work out the minimum size of this box's region // the box affects c.v_col+1 -> c.v_col+c.colspan - for (var r=r1+1; r2>r; r++) mindim -= minsizes[r]; + for (var r=r1+1; r2>r; r++) { + mindim -= minsizes[r]; + } minsizes[r2] = max(mindim, minsizes[r2]); // work out the maximum size of this box's region for (var r=r1+1; r2>r; r++) { - if (maxdim > maxsizes[r]) maxdim -= maxsizes[r]; - else { maxdim = 0; break; } + if (maxdim > maxsizes[r]) { + maxdim -= maxsizes[r]; + } else { + maxdim = 0; + break; + } } maxsizes[r2] = max(maxdim, maxsizes[r2]); } @@ -259,7 +284,7 @@ // reset markers r1 = 0; minrows=0; maxrows=0; // calculate size for each region based on targetRowSize - for(var r=1; regmark>r; r++) { + for (var r=1; regmark>r; r++) { r2 = regions[r]; // honor maxwidths then minwidths diff = max(minsizes[r], min(maxsizes[r], targetRowSize * (r2-r1))); @@ -271,21 +296,30 @@ } // our current size size = sizes[regmark-1]; - // break if we were close to the target - if (0.5 > size-target and size-target >= -0.5) break; - // not at the target size, adjust accordingly + if (0.5 > size-target and size-target >= -0.5) { + // break if we were close to the target + break; + } if (size > target) { - // no rows to be further decreased in size - if (minrows == 0) break; + // not at the target size, adjust accordingly + if (minrows == 0) { + // no rows to be further decreased in size + break; + } // else adjust targetRowSize according to target-total deficit targetRowSize += ((target-size) / minrows); } else { - // no rows to be further increased in size - if (maxrows == 0) break; + if (maxrows == 0) { + // no rows to be further increased in size + break; + } // adjust targetRowSize according to target-total deficit targetRowSize += ((target-size) / maxrows); } - if (i==99) vexi.log.warn("failed to solve grid"); + if (i>=99) { + // infinite loop prevention + vexi.log.warn("failed to solve grid"); + } } // place our boxes @@ -299,7 +333,9 @@ c.height = c0.vshrink ? c0.contentheight : min(c0.maxheight, r2-r1); c.y = (c.height == r2-r1) ? r1 : fromVAlign(c0.align, r1, r2-r1-c.height); c = rowregions.next(); - if (c) c0 = c[0]; + if (c) { + c0 = c[0]; + } } } @@ -330,21 +366,21 @@ /** assign child c to the pack slot specific by col,row */ var assignSlot = function(c, col, row) { var c0 = c[0]; - // col-related assignments if (!colregions.contains(c) or c0.v_col != col) { - c0.v_col = col; - colregions.insert(c, c0.v_col+c0.colspan); + // col-related assignments + c0.v_col = col; + colregions.insert(c, c0.v_col+c0.colspan); } - // row-related assignments if (!rowregions.contains(c) or c0.v_row != row) { - c0.v_row = row; - rowregions.insert(c, c0.v_row+c0.rowspan); + // row-related assignments + c0.v_row = row; + rowregions.insert(c, c0.v_row+c0.rowspan); } } /** pack by column first, expanding rows as required */ var packByCol = function() { - var frontier = .vector(vexi.box); + var frontier = new .vector(); var fullpass = true; var nextcol = 0; // the next available col var nextrow = 0; // the next available row @@ -355,11 +391,18 @@ for (var j=0; n>j; j++) { c = $content[j]; c0 = c[0]; - // disregard hidden children - if (!c0.display) { c.display = false; continue; } - else c.display = true; - // if we don't fit on the row, jump to the next - if (nextcol!=0 and nextcol+c0.colspan > numcols) { nextcol=0; nextrow++; } + if (!c0.display) { + // disregard hidden children + c.display = false; + continue; + } else { + c.display = true; + } + if (nextcol!=0 and nextcol+c0.colspan > numcols) { + // if we don't fit on the row, jump to the next + nextcol=0; + nextrow++; + } // check to see if we are making a full pass at the row fullpass = nextcol==0; // work through frontier boxes until a suitable position is found @@ -367,43 +410,61 @@ f = frontier.first; while (f != null) { f0 = f[0]; - // reduce frontier by removing boxes not affecting the frontier row if (nextrow >= f0.v_row+f0.rowspan) { + // reduce frontier by removing boxes not affecting the frontier row f0 = frontier.after(f); frontier.remove(f); f = f0; continue; } - // frontier not accomdating current child, look further if (f0.v_col+f0.colspan > nextcol and nextcol+c0.colspan > f0.v_col) { + // frontier not accomdating current child, look further + // establish next available col nextcol = f0.v_col+f0.colspan; // establish next available row minrows = (minrows == 0) ? f0.v_row+f0.rowspan : min(minrows, f0.v_row+f0.rowspan); - // c will not fit on nextrow + if (nextcol+c0.colspan > numcols) { - // if not a full pass, try next immediate row - if (!fullpass) { nextrow++; nextcol=0; minrows=0; } - // try c on next available row - else { nextcol=0; nextrow=minrows; minrows=0; } + // c will not fit on nextrow + if (!fullpass) { + // if not a full pass, try next immediate row + nextrow++; + nextcol=0; + minrows=0; + } else { + // try c on next available row + nextcol=0; + nextrow=minrows; + minrows=0; + } // try frontier again continue PACKME; } - // fit between previous frontier and this frontier - } else if (f0.v_col >= nextcol+c0.colspan) break PACKME; + } else if (f0.v_col >= nextcol+c0.colspan) { + // fit between previous frontier and this frontier + break PACKME; + } // next frontier f = frontier.after(f); } - // fits in the col after frontier - if (numcols >= nextcol+c0.colspan) break; + if (numcols >= nextcol+c0.colspan) { + // fits in the col after frontier + break; + } } - // add to frontier if we affect the frontier if (c0.rowspan>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); + if (f) { + frontier.insert(c, f); + } else { + frontier.unshift(c); + } + } else { + frontier.push(c); + } } // place packed child assignSlot(c, nextcol, nextrow); @@ -419,7 +480,7 @@ /** pack by row first - for comments see packByCol **/ var packByRow = function() { - var frontier = .vector(vexi.box); + var frontier = new .vector(); var fullpass = true; var nextrow = 0; // the next available row var nextcol = 0; // the next available col @@ -431,10 +492,17 @@ c = $content[j]; c0 = c[0]; // disregard hidden children - if (!c0.display) { c.display = false; continue; } - else c.display = true; - // if we don't fit on the col, jump to the next - if (nextrow!=0 and nextrow+c0.rowspan > numrows) { nextrow=0; nextcol++; } + if (!c0.display) { + c.display = false; + continue; + } else { + c.display = true; + } + if (nextrow!=0 and nextrow+c0.rowspan > numrows) { + // 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 fullpass = nextrow==0; @@ -443,42 +511,54 @@ f = frontier.first; while (f != null) { f0 = f[0]; - // reduce frontier by removing boxes not affecting the frontier col 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; } - // frontier not accomdating current child, look further 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); - // c will not fit on nextcol + if (nextrow+c0.rowspan > numrows) { - // if not a full pass, try next immediate col - if (!fullpass) { nextrow++; nextcol=0; minrows=0; } - // try c on next available col - else { nextrow=0; nextcol=mincols; mincols=0; } + // 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; } - // fit between previous frontier and this frontier - } else if (f0.v_row >= nextrow+c0.rowspan) break PACKME; + } else if (f0.v_row >= nextrow+c0.rowspan) { + // fit between previous frontier and this frontier + break PACKME; + } // next frontier f = frontier.after(f); } - // fits on this row after frontier - if (numrows >= nextrow+c0.rowspan) break; + if (numrows >= nextrow+c0.rowspan) { + // fits on this row after frontier + break; + } } - // add to frontier if we affect the frontier 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); + if (f) { + frontier.insert(c, f); + } else { + frontier.unshift(c); + } } else frontier.push(c); } // place packed child @@ -499,7 +579,9 @@ /** ambiguous function to invoke specific packing function */ var pack = function() { - if (!activegrid) return; + if (!activegrid) { + return; + } userows ? packByRow() : packByCol(); pack_children = false; } @@ -510,13 +592,17 @@ * new children to or removing children from a grid */ var schedule = function() { - if (scheduled) return; + if (scheduled) { + return; + } scheduled = true; vexi.thread = function() { scheduled = false; - if (pack_children) pack(); - else if (place_width or place_height) + if (pack_children) { + pack(); + } else if (place_width or place_height) { place(place_width, place_height); + } } } @@ -525,6 +611,10 @@ schedule(); } + var checkInt = function(v) { + cascade = typeof(v)=="number" ? v : vexi.string.parseInt(v); + } + var invokePack = function(v) { if (v == trapee[trapname]) return; cascade = v; @@ -555,7 +645,9 @@ cascade = v; if (v == null) { var i = $content.indexof(trapee); - if (i==-1) return; + if (i==-1) { + return; + } $content[i] = null; colregions.remove(trapee); rowregions.remove(trapee); @@ -565,19 +657,18 @@ /** set up children so the grid can react to them */ thisbox.Children ++= function(v) { - // adding a child if (v) { - // gridproxy - insert contents as children if (v.v_gridproxy) { + // insert contents as children var c = v.v_gridcontent; var n = c.numchildren; - for (var i=0; n>i; i++) - thisbox[numchildren] = c[0]; + for (var i=0; n>i; i++) { + thisbox.add(c[0]); + } return; } - // initialize colspan/rowspan properties - if (v.colspan == null) v.colspan = 1; - if (v.rowspan == null) v.rowspan = 1; + // adding a child + // trap assignment v.contentwidth ++= invokePlaceWidth; v.contentheight ++= invokePlaceHeight; @@ -586,6 +677,11 @@ v.display ++= invokePack; v.colspan ++= invokePack; v.rowspan ++= invokePack; + v.colspan ++= checkInt; + v.rowspan ++= checkInt; + // initialize span properties or check they are ints + v.colspan = v.colspan==null ? 1 : v.colspan; + v.rowspan = v.rowspan==null ? 1 : v.rowspan; // we wrap them in an outer box which we can manipulate var b = v.v_gridbox; if (b == null) { @@ -597,12 +693,14 @@ // can kick in - these properties will be set properly by place() b.height = 0; b.width = 0; - } else b[0] = v; + } else { + b[0] = v; + } // insert gridbox which contains child $content[trapname] = b; - // removing a child } else { + // removing a child var c = null; var b = $content[trapname]; if (b) { @@ -610,7 +708,9 @@ colregions.remove(b); rowregions.remove(b); c = b[0]; - } else throw "attempt to get null child from a box"; + } else { + throw "attempt to get null child from a box"; + } if (c) { c.contentwidth --= invokePlaceWidth; c.contentheight --= invokePlaceHeight; @@ -618,8 +718,12 @@ c.maxheight --= invokePlaceHeight; c.colspan --= invokePack; c.rowspan --= invokePack; + v.colspan --= checkInt; + v.rowspan --= checkInt; c.v_gridbox = null; - } else throw "should not happen"; + } else { + throw "should not happen"; + } // finish removal $content[trapname] = null; } @@ -628,13 +732,19 @@ } /** return the actual child instead of it's grid wrapper */ - thisbox.Children ++= function() { return $content[trapname] ? $content[trapname][0] : null; } + thisbox.Children ++= function() { + var c = $content.trapname; + return c ? c[0] : null; + } thisbox.numchildren ++= function() { return $content.numchildren; } /** return the grid wrapper index as grid.indexof(child) == -1 */ var getindexof = function(v) { - if (v==null) throw "Called indexof() with null child"; - return v.v_gridbox ? $content.indexof(v.v_gridbox) : -1; + if (v==null) { + throw "Called indexof() with null child"; + } + var v0 = v.v_gridbox; + return v0 ? $content.indexof(v0) : -1; } thisbox.indexof ++= function() { return getindexof; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn