Revision: 2235 http://vexi.svn.sourceforge.net/vexi/?rev=2235&view=rev Author: clrg Date: 2007-09-17 09:15:44 -0700 (Mon, 17 Sep 2007)
Log Message: ----------- Fix dynamic grid packing and always place after packing Modified Paths: -------------- trunk/widgets/org.vexi.widgets/src/vexi/layout/grid.t trunk/widgets/org.vexi.widgets/src_vunit/test/layout/grid_columns.t Modified: trunk/widgets/org.vexi.widgets/src/vexi/layout/grid.t =================================================================== --- trunk/widgets/org.vexi.widgets/src/vexi/layout/grid.t 2007-09-17 14:54:41 UTC (rev 2234) +++ trunk/widgets/org.vexi.widgets/src/vexi/layout/grid.t 2007-09-17 16:15:44 UTC (rev 2235) @@ -38,154 +38,6 @@ var rowregions = .orderedlist(vexi.box); var rowregrefs = {}; - /* - * 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 - * children down the number of rows and accomodate children by - * adding extra columns. - */ - - /** 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 (c0.col != col) { - c0.col = col; - colregions.insert(c, c0.col+c0.colspan); - } - // row-related assignments - if (c0.row != row) { - c0.row = row; - rowregions.insert(c, c0.row+c0.rowspan); - } - } - - /** pack by column first, expanding rows as required */ - var packByCol = function() { - if (!activegrid) return; - var frontier = .vector(vexi.box); - 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 n = numchildren; - var c, c0; var f, f0; - // assign col/row values to packed children - for (var j=0; n>j; j++) { - c = $content[j]; - c0 = c[0]; - // disregard hidden children - if (!c0.display) { c.display = false; continue; } - // if we don't fit on the row, jump to the next - if (nextcol!=0 and nextcol+c0.colspan > numcols) { nextcol=0; nextrow++; } - - // work through frontier boxes until a suitable position is found - PACKME: while (frontier.length>0) { - f = frontier.first; - while (f != null) { - f0 = f[0]; - // reduce frontier by removing boxes not affecting the frontier row - if (nextrow >= f0.row+f0.rowspan) { - f0 = frontier.after(f); - frontier.remove(f); - f = f0; - continue; - // frontier not accomdating current child, look further - } else if (nextcol+c0.colspan > f0.col and f0.col+f0.colspan > nextcol) { - // establish next available col - nextcol = f0.col+f0.colspan; - // establish next available row - if (minrows == 0) minrows = f0.row+f0.rowspan; - else minrows = min(minrows, f0.row+f0.rowspan); - // c will not fit on nextrow, try c on next available row - if (nextcol+c0.colspan > numcols) { nextcol=0; nextrow=minrows; minrows=0; break; } - // fit between previous frontier and this frontier - } else if (f0.col > nextcol+c0.colspan) break PACKME; - // next frontier - f = frontier.after(f); - } - if (numcols >= nextcol+c0.colspan) break; - } - // add to frontier if we affect the frontier - if (c0.rowspan>1) { - f = frontier.before(f); - frontier.insert(c, f); - } - // place packed child - assignSlot(c, nextcol, nextrow); - // prepare for next iteration - minrows = 0; // reset minrows - nextcol += c0.colspan; // bump up nextcol - // update the number of rows - numrows = max(numrows, c0.row+c0.rowspan); - } - } - - /** pack by row first - for comments see packByCol **/ - var packByRow = function() { - if (!activegrid) return; - var frontier = .vector(vexi.box); - 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 n = numchildren; - var c, c0; var f, f0; - // assign row/col values to packed children - for (var j=0; n>j; j++) { - c = $content[j]; - c0 = c[0]; - // disregard hidden children - if (!c0.display) { c.display = false; continue; } - // if we don't fit on the col, jump to the next - if (nextrow!=0 and nextrow+c0.rowspan > numrows) { nextrow=0; nextcol++; } - - // work through frontier boxes until a suitable position is found - PACKME: while (frontier.length>0) { - f = frontier.first; - while (f != null) { - f0 = f[0]; - // reduce frontier by removing boxes not affecting the frontier col - if (nextcol >= f0.col+f0.colspan) { - f0 = frontier.after(f); - frontier.remove(f); - f = f0; - continue; - // frontier not accomdating current child, look further - } else if (nextrow+c0.rowspan > f0.row and f0.row+f0.rowspan > nextrow) { - // establish next available row - nextrow = f0.row+f0.rowspan; - // establish next available col - if (mincols == 0) mincols = f0.col+f0.colspan; - else mincols = min(mincols, f0.col+f0.colspan); - // c will not fit on nextcol, try c on next available col - if (nextrow+c0.rowspan > numrows) { nextrow=0; nextcol=mincols; mincols=0; break; } - // fit between previous frontier and this frontier - } else if (f0.row > nextrow+c0.rowspan) break PACKME; - // next frontier - f = frontier.after(f); - } - if (numrows >= nextrow+c0.rowspan) break; - } - // add to frontier if we affect the frontier - if (c0.colspan>1) { - f = frontier.before(f); - frontier.insert(c, f); - } - // place packed child - assignSlot(c, nextrow, nextcol); - // prepare for next iteration - mincols = 0; // reset mincols - nextrow += c0.rowspan; // bump up nextrow - // update the number of cols - numrows = max(numrows, c0.col+c0.colspan); - } - } - - /** ambiguous function to invoke specific packing function */ - var pack = function() { userows ? packByRow() : packByCol(); } - /* * PLACING * @@ -316,7 +168,9 @@ while (c and regions[r] == c0.col+c0.colspan) { r1 = sizes[rindmap[c0.col]]; r2 = sizes[r]; + //vexi.log.info(c0.name+" colinf: "+r+", "+regions[r]+", "+sizes[r]+", "+r1+", "+r2); c.width = c0.hshrink ? c0.contentwidth : min(c0.maxwidth, r2-r1); + //vexi.log.info(c0.name+" width: "+c.width); c.x = (c.width == r2-r1) ? r1 : fromHAlign(c0.align, r1, r2-r1-c.width); c = colregions.next(); if (c) c0 = c[0]; @@ -425,7 +279,9 @@ while (c and regions[r] == c0.row+c0.rowspan) { r1 = sizes[rindmap[c0.row]]; r2 = sizes[r]; + //vexi.log.info(c0.name+" rowinf: "+r+", "+regions[r]+", "+sizes[r]+", "+r1+", "+r2); c.height = c0.vshrink ? c0.contentheight : min(c0.maxheight, r2-r1); + //vexi.log.info(c0.name+" height: "+c.height); c.y = (c.height == r2-r1) ? r1 : fromVAlign(c0.align, r1, r2-r1-c.height); c = rowregions.next(); if (c) c0 = c[0]; @@ -440,11 +296,164 @@ } } - var compute = function() { - pack(); + /* + * 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 + * children down the number of rows and accomodate children by + * adding extra columns. + */ + + /** 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 (c0.col != col) { + c0.col = col; + colregions.insert(c, c0.col+c0.colspan); + } + // row-related assignments + if (c0.row != row) { + c0.row = row; + rowregions.insert(c, c0.row+c0.rowspan); + } + } + + /** pack by column first, expanding rows as required */ + var packByCol = function() { + if (!activegrid) return; + var frontier = .vector(vexi.box); + 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 n = numchildren; + var c, c0; var f, f0; + // assign col/row values to packed children + 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++; } + + // work through frontier boxes until a suitable position is found + PACKME: while (frontier.length>0) { + f = frontier.first; + while (f != null) { + f0 = f[0]; + // reduce frontier by removing boxes not affecting the frontier row + if (nextrow >= f0.row+f0.rowspan) { + f0 = frontier.after(f); + frontier.remove(f); + f = f0; + continue; + // frontier not accomdating current child, look further + } else if (nextcol+c0.colspan > f0.col and f0.col+f0.colspan > nextcol) { + // establish next available col + nextcol = f0.col+f0.colspan; + // establish next available row + if (minrows == 0) minrows = f0.row+f0.rowspan; + else minrows = min(minrows, f0.row+f0.rowspan); + // c will not fit on nextrow, try c on next available row + if (nextcol+c0.colspan > numcols) { nextcol=0; nextrow=minrows; minrows=0; break; } + // fit between previous frontier and this frontier + } else if (f0.col > nextcol+c0.colspan) break PACKME; + // next frontier + f = frontier.after(f); + } + if (numcols >= nextcol+c0.colspan) break; + } + // add to frontier if we affect the frontier + if (c0.rowspan>1) { + f = frontier.before(f); + frontier.insert(c, f); + } + // place packed child + assignSlot(c, nextcol, nextrow); + // prepare for next iteration + minrows = 0; // reset minrows + nextcol += c0.colspan; // bump up nextcol + // update the number of rows + numrows = max(numrows, c0.row+c0.rowspan); + } + // always want to do this after packing place(true, true); } + /** pack by row first - for comments see packByCol **/ + var packByRow = function() { + if (!activegrid) return; + var frontier = .vector(vexi.box); + 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 n = numchildren; + var c, c0; var f, f0; + // assign row/col values to packed children + 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 col, jump to the next + if (nextrow!=0 and nextrow+c0.rowspan > numrows) { nextrow=0; nextcol++; } + + // work through frontier boxes until a suitable position is found + PACKME: while (frontier.length>0) { + f = frontier.first; + while (f != null) { + f0 = f[0]; + // reduce frontier by removing boxes not affecting the frontier col + if (nextcol >= f0.col+f0.colspan) { + f0 = frontier.after(f); + frontier.remove(f); + f = f0; + continue; + // frontier not accomdating current child, look further + } else if (nextrow+c0.rowspan > f0.row and f0.row+f0.rowspan > nextrow) { + // establish next available row + nextrow = f0.row+f0.rowspan; + // establish next available col + if (mincols == 0) mincols = f0.col+f0.colspan; + else mincols = min(mincols, f0.col+f0.colspan); + // c will not fit on nextcol, try c on next available col + if (nextrow+c0.rowspan > numrows) { nextrow=0; nextcol=mincols; mincols=0; break; } + // fit between previous frontier and this frontier + } else if (f0.row > nextrow+c0.rowspan) break PACKME; + // next frontier + f = frontier.after(f); + } + if (numrows >= nextrow+c0.rowspan) break; + } + // add to frontier if we affect the frontier + if (c0.colspan>1) { + f = frontier.before(f); + frontier.insert(c, f); + } + // place packed child + assignSlot(c, nextrow, nextcol); + // prepare for next iteration + mincols = 0; // reset mincols + nextrow += c0.rowspan; // bump up nextrow + // update the number of cols + numrows = max(numrows, c0.col+c0.colspan); + } + // always want to do this after packing + place(true, true); + } + + /** ambiguous function to invoke specific packing function */ + var pack = function() { userows ? packByRow() : packByCol(); } + + /* + * INTERNAL TRAP FUNCTIONS + */ + var invokePack = function(v) { if (v == trapee[trapname]) return; cascade = v; @@ -496,15 +505,14 @@ // let the gc handle outer box cascade = v; } - compute(); + pack(); } /** used to mass-modify grid contents without invoking computation */ thisbox.lockgrid ++= function(v) { - activegrid = v; - if (v) { + activegrid = !v; + if (!v) { pack(); - compute(); return; } } @@ -516,22 +524,24 @@ thisbox.height ++= invokePlaceHeight; thisbox.cols ++= function(v) { + var diff = (v != numcols); if (v != 0) { numcols = v; numrows = 0; userows = false; + if (diff) pack(); } - compute(); return; } thisbox.rows ++= function(v) { + var diff = (v != numrows); if (v != 0) { numcols = 0; numrows = v; userows = true; + if (diff) pack(); } - compute(); return; } @@ -541,7 +551,7 @@ thisbox.visible ++= function(v) { cascade = v; activegrid = v; - if (v) compute(); + if (v) pack(); } </ui:box> Modified: trunk/widgets/org.vexi.widgets/src_vunit/test/layout/grid_columns.t =================================================================== --- trunk/widgets/org.vexi.widgets/src_vunit/test/layout/grid_columns.t 2007-09-17 14:54:41 UTC (rev 2234) +++ trunk/widgets/org.vexi.widgets/src_vunit/test/layout/grid_columns.t 2007-09-17 16:15:44 UTC (rev 2235) @@ -86,12 +86,19 @@ assertHeight(100, b[5]); b[6].display = true; b[7].display = true; + b.forcereflow(); assertSlot(0,3, b[6]); assertSlot(0,4, b[7]); assertWidth(100, b[6]); assertWidth(100, b[7]); + assertHeight(50, b[0]); + assertHeight(50, b[1]); + assertHeight(50, b[2]); + assertHeight(50, b[3]); + assertHeight(50, b[4]); + assertHeight(50, b[5]); assertHeight(50, b[6]); - assertHeight(50, b[7]); + assertHeight(100, b[7]); } }; return vunit..newQuickSuite("vexi.layout.grid Packing Columns", suite); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn