UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

333 lines (276 loc) 9.08 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2006 STZ-IDA, Germany, http://www.stz-ida.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Til Schneider (til132) ************************************************************************ */ /** * Shows the header of a table. */ qx.Class.define("qx.ui.table.pane.Header", { extend: qx.ui.core.Widget, /* ***************************************************************************** CONSTRUCTOR ***************************************************************************** */ /** * @param paneScroller {qx.ui.table.pane.Scroller} the TablePaneScroller the header belongs to. */ construct(paneScroller) { super(); this._setLayout(new qx.ui.layout.HBox()); // add blocker this.__blocker = new qx.ui.core.Blocker(this); this.__paneScroller = paneScroller; // ARIA attrs this.getContentElement().setAttribute("role", "row"); }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members: { __paneScroller: null, __moveFeedback: null, __lastPointerOverColumn: null, __blocker: null, /** * Returns the TablePaneScroller this header belongs to. * * @return {qx.ui.table.pane.Scroller} the TablePaneScroller. */ getPaneScroller() { return this.__paneScroller; }, /** * Returns the table this header belongs to. * * @return {qx.ui.table.Table} the table. */ getTable() { return this.__paneScroller.getTable(); }, /** * Returns the blocker of the header. * * @return {qx.ui.core.Blocker} the blocker. */ getBlocker() { return this.__blocker; }, /** * Event handler. Called the column order has changed. * */ onColOrderChanged() { this._updateContent(true); }, /** * Event handler. Called when the pane model has changed. */ onPaneModelChanged() { this._updateContent(true); }, /** * Event handler. Called when the table model meta data has changed. * */ onTableModelMetaDataChanged() { this._updateContent(); }, /** * Sets the column width. This overrides the width from the column model. * * @param col {Integer} * The column to change the width for. * * @param width {Integer} * The new width. * * @param isPointerAction {Boolean} * <i>true</i> if the column width is being changed as a result of a * pointer drag in the header; false or undefined otherwise. * */ setColumnWidth(col, width, isPointerAction) { var child = this.getHeaderWidgetAtColumn(col); if (child != null) { child.setWidth(width); } }, /** * Sets the column the pointer is currently over. * * @param col {Integer} the model index of the column the pointer is currently over or * null if the pointer is over no column. */ setPointerOverColumn(col) { if (col != this.__lastPointerOverColumn) { if (this.__lastPointerOverColumn != null) { var widget = this.getHeaderWidgetAtColumn( this.__lastPointerOverColumn ); if (widget != null) { widget.removeState("hovered"); } } if (col != null) { this.getHeaderWidgetAtColumn(col).addState("hovered"); } this.__lastPointerOverColumn = col; } }, /** * Get the header widget for the given column * * @param col {Integer} The column number * @return {qx.ui.table.headerrenderer.HeaderCell} The header cell widget */ getHeaderWidgetAtColumn(col) { var xPos = this.getPaneScroller().getTablePaneModel().getX(col); return this._getChildren()[xPos]; }, /** * Shows the feedback shown while a column is moved by the user. * * @param col {Integer} the model index of the column to show the move feedback for. * @param x {Integer} the x position the left side of the feedback should have * (in pixels, relative to the left side of the header). */ showColumnMoveFeedback(col, x) { var pos = this.getContentLocation(); if (this.__moveFeedback == null) { var table = this.getTable(); var xPos = this.getPaneScroller().getTablePaneModel().getX(col); var cellWidget = this._getChildren()[xPos]; var tableModel = table.getTableModel(); var columnModel = table.getTableColumnModel(); var cellInfo = { xPos: xPos, col: col, name: tableModel.getColumnName(col), table: table }; var cellRenderer = columnModel.getHeaderCellRenderer(col); var feedback = cellRenderer.createHeaderCell(cellInfo); var size = cellWidget.getBounds(); // Configure the feedback feedback.setWidth(size.width); feedback.setHeight(size.height); feedback.setZIndex(1000000); feedback.setOpacity(0.8); feedback.setLayoutProperties({ top: pos.top }); this.getApplicationRoot().add(feedback); this.__moveFeedback = feedback; } this.__moveFeedback.setLayoutProperties({ left: pos.left + x }); this.__moveFeedback.show(); }, /** * Hides the feedback shown while a column is moved by the user. */ hideColumnMoveFeedback() { if (this.__moveFeedback != null) { this.__moveFeedback.destroy(); this.__moveFeedback = null; } }, /** * Returns whether the column move feedback is currently shown. * * @return {Boolean} <code>true</code> whether the column move feedback is * currently shown, <code>false</code> otherwise. */ isShowingColumnMoveFeedback() { return this.__moveFeedback != null; }, /** * Updates the content of the header. * * @param completeUpdate {Boolean} if true a complete update is performed. On a * complete update all header widgets are recreated. */ _updateContent(completeUpdate) { var table = this.getTable(); var tableModel = table.getTableModel(); var columnModel = table.getTableColumnModel(); var paneModel = this.getPaneScroller().getTablePaneModel(); var children = this._getChildren(); var colCount = paneModel.getColumnCount(); var sortedColumn = tableModel.getSortColumnIndex(); // Remove all widgets on the complete update if (completeUpdate) { this._cleanUpCells(); } // Update the header var cellInfo = {}; cellInfo.sortedAscending = tableModel.isSortAscending(); for (var x = 0; x < colCount; x++) { var col = paneModel.getColumnAtX(x); if (col === undefined) { continue; } var colWidth = columnModel.getColumnWidth(col); var cellRenderer = columnModel.getHeaderCellRenderer(col); cellInfo.xPos = x; cellInfo.col = col; cellInfo.name = tableModel.getColumnName(col); cellInfo.editable = tableModel.isColumnEditable(col); cellInfo.sorted = col == sortedColumn; cellInfo.table = table; // Get the cached widget var cachedWidget = children[x]; // Create or update the widget if (cachedWidget == null) { // We have no cached widget -> create it cachedWidget = cellRenderer.createHeaderCell(cellInfo); cachedWidget.set({ width: colWidth }); this._add(cachedWidget); } else { // This widget already created before -> recycle it cellRenderer.updateHeaderCell(cellInfo, cachedWidget); } // set the states if (x === 0) { cachedWidget.addState("first"); cachedWidget.removeState("last"); } else if (x === colCount - 1) { cachedWidget.removeState("first"); cachedWidget.addState("last"); } else { cachedWidget.removeState("first"); cachedWidget.removeState("last"); } } }, /** * Cleans up all header cells. * */ _cleanUpCells() { var children = this._getChildren(); for (var x = children.length - 1; x >= 0; x--) { var cellWidget = children[x]; cellWidget.destroy(); } } }, /* ***************************************************************************** DESTRUCTOR ***************************************************************************** */ destruct() { this.__blocker.dispose(); this._disposeObjects("__paneScroller"); } });