📄 tableresizepolicy.js
字号:
// if this is the first item to specify a pixel size, or is larger than any // previous specified size or minimum size, it becomes the new minimum if (rowMinHeight == null || itemHeight > rowMinHeight) { rowMinHeight = itemHeight; } // if this item specifies a pixel size larger than a previously specified // max, raise the max height for the row as a whole if (itemHeight > rowMaxHeight) rowMaxHeight = itemHeight; // if the itemHeight is a string (a relative size) } else if (isc.isA.String(itemHeight)) { // if height is "*" or "2*" if (itemHeight.contains("*")) { item._isVariableHeight = true; // get the starCount as a number // NOTE: if the item takes up more than one row, split it evenly across // its rows var itemStarCount = (itemHeight == "*" ? 1 : parseFloat(itemHeight)) / itemRows; if (logDebug) this.logWarn("item: " + item + " has star size: " + itemStarCount); rowStarCount = Math.max(rowStarCount, itemStarCount); // else if height is a percentage } else { item._isVariableHeight = true; // get the percentage as a number // NOTE: if the item takes up more than one row, split it evenly across // its rows var itemPercent = parseFloat(itemHeight) / itemRows; if (logDebug) this.logWarn("item: " + item + " has percent size: " + itemPercent); // and remember it if it's greater than the max percent already seen in // this row if (itemPercent > rowMaxPercent) rowMaxPercent = itemPercent; } // check for minHeight / maxHeight settings on flexible-sized items // the row must be as big as the minHeight of the item if (item.minHeight > rowMinHeight) { rowMinHeight = item.minHeight; } // NOTE: minimums should win out over maximums // allow an item's minHeight to win out over another item's previously // specified maxHeight if (item.minHeight > rowMaxHeight) { rowMaxHeight = item.minHeight; } // lower row maxHeight only to the largest previously specified // item.minHeight (rowMinHeight) if (item.maxHeight < rowMaxHeight && rowMinHeight < item.maxHeight) { rowMaxHeight = item.maxHeight } } // remember the characteristics of this row // if a percentage or star was found, remember all the values if (rowMaxPercent > 0 || rowStarCount > 0) { // no one set a pixel size or minHeight. Default to 0 if (rowMinHeight == null) rowMinHeight = 0; rowHeights[r] = [rowMinHeight, rowMaxHeight, rowMaxPercent, rowStarCount]; } else { if (rowMinHeight == null) { // there were no specified sizes for the row (pixel, '*' or percent) rowMinHeight = items._defaultRowHeight || 22; } rowHeights[r] = rowMinHeight; } } } } // remember the rowHeights in the items items.rowHeights = rowHeights; if (logInfo) this.logInfo("\ntotalWidth: " + totalWidth + ", totalHeight: " + totalHeight + "\nspecified sizes:\n" + "cols:" + this.echoAll(items.colWidths) + ", rows: " + this.echoAll(items.rowHeights), "tablePolicy"); // get real row and column sizes items._colWidths = colWidths = isc.Canvas.stretchResizeList(items.colWidths, totalWidth); items._rowHeights = rowHeights = isc.Canvas.stretchResizeList(items.rowHeights, totalHeight); if (logInfo) this.logInfo("\nderived sizes:\n" + "cols:" + this.echoAll(items._colWidths) + ", rows: " + this.echoAll(items._rowHeights), "tablePolicy"); // we have widths and heights for each column and row. Now apply those sizes to the items, // which may span multiple columns or rows // NOTE: we currently only support "*" sizes, not percents for (itemNum = 0; itemNum < items.length; itemNum++) { item = items[itemNum]; if (!item.visible) continue; var isACanvas = isc.isA.Canvas(item), // Note - use getWidth() / getHeight() on canvii, to allow us to store height / width // with different (internal) property names if we choose to do so. width = isACanvas ? item.getWidth() : item.width, height = isACanvas ? item.getHeight() : item.getCellHeight(overflowedAsFixed), orientation = item.getTitleOrientation(), placement = item._tablePlacement, // We need the derived title width in order to manage title cell clipping properly // in form items. If we're not showing a title, of course this will be zero. titleWidth = 0; if (item.showTitle) { if (orientation == isc.Canvas.LEFT) { titleWidth = colWidths[placement[0]]; } else { titleWidth = colWidths[placement[2]]; } } // account for variable width items. NOTE: we don't support percent widths on items if (width == "*") { width = 0; var skipBefore = (item.showTitle && orientation == isc.Canvas.LEFT) ? 1 : 0, skipAfter = (item.showTitle && orientation == isc.Canvas.RIGHT) ? 1 : 0, startCol = placement[0], endCol = placement[2]; for (var c = startCol + skipBefore; c < endCol - skipAfter; c++) { width += colWidths[c]; } } // account for variable height items if (item._isVariableHeight) { height = 0; var startRow = placement[1], endRow = placement[3]; // NOTE: don't need logic for extra cells for titles, because extra cells aren't // added for top or bottom-oriented titles for (var c = startRow; c < endRow; c++) { height += rowHeights[c]; } } // remember the width and height of the item item._size = [width, height]; // Remember the width of the item title item._titleWidth = titleWidth }},// This method should determine whether// - tableResizePolicy has been run on this table already// - any items visibility have changed since the policy was run// - any items have been moved within the items array (or items removed / new items introduced)_tableResizePolicyIsValid : function (items) { if (!items._rowTable) return false; return true;},// Helper method to mark an already run policy as invalid.invalidateTableResizePolicy : function (items) { delete items._rowTable; delete items._rowHeights; delete items._colWidths;},//> @method Canvas.stretchResizeList() (A)// Given a list of inputs sizes as:// a number // or// [minSize, maxSize, maxPercent, starCount]// and a totalSize, figure out the size of the dynamically sized items// according to the totalSize.//// You can use percentages or fixed sizes to go beyond the totalSize//// @group drawing// @param inputSizes (array) array of sizes (see above)// @param totalSize (number) total sizes for the //// @return (number[]) output sizes (all numbers)//<stretchResizeList : function (inputSizes, totalSize) { var totalPercent = 0, // amount "%" items amount to starCount = 0, // number of "*" star items totalFixed = 0, // total space taken up by fixed-size items outputSizes = inputSizes.duplicate(); for (var i = 0; i < inputSizes.length; i++) { var size = outputSizes[i]; if (isc.isA.Number(size)) { // fixed size item size = Math.max(size,1); // assure at least 1 totalFixed += size; outputSizes[i] = size; } else { // variable (% / * / both) sized item var rowPercent = size[2], rowStarCount = size[3] ; // if a percent without a "*" if (rowStarCount == 0) { // percentage -- add it to the percentage total totalPercent += rowPercent; } // tracked total amount of "*"s starCount += rowStarCount; } } // at this point, // - totalFixed is the total of the fixed, absolute sizes // - totalPercent is the total percentage numbers (that aren't stars) // - starCount is the total number of stars across all rows (even if those rows also have // percents specified) // - "stars" are translated to percents, sharing all remaining percent points (of 100) // not allocated to specified percent sizes // - stars and percents share all space not allocated to static numbers // - if there are any percents or stars, all space is always filled if (starCount) { var starPercent = 0; if (totalPercent < 100) { // star sized items share the remaining percent size starPercent = (100 - totalPercent) / starCount; } // assign a percentage to each star item // if a row has both a star and a percentage, keep the larger item for (var r = 0; r < inputSizes.length; r++) { var size = outputSizes[r]; if (isc.isA.Number(size)) continue; // skip fixed size items var rowPercent = size[2], rowStarCount = size[3], rowStarPercent = rowStarCount * starPercent; // if the total percentage from stars is greater than the fixed percent if (rowPercent < rowStarPercent) { // change the fixed percent size[2] = rowStarPercent; } // if this item had stars, it has not yet been included in totalPercent (even if it // specified both star and percent), so now include it's percent in totalPercent. // NB: We rely on "totalPercent" to be correct when we subsequently divy the // remainingSpace among items with percents; if it's wrong over/underflow will // occur. However totalPercent does not need to equal 100 because percents are // just treated as proportions. if (rowStarCount > 0) totalPercent += size[2]; } } // at this point, // - totalFixed is still the total of the fixed, absolute sizes // - totalPercent is the total percentage (including what used to be stars) // - we have no stars left // if nothing has variable size, we're done if (totalPercent <= 0) return outputSizes; var remainingSpace = Math.max(0, totalSize - totalFixed); //this.logWarn("remaining space: " + remainingSpace + // ", totalPercent: " + totalPercent); // apply mins and maximums. Note if an item gets set to its min or max, the behavior is // exactly as though the item had originally specified that fixed size. remainingSpace is // reduced along with the totalPercent it was being divided by. Note that when this // happens for a min, all other items get smaller, or for a max, all other items get // larger, so we have to recheck any previous mins or maxs. for (var r = 0; r < inputSizes.length; r++) { var pixelsPerPercent = Math.max(0, remainingSpace / totalPercent), size = outputSizes[r]; if (isc.isA.Number(size)) continue; var min = size[0]; if (min == 0) continue; var itemPercent = size[2], itemPixels = pixelsPerPercent * itemPercent; if (itemPixels < min) { outputSizes[r] = min; remainingSpace -= min; totalPercent -= itemPercent; // NOTE: we really only have to go back to the last non-zero minimum r = 0; } } // check maximums for (var r = 0; r < inputSizes.length; r++) { var pixelsPerPercent = Math.max(0, remainingSpace / totalPercent), size = outputSizes[r]; if (isc.isA.Number(size)) continue; var max = size[1], itemPercent = size[2], itemPixels = pixelsPerPercent * itemPercent; if (itemPixels > max) { outputSizes[r] = max; remainingSpace -= max; totalPercent -= itemPercent; // NOTE: we really only have to go back to the last non-infinite maximum r = 0; } } // at this point, all remaining variable-sized items fall within their max and min. (it's // also possible that all variable-sized items have been resolved to their max or min, // indicating overflow or underflow) pixelsPerPercent = Math.max(0, remainingSpace / totalPercent); for (var r = 0; r < inputSizes.length; r++) { size = outputSizes[r]; if (isc.isA.Number(size)) continue; // get the percent of the total outstanding percent that goes to this item var itemPercent = size[2]; outputSizes[r] = Math.floor(itemPercent * pixelsPerPercent); } // XXX do something about "remaining" pixels ??? // return the output sizes array return outputSizes;}}); // END isc.Canvas.addMethods()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -