/* ************************************************************************ 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) * David Perez Carmona (david-perez) ************************************************************************ */ /* ************************************************************************ #require(qx.theme.Modern) #require(qx.theme.Classic) #require(qx.log.Logger) ************************************************************************ */ /** * A data cell renderer for the tree column of a simple tree */ qx.Class.define("org.argeo.slc.web.util.TreeDataCellRenderer", { extend : qx.ui.treevirtual.SimpleTreeDataCellRenderer, construct : function() { this.base(arguments); this.__am = qx.util.AliasManager.getInstance(); this.__rm = qx.util.ResourceManager; this.__tm = qx.theme.manager.Appearance.getInstance(); // Base URL used for indentation this.BLANK = this.__rm.toUri(this.__am.resolve("static/blank.gif")); }, statics : { __icon : { } }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members : { // overridden _getCellStyle : function(cellInfo) { var node = cellInfo.value; // Return the style for the div for the cell. If there's cell-specific // style information provided, append it. var html = this.base(arguments, cellInfo) + (node.cellStyle ? node.cellStyle + ";" : ""); return html; }, // overridden _getContentHtml : function(cellInfo) { var html = ""; // Horizontal position var pos = 0; // If needed, add extra content before indentation var extra = this._addExtraContentBeforeIndentation(cellInfo, pos); html += extra.html; pos = extra.pos; // Add the indentation (optionally with tree lines) var indentation = this._addIndentation(cellInfo, pos); html += indentation.html pos = indentation.pos; // If needed, add extra content before icon extra = this._addExtraContentBeforeIcon(cellInfo, pos); html += extra.html; pos = extra.pos; // Add the node icon var icon = this._addIcon(cellInfo, pos); html += icon.html; pos = icon.pos; // If needed, add extra content before label extra = this._addExtraContentBeforeLabel(cellInfo, pos); html += extra.html; pos = extra.pos; // Add the node's label html += this._addLabel(cellInfo, pos); return html; }, /** * Add an image to the tree. This might be a visible icon or it may be * part of the indentation. * * @param imageInfo {Map} * How to display the image. It optionally includes any of the * following: *
*
position {Map}
*
* If provided, a div is created to hold the image. The div's top, * right, bottom, left, width, and/or height may be specified with * members of this map. Each is expected to be an integer value. *
*
imageWidth, imageHeight
*
* The image's width and height. These are used only if both are * specified. *
*
* * @return {String} * The html for this image, possibly with a surrounding div (see * 'position', above). */ _addImage : function(imageInfo) { var html = []; // Resolve the URI var source = this.__rm.toUri(this.__am.resolve(imageInfo.url)); // If we've been given positioning attributes, enclose image in a div if (imageInfo.position) { var pos = imageInfo.position; html.push('
'); } // Don't use an image tag. They render differently in Firefox and IE7 // even if both are enclosed in a div specified as content box. Instead, // add the image as the background image of a div. html.push('
 
'); if (imageInfo.position) { html.push('
'); } return html.join(""); }, /** * Add the indentation for this node of the tree. * * The indentation optionally includes tree lines. Whether tree lines are * used depends on (a) the properties 'useTreeLines' and * 'excludeFirstLevelTreelines' within this class; and (b) the widget * theme in use (some themes don't support tree lines). * * @param cellInfo {Map} The information about the cell. * See {@link qx.ui.table.cellrenderer.Abstract#createDataCellHtml}. * * @param pos {Integer} * The position from the left edge of the column at which to render this * item. * * @return {Map} * The returned map contains an 'html' member which contains the html for * the indentation, and a 'pos' member which is the starting position * plus the width of the indentation. */ _addIndentation : function(cellInfo, pos) { var node = cellInfo.value; var imageData; var html = ""; // Generate the indentation. Obtain icon determination values once // rather than each time through the loop. var bUseTreeLines = this.getUseTreeLines(); var bExcludeFirstLevelTreeLines = this.getExcludeFirstLevelTreeLines(); var bAlwaysShowOpenCloseSymbol = this.getAlwaysShowOpenCloseSymbol(); for (var i=0; i' + '' + node.label + '' + ''; return html; }, /** * Adds extra content just before the indentation. * * @param cellInfo {Map} The information about the cell. * See {@link qx.ui.table.cellrenderer.Abstract#createDataCellHtml}. * * @param pos {Integer} * The position from the left edge of the column at which to render this * item. * * @return {Map} * The returned map contains an 'html' member which contains the html for * the indentation, and a 'pos' member which is the starting position * plus the width of the indentation. */ _addExtraContentBeforeIndentation : function(cellInfo, pos) { return { html: '', pos: pos }; }, /** * Adds extra content just before the icon. * * @param cellInfo {Map} The information about the cell. * See {@link qx.ui.table.cellrenderer.Abstract#createDataCellHtml}. * * @param pos {Integer} * The position from the left edge of the column at which to render this * item. * * @return {Map} * The returned map contains an 'html' member which contains the html for * the indentation, and a 'pos' member which is the starting position * plus the width of the indentation. */ _addExtraContentBeforeIcon : function(cellInfo, pos) { return { html: '', pos: pos }; }, /** * Adds extra content just before the label. * * @param cellInfo {Map} The information about the cell. * See {@link qx.ui.table.cellrenderer.Abstract#createDataCellHtml}. * * @param pos {Integer} * The position from the left edge of the column at which to render this * item. * * @return {Map} * The returned map contains an 'html' member which contains the html for * the indentation, and a 'pos' member which is the starting position * plus the width of the indentation. */ _addExtraContentBeforeLabel : function(cellInfo, pos) { return { html: '', pos: pos }; }, /** * Determine the symbol to use for indentation of a tree row, at a * particular column. The indentation to use may be just white space or * may be a tree line. Tree lines come in numerous varieties, so the * appropriate one is selected. * * @type member * * @param column {Integer} * The column of indentation being requested, zero-relative * * @param node {Node} * The node being displayed in the row. The properties of a node are * described in {@link qx.ui.treevirtual.SimpleTreeDataModel} * * @param bUseTreeLines {Boolean} * Whether to find an appropriate tree line icon, or simply provide * white space. * * @param bAlwaysShowOpenCloseSymbol {Boolean} * Whether to display the open/close icon for a node even if it has no * children. * * @param bExcludeFirstLevelTreeLines {Boolean} * If bUseTreeLines is enabled, then further filtering of the left-most * tree line may be specified here. If true then the left-most * tree line, between top-level siblings, will not be displayed. * If false, then the left-most tree line wiill be displayed * just like all of the other tree lines. * * @return {var} TODOC */ _getIndentSymbol : function(column, node, bUseTreeLines, bAlwaysShowOpenCloseSymbol, bExcludeFirstLevelTreeLines) { var STDCR = org.argeo.slc.web.util.TreeDataCellRenderer; // If we're in column 0 and excludeFirstLevelTreeLines is enabled, then // we treat this as if no tree lines were requested. if (column == 0 && bExcludeFirstLevelTreeLines) { bUseTreeLines = false; } // If we're not on the final column... if (column < node.level - 1) { // then return either a line or a blank icon, depending on // bUseTreeLines return (bUseTreeLines && ! node.lastChild[column] ? STDCR.__icon.line : { icon : this.BLANK }); } var bLastChild = node.lastChild[node.lastChild.length - 1]; // Is this a branch node that does not have the open/close button hidden? if (node.type == qx.ui.treevirtual.SimpleTreeDataModel.Type.BRANCH && ! node.bHideOpenClose) { // Does this node have any children, or do we always want the // open/close symbol to be shown? if (node.children.length > 0 || bAlwaysShowOpenCloseSymbol) { // If we're not showing tree lines... if (!bUseTreeLines) { // ... then just use a expand or contract return (node.bOpened ? STDCR.__icon.contract : STDCR.__icon.expand); } // Are we looking at a top-level, first child of its parent? if (column == 0 && node.bFirstChild) { // Yup. If it's also a last child... if (bLastChild) { // ... then use no tree lines. return (node.bOpened ? STDCR.__icon.onlyContract : STDCR.__icon.onlyExpand); } else { // otherwise, use descender lines but no ascender. return (node.bOpened ? STDCR.__icon.startContract : STDCR.__icon.startExpand); } } // It's not a top-level, first child. Is this the last child of its // parent? if (bLastChild) { // Yup. Return an ending expand or contract. return (node.bOpened ? STDCR.__icon.endContract : STDCR.__icon.endExpand); } // Otherwise, return a crossing expand or contract. return (node.bOpened ? STDCR.__icon.crossContract : STDCR.__icon.crossExpand); } } // This node does not have any children. Return an end or cross, if // we're using tree lines. if (bUseTreeLines) { // If this is a child of the root node... if (node.parentNodeId == 0) { // If this is the only child... if (bLastChild && node.bFirstChild) { // ... then return a blank. return { icon : this.BLANK }; } // Otherwise, if this is the last child... if (bLastChild) { // ... then return an end line. return STDCR.__icon.end; } // Otherwise if this is the first child... if (node.bFirstChild) { // ... then return a start line. return STDCR.__icon.start; } } // If this is a last child, return and ending line; otherwise cross. return (bLastChild ? STDCR.__icon.end : STDCR.__icon.cross); } return { icon : this.BLANK }; } }, defer : function() { // Ensure that the theme is initialized qx.theme.manager.Meta.getInstance().initialize(); var STDCR = org.argeo.slc.web.util.TreeDataCellRenderer; var ImageLoader = qx.io2.ImageLoader; var am = qx.util.AliasManager.getInstance(); var rm = qx.util.ResourceManager; var tm = qx.theme.manager.Appearance.getInstance(); var loadImage = function(f) { ImageLoader.load(rm.toUri(am.resolve(f))); }; STDCR.__icon.line = tm.styleFrom("treevirtual-line"); loadImage(STDCR.__icon.line.icon); STDCR.__icon.contract = tm.styleFrom("treevirtual-contract"); loadImage(STDCR.__icon.contract.icon); STDCR.__icon.expand = tm.styleFrom("treevirtual-expand"); loadImage(STDCR.__icon.expand.icon); STDCR.__icon.onlyContract = tm.styleFrom("treevirtual-only-contract"); loadImage(STDCR.__icon.onlyContract.icon); STDCR.__icon.onlyExpand = tm.styleFrom("treevirtual-only-expand"); loadImage(STDCR.__icon.onlyExpand.icon); STDCR.__icon.startContract = tm.styleFrom("treevirtual-start-contract"); loadImage(STDCR.__icon.startContract.icon); STDCR.__icon.startExpand = tm.styleFrom("treevirtual-start-expand"); loadImage(STDCR.__icon.startExpand.icon); STDCR.__icon.endContract = tm.styleFrom("treevirtual-end-contract"); loadImage(STDCR.__icon.endContract.icon); STDCR.__icon.endExpand = tm.styleFrom("treevirtual-end-expand"); loadImage(STDCR.__icon.endExpand.icon); STDCR.__icon.crossContract = tm.styleFrom("treevirtual-cross-contract"); loadImage(STDCR.__icon.crossContract.icon); STDCR.__icon.crossExpand = tm.styleFrom("treevirtual-cross-expand"); loadImage(STDCR.__icon.crossExpand.icon); STDCR.__icon.end = tm.styleFrom("treevirtual-end"); loadImage(STDCR.__icon.end.icon); STDCR.__icon.cross = tm.styleFrom("treevirtual-cross"); loadImage(STDCR.__icon.cross.icon); }, destruct : function() { this._disposeFields( "__am", "__rm", "__tm", "BLANK"); } });