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