/* ************************************************************************
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.ria.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.ria.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.startContract;
}
}
// 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.ria.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");
}
});