summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2007-02-11 20:22:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:44:59 -0500
commit7deea1aead01beabde1218379b72dd20f64f93ce (patch)
treee23a057f604558f7a6c9d4267bbf39ef7cf9f8ea /webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js
parent9bdb49455aa6ad38f71375f602e691d2b7765d04 (diff)
downloadsamba-7deea1aead01beabde1218379b72dd20f64f93ce.tar.gz
samba-7deea1aead01beabde1218379b72dd20f64f93ce.tar.bz2
samba-7deea1aead01beabde1218379b72dd20f64f93ce.zip
r21285: - Add the new ResizeTableColumnModel and make use of it in TreeVirtual. This
allows the Ldb Browser tree to properly size itself upon initially appearing and upon window resizes. There are still a few problems with it that I need to resolve, including an occasional set of double scrollbars, and making it resize the tree column when the splitter is resized. (This used to be commit c3c93ad36a9e850865aa8b09e319a77441243b01)
Diffstat (limited to 'webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js')
-rw-r--r--webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js621
1 files changed, 621 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js b/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js
new file mode 100644
index 0000000000..39ab740f82
--- /dev/null
+++ b/webapps/qooxdoo-0.6.5-sdk/frontend/framework/source/class/qx/ui/table/DefaultResizeBehavior.js
@@ -0,0 +1,621 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2007 Derrell Lipman
+
+ License:
+ LGPL: http://www.gnu.org/licenses/lgpl.html
+ EPL: http://www.eclipse.org/org/documents/epl-v10.php
+ See the LICENSE file in the project's top-level directory for details.
+
+ Authors:
+ * Derrell Lipman (derrell)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(table)
+
+************************************************************************ */
+
+/**
+ * The default resize behavior. Until a resize model is loaded, the default
+ * behavior is to:
+ * <ol>
+ * <li>
+ * Upon the table initially appearing, and upon any window resize, divide
+ * the table space equally between the visible columns.
+ * </li>
+ * <li>
+ * When a column is increased in width, all columns to its right are
+ * pushed to the right with no change to their widths. This may push some
+ * columns off the right edge of the table, causing a horizontal scroll
+ * bar to appear.
+ * </li>
+ * <li>
+ * When a column is decreased in width, if the total width of all columns
+ * is <i>greater than</i> the table width, no additional column wiidth
+ * changes are made.
+ * </li>
+ * <li>
+ * When a column is decreased in width, if the total width of all columns
+ * is <i>less than</i> the width of the table, the visible column
+ * immediately to the right of the column which decreased in width has its
+ * width increased to fill the remaining space.
+ * </li>
+ * </ol>
+ *
+ * A resize model may be loaded to provide more guidance on how to adjust
+ * column width upon each of the events: initial appear, window resize, and
+ * column resize. *** TO BE FILLED IN ***
+ */
+qx.OO.defineClass("qx.ui.table.DefaultResizeBehavior",
+ qx.ui.table.AbstractResizeBehavior,
+function()
+{
+ qx.ui.table.AbstractResizeBehavior.call(this);
+});
+
+
+/*
+ * A function to instantiate a resize behavior column data object.
+ */
+qx.OO.addProperty(
+ {
+ name :
+ "newResizeBehaviorColumnData",
+ type :
+ "function",
+ setOnlyOnce :
+ true,
+ defaultValue:
+ function(obj)
+ {
+ return new qx.ui.table.ResizeBehaviorColumnData();
+ }
+ });
+
+
+/**
+ * Set the width of a column.
+ *
+ * @param col {Integer}
+ * The column whose width is to be set
+ *
+ * @param width {Integer, String}
+ * The width of the specified column. The width may be specified as integer
+ * number of pixels (e.g. 100), a string representing percentage of the
+ * inner width of the Table (e.g. "25%"), or a string representing a flex
+ * width (e.g. "1*").
+ */
+qx.Proto.setWidth = function(col, width)
+{
+ // Ensure the column is within range
+ if (col >= this._resizeColumnData.length)
+ {
+ throw new Error("Column number out of range");
+ }
+
+ // Set the new width
+ this._resizeColumnData[col].setWidth(width);
+};
+
+
+/**
+ * Set the minimum width of a column.
+ *
+ * @param col {Integer}
+ * The column whose minimum width is to be set
+ *
+ * @param width {Integer}
+ * The minimum width of the specified column.
+ */
+qx.Proto.setMinWidth = function(col, width)
+{
+ // Ensure the column is within range
+ if (col >= this._resizeColumnData.length)
+ {
+ throw new Error("Column number out of range");
+ }
+
+ // Set the new width
+ this._resizeColumnData[col].setMinWidth(width);
+};
+
+
+/**
+ * Set the maximum width of a column.
+ *
+ * @param col {Integer}
+ * The column whose maximum width is to be set
+ *
+ * @param width {Integer}
+ * The maximum width of the specified column.
+ */
+qx.Proto.setMaxWidth = function(col, width)
+{
+ // Ensure the column is within range
+ if (col >= this._resizeColumnData.length)
+ {
+ throw new Error("Column number out of range");
+ }
+
+ // Set the new width
+ this._resizeColumnData[col].setMaxWidth(width);
+};
+
+
+/**
+ * Set any or all of the width, minimum width, and maximum width of a column
+ * in a single call.
+ *
+ * @param map {Map}
+ * A map containing any or all of the property names "width", "minWidth",
+ * and "maxWidth". The property values are as described for
+ * {@link #setWidth}, {@link #setMinWidth} and {@link #setMaxWidth}
+ * respectively.
+ */
+qx.Proto.set = function(col, map)
+{
+ for (var prop in map)
+ {
+ switch(prop)
+ {
+ case "width":
+ this.setWidth(col, map[prop]);
+ break;
+
+ case "minWidth":
+ this.setMinWidth(col, map[prop]);
+ break;
+
+ case "maxWidth":
+ this.setMaxWidth(col, map[prop]);
+ break;
+
+ default:
+ throw new Error("Unknown property: " + prop);
+ }
+ }
+};
+
+
+// overloaded
+qx.Proto.onAppear = function(tableColumnModel, event)
+{
+ // Get the initial available width so we know whether a resize caused an
+ // increase or decrease in the available space.
+ this._width = this._getAvailableWidth(tableColumnModel);
+
+ // Calculate column widths
+ this._computeColumnsFlexWidth(tableColumnModel, event);
+};
+
+
+// overloaded
+qx.Proto.onWindowResize = function(tableColumnModel, event)
+{
+ // Calculate column widths
+ this._computeColumnsFlexWidth(tableColumnModel, event);
+};
+
+
+// overloaded
+qx.Proto.onColumnWidthChanged = function(tableColumnModel, event)
+{
+ // Extend the next column to fill blank space
+ this._extendNextColumn(tableColumnModel, event);
+};
+
+
+// overloaded
+qx.Proto.onVisibilityChanged = function(tableColumnModel, event)
+{
+ // Extend the last column to fill blank space
+ this._extendLastColumn(tableColumnModel, event);
+};
+
+
+// overloaded
+qx.Proto._setNumColumns = function(numColumns)
+{
+ // Are there now fewer (or the same number of) columns than there were
+ // previously?
+ if (numColumns <= this._resizeColumnData.length)
+ {
+ // Yup. Delete the extras.
+ this._resizeColumnData.splice(numColumns);
+ return;
+ }
+
+ // There are more columns than there were previously. Allocate more.
+ for (var i = this._resizeColumnData.length; i < numColumns; i++)
+ {
+ this._resizeColumnData[i] = this.getNewResizeBehaviorColumnData()();
+ this._resizeColumnData[i]._columnNumber = i;
+ }
+};
+
+
+/**
+ * Computes the width of all flexible children (based loosely on the method of
+ * the same name in HorizontalBoxLayoutImpl).
+ *
+ * @param tableColumnModel {qx.ui.table.ResizeTableColumnModel}
+ * The table column model in use.
+ *
+ * @param event
+ * The event object.
+ */
+qx.Proto._computeColumnsFlexWidth = function(tableColumnModel, event)
+{
+ // Semi-permanent configuration settings
+ var debug = true;
+
+ if (debug)
+ {
+ this.debug("computeColumnsFlexWidth");
+ }
+
+ var visibleColumns = tableColumnModel._visibleColumnArr;
+ var visibleColumnsLength = visibleColumns.length;
+ var columnData;
+ var flexibleColumns = [ ];
+ var widthUsed = 0;
+ var i;
+
+ // Determine the available width
+ var width = this._getAvailableWidth(tableColumnModel);
+
+
+ // *************************************************************
+ // 1. Compute the sum of all static sized columns and find
+ // all flexible columns.
+ // *************************************************************
+ for (i = 0; i < visibleColumnsLength; i++)
+ {
+ // Get the current column's column data
+ columnData = this._resizeColumnData[visibleColumns[i]];
+
+ // Is this column width type "auto"?
+ if (columnData._computedWidthTypeAuto)
+ {
+ // Yup. Convert it to a Flex "1*"
+ columnData._computedWidthTypeAuto = false;
+ columnData._computedWidthTypeFlex = true;
+ columnData._computedWidthParsed = 1;
+ }
+
+ // Is this column a flex width?
+ if (columnData._computedWidthTypeFlex)
+ {
+ // Yup. Save it for future processing.
+ flexibleColumns.push(columnData);
+ }
+ else if (columnData._computedWidthTypePercent)
+ {
+ // We can calculate the width of a Percent type right now. Convert it
+ // to a Flex type that's already calculated (no further calculation
+ // required).
+ columnData._computedWidthPercentValue =
+ Math.round(width * (columnData._computedWidthParsed / 100));
+ widthUsed += columnData._computedWidthPercentValue;
+ }
+ else
+ {
+ // We have a fixed width. Track width already allocated.
+ widthUsed += columnData.getWidth();
+ }
+ }
+
+ if (debug)
+ {
+ this.debug("Width: " + widthUsed + "/" + width);
+ this.debug("Flexible Count: " + flexibleColumns.length);
+ }
+
+
+ // *************************************************************
+ // 2. Compute the sum of all flexible column widths
+ // *************************************************************
+ var widthRemaining = width - widthUsed;
+ var flexibleColumnsLength = flexibleColumns.length;
+ var prioritySum = 0;
+
+ for (i = 0; i < flexibleColumnsLength; i++)
+ {
+ prioritySum += flexibleColumns[i]._computedWidthParsed;
+ }
+
+
+ // *************************************************************
+ // 3. Calculating the size of each 'part'.
+ // *************************************************************
+ var partWidth = widthRemaining / prioritySum;
+
+ // *************************************************************
+ // 4. Adjust flexible columns, taking min/max values into account
+ // *************************************************************
+
+ bSomethingChanged = true;
+ for (flexibleColumnsLength = flexibleColumns.length;
+ bSomethingChanged && flexibleColumnsLength > 0;
+ flexibleColumnsLength = flexibleColumns.length)
+ {
+ // Assume nothing will change
+ bSomethingChanged = false;
+
+ for (i = flexibleColumnsLength - 1; i >= 0; i--)
+ {
+ columnData = flexibleColumns[i];
+
+ computedFlexibleWidth =
+ columnData._computedWidthFlexValue =
+ columnData._computedWidthParsed * partWidth;
+
+ // If the part is not within its specified min/max range, adjust it.
+ var min = columnData.getMinWidthValue();
+ var max = columnData.getMaxWidthValue();
+ if (min && computedFlexibleWidth < min)
+ {
+ columnData._computedWidthFlexValue = Math.round(min);
+ widthUsed += columnData._computedWidthFlexValue;
+ qx.lang.Array.removeAt(flexibleColumns, i);
+ bSomethingChanged = true;
+
+ // Don't round fixed-width columns (in step 5)
+ columnData = null;
+ }
+ else if (max && computedFlexibleWidth > max)
+ {
+ columnData._computedWidthFlexValue = Math.round(max);
+ widthUsed += columnData._computedWidthFlexValue;
+ qx.lang.Array.removeAt(flexibleColumns, i);
+ bSomethingChanged = true;
+
+ // Don't round fixed-width columns (in step 5)
+ columnData = null;
+ }
+ }
+ }
+
+ // If any flexible columns remain, then allocate the remaining space to them
+ if (flexibleColumns.length > 0)
+ {
+ // Recalculate the priority sum of the remaining flexible columns
+ prioritySum = 0;
+ for (i = 0; i < flexibleColumnsLength; i++)
+ {
+ prioritySum += flexibleColumns[i]._computedWidthParsed;
+ }
+
+ // Recalculate the width remaining and part width
+ widthRemaining = width - widthUsed;
+ partWidth = widthRemaining / prioritySum;
+
+ // If there's no width remaining...
+ if (widthRemaining <= 0)
+ {
+ // ... then use minimum width * priority for all remaining columns
+ for (i = 0; i < flexibleColumnsLength; i++)
+ {
+ columnData = flexibleColumns[i];
+
+ computedFlexibleWidth =
+ columnData._computedWidthFlexValue =
+ (qx.ui.table.DefaultResizeBehavior.MIN_WIDTH *
+ flexibleColumns[i]._computedWidthParsed);
+ columnData._computedWidthFlexValue = Math.round(computedFlexibleWidth);
+ widthUsed += columnData._computedWidthFlexValue;
+ }
+ }
+ else
+ {
+ // Assign widths of remaining flexible columns
+ for (i = 0; i < flexibleColumnsLength; i++)
+ {
+ columnData = flexibleColumns[i];
+
+ computedFlexibleWidth =
+ columnData._computedWidthFlexValue =
+ columnData._computedWidthParsed * partWidth;
+
+ // If the computed width is less than our hard-coded minimum...
+ if (computedFlexibleWidth <
+ qx.ui.table.DefaultResizeBehavior.MIN_WIDTH)
+ {
+ // ... then use the hard-coded minimum
+ computedFlexibleWidth = qx.ui.table.DefaultResizeBehavior.MIN_WIDTH;
+ }
+
+ columnData._computedWidthFlexValue = Math.round(computedFlexibleWidth);
+ widthUsed += columnData._computedWidthFlexValue;
+ }
+ }
+ }
+
+ // *************************************************************
+ // 5. Fix rounding errors
+ // *************************************************************
+ if (columnData != null && widthRemaining > 0)
+ {
+ columnData._computedWidthFlexValue += width - widthUsed;
+ }
+
+ // *************************************************************
+ // 6. Set the column widths to what we have calculated
+ // *************************************************************
+ for (i = 0; i < visibleColumnsLength; i++)
+ {
+ var colWidth;
+
+ // Get the current column's column data
+ columnData = this._resizeColumnData[visibleColumns[i]];
+
+ // Is this column a flex width?
+ if (columnData._computedWidthTypeFlex)
+ {
+ // Yup. Set the width to the calculated width value based on flex
+ colWidth = columnData._computedWidthFlexValue;
+ }
+ else if (columnData._computedWidthTypePercent)
+ {
+ // Set the width to the calculated width value based on percent
+ colWidth = columnData._computedWidthPercentValue;
+ }
+ else
+ {
+ colWidth = columnData.getWidth();
+ }
+
+ // Now that we've calculated the width, set it.
+ tableColumnModel.setColumnWidth(visibleColumns[i], colWidth);
+
+ if (debug)
+ {
+ this.debug("col " + columnData._columnNumber + ": width=" + colWidth);
+ }
+ }
+};
+
+
+/**
+ * Extend the visible column to right of the column which just changed width,
+ * to fill any available space within the inner width of the table. This
+ * means that if the sum of the widths of all columns exceeds the inner width
+ * of the table, no change is made. If, on the other hand, the sum of the
+ * widths of all columns is less than the inner width of the table, the
+ * visible column to the right of the column which just changed width is
+ * extended to take up the width available within the inner width of the
+ * table.
+ *
+ * @param tableColumnModel {qx.ui.table.ResizeTableColumnModel}
+ * The table column model in use.
+ *
+ * @param event
+ * The event object.
+ */
+qx.Proto._extendNextColumn = function(tableColumnModel, event)
+{
+ // Event data properties: col, oldWidth, newWidth
+ var data = event.getData();
+
+ var visibleColumns = tableColumnModel._visibleColumnArr;
+
+ // Determine the available width
+ var width = this._getAvailableWidth(tableColumnModel);
+
+ // Determine the number of visible columns
+ var numColumns = visibleColumns.length;
+
+ // Did this column become longer than it was?
+ if (data.newWidth > data.oldWidth)
+ {
+ // Yup. Don't resize anything else. The other columns will just get
+ // pushed off and require scrollbars be added (if not already there).
+ return;
+ }
+
+ // This column became shorter. See if we no longer take up the full space
+ // that's available to us.
+ var i;
+ var nextCol;
+ var widthUsed = 0;
+ for (i = 0; i < numColumns; i++)
+ {
+ widthUsed +=
+ tableColumnModel.getColumnWidth(visibleColumns[i]);
+ }
+
+ // If the used width is less than the available width...
+ if (widthUsed < width)
+ {
+ // ... then determine the next visible column
+ for (i = 0; i < visibleColumns.length; i++)
+ {
+ if (visibleColumns[i] == data.col)
+ {
+ nextCol = visibleColumns[i + 1];
+ break;
+ }
+ }
+
+ if (nextCol)
+ {
+ // Make the next column take up the available space.
+ var oldWidth = tableColumnModel.getColumnWidth(nextCol);
+ var newWidth = (width - (widthUsed -
+ tableColumnModel.getColumnWidth(nextCol)));
+ tableColumnModel.setColumnWidth(nextCol, newWidth);
+ }
+ }
+};
+
+
+/**
+ * If a column was just made invisible, extend the last column to fill any
+ * available space within the inner width of the table. This means that if
+ * the sum of the widths of all columns exceeds the inner width of the table,
+ * no change is made. If, on the other hand, the sum of the widths of all
+ * columns is less than the inner width of the table, the last column is
+ * extended to take up the width available within the inner width of the
+ * table.
+ *
+ * @param tableColumnModel {qx.ui.table.ResizeTableColumnModel}
+ * The table column model in use.
+ *
+ * @param event
+ * The event object.
+ */
+qx.Proto._extendLastColumn = function(tableColumnModel, event)
+{
+ // Event data properties: col, visible
+ var data = event.getData();
+
+ // If the column just became visible, don't make any width changes
+ if (data.visible)
+ {
+ return;
+ }
+
+ // Get the array of visible columns
+ var visibleColumns = tableColumnModel._visibleColumnArr;
+
+ // Determine the available width
+ var width = this._getAvailableWidth(tableColumnModel);
+
+ // Determine the number of visible columns
+ var numColumns = visibleColumns.length;
+
+ // See if we no longer take up the full space that's available to us.
+ var i;
+ var lastCol;
+ var widthUsed = 0;
+ for (i = 0; i < numColumns; i++)
+ {
+ widthUsed +=
+ tableColumnModel.getColumnWidth(visibleColumns[i]);
+ }
+
+ // If the used width is less than the available width...
+ if (widthUsed < width)
+ {
+ // ... then get the last visible column
+ lastCol = visibleColumns[visibleColumns.length - 1];
+
+ // Make the last column take up the available space.
+ var oldWidth = tableColumnModel.getColumnWidth(lastCol);
+ var newWidth = (width - (widthUsed -
+ tableColumnModel.getColumnWidth(lastCol)));
+ tableColumnModel.setColumnWidth(lastCol, newWidth);
+ }
+};
+
+
+
+qx.Class.MIN_WIDTH = 10;