diff options
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol')
5 files changed, 2060 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/AbstractTreeElement.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/AbstractTreeElement.js new file mode 100644 index 0000000000..16245b9f0b --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/AbstractTreeElement.js @@ -0,0 +1,529 @@ +/* ************************************************************************ + + qooxdoo - the new era of web development + + http://qooxdoo.org + + Copyright: + 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org + 2006 by Derrell Lipman + + License: + LGPL 2.1: http://www.gnu.org/licenses/lgpl.html + + Authors: + * Sebastian Werner (wpbasti) + * Andreas Ecker (ecker) + * Derrell Lipman (derrell) + +************************************************************************ */ + +/* ************************************************************************ + +#module(ui_treefullcontrol) + +************************************************************************ */ + +qx.OO.defineClass("qx.ui.treefullcontrol.AbstractTreeElement", qx.ui.layout.BoxLayout, +function(treeRowStructure) +{ + if (this.classname == qx.ui.treefullcontrol.AbstractTreeElement.ABSTRACT_CLASS) { + throw new Error("Please omit the usage of qx.ui.treefullcontrol.AbstractTreeElement directly. Choose between qx.ui.treefullcontrol.TreeFolder, qx.ui.treefullcontrol.TreeFolderSimple, qx.ui.treefullcontrol.TreeFile and qx.ui.treefullcontrol.TreeFileSimple instead!"); + } + + if (treeRowStructure !== qx.ui.treefullcontrol.TreeRowStructure.getInstance()) + { + throw new Error("A qx.ui.treefullcontrol.TreeRowStructure parameter is required."); + } + + // Precreate subwidgets + this._indentObject = treeRowStructure._indentObject; + this._iconObject = treeRowStructure._iconObject; + this._labelObject = treeRowStructure._labelObject; + + // Make anonymous + this._indentObject.setAnonymous(true); + this._iconObject.setAnonymous(true); + this._labelObject.setAnonymous(true); + + // Behaviour and Hard Styling + this._labelObject.setSelectable(false); + this._labelObject.setStyleProperty("lineHeight", + "100%"); + + qx.ui.layout.BoxLayout.call(this, "horizontal"); + + if (qx.util.Validation.isValid(treeRowStructure._label)) { + this.setLabel(treeRowStructure._label); + } + + // Prohibit selection + this.setSelectable(false); + + // Base URL used for indent images + this.BASE_URI = qx.manager.object.AliasManager.getInstance().resolvePath("widget/tree/"); + + /* + * Add all of the objects which are to be in the horizontal layout. + */ + for (var i = 0; i < treeRowStructure._fields.length; i++) + { + this.add(treeRowStructure._fields[i]); + } + + // Set Icons + if ((treeRowStructure._icons.unselected != null) && + (qx.util.Validation.isValidString(treeRowStructure._icons.unselected))) { + this.setIcon(treeRowStructure._icons.unselected); + this.setIconSelected(treeRowStructure._icons.unselected); + } + if ((treeRowStructure._icons.selected != null) && + (qx.util.Validation.isValidString(treeRowStructure._icons.selected))) { + this.setIconSelected(treeRowStructure._icons.selected); + } + + // Setup initial icon + this._iconObject.setSource(this._evalCurrentIcon()); + + // Set Appearance + this._iconObject.setAppearance("tree-element-icon"); + this._labelObject.setAppearance("tree-element-label"); + + // Register event listeners + this.addEventListener("mousedown", this._onmousedown); + this.addEventListener("mouseup", this._onmouseup); +}); + +qx.ui.treefullcontrol.AbstractTreeElement.ABSTRACT_CLASS = "qx.ui.treefullcontrol.AbstractTreeElement"; + + + + +/* +--------------------------------------------------------------------------- + PROPERTIES +--------------------------------------------------------------------------- +*/ + +qx.OO.changeProperty({ name : "appearance", + type : "string", + defaultValue : "tree-element" + }); + +/*! + The icons +*/ +qx.OO.addProperty({ name : "icon", + type : "string" + }); + +qx.OO.addProperty({ name : "iconSelected", + type : "string" + }); + +/*! + The label/caption/text of the qx.ui.basic.Atom instance +*/ +qx.OO.addProperty({ name : "label", + type : "string" + }); + +/*! + Selected property +*/ +qx.OO.addProperty({ name : "selected", + type : "boolean", + defaultValue : false + }); + + + + + + +/* +--------------------------------------------------------------------------- + MODIFIER +--------------------------------------------------------------------------- +*/ + +qx.Proto._modifyLabel = function(propValue, propOldValue, propData) +{ + if (this._labelObject) { + this._labelObject.setHtml(propValue); + } + + return true; +} + +qx.Proto._modifySelected = function(propValue, propOldValue, propData) +{ + if (propValue) { + this.addState("selected"); + this._labelObject.addState("selected"); + } else { + this.removeState("selected"); + this._labelObject.removeState("selected"); + } + + var vTree = this.getTree(); + if (!vTree._fastUpdate || + (propOldValue && vTree._oldItem == this)) { + this._iconObject.setSource(this._evalCurrentIcon()); + + if (propValue) { + this._iconObject.addState("selected"); + } else { + this._iconObject.removeState("selected"); + } + } + + var vManager = this.getTree().getManager(); + + if (propOldValue && vManager.getSelectedItem() == this) + { + vManager.deselectAll(); + } + else if (propValue && vManager.getSelectedItem() != this) + { + vManager.setSelectedItem(this); + } + + return true; +} + +qx.Proto._evalCurrentIcon = function() +{ + if (this.getSelected() && this.getIconSelected()) { + return this.getIconSelected(); + } else { + return this.getIcon() || "icon/16/file-new.png"; + } +} + + + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getParentFolder = function() +{ + try { + return this.getParent().getParent(); + } catch(ex) {} + + return null; +} + +qx.Proto.getLevel = function() +{ + var vParentFolder = this.getParentFolder(); + return vParentFolder ? vParentFolder.getLevel() + 1 : null; +} + +qx.Proto.getTree = function() +{ + var vParentFolder = this.getParentFolder(); + return vParentFolder ? vParentFolder.getTree() : null; +} + +qx.Proto.getIndentObject = function() { + return this._indentObject; +} + +qx.Proto.getIconObject = function() { + return this._iconObject; +} + +qx.Proto.getLabelObject = function() { + return this._labelObject; +} + +/** + * Obtain the entire hierarchy of labels from the root down to the current + * node. + * + * @param + * vArr - + * When called by the user, arr should typically be an empty array. Each + * level from the current node upwards will push its label onto the array. + */ +qx.Proto.getHierarchy = function(vArr) { + // Add our label to the array + if (this._labelObject) { + vArr.unshift(this._labelObject.getHtml()); + } + + // Get the parent folder + var parent = this.getParentFolder(); + + // If it exists... + if (parent) { + // ... then add it and its ancestors' labels to the array. + parent.getHierarchy(vArr); + } + + // Give 'em what they came for + return vArr; +} + + + + +/* +--------------------------------------------------------------------------- + QUEUE HANDLING +--------------------------------------------------------------------------- +*/ + +qx.Proto.addToTreeQueue = function() +{ + var vTree = this.getTree(); + if (vTree) { + vTree.addChildToTreeQueue(this); + } +} + +qx.Proto.removeFromTreeQueue = function() +{ + var vTree = this.getTree(); + if (vTree) { + vTree.removeChildFromTreeQueue(this); + } +} + +qx.Proto.addToCustomQueues = function(vHint) +{ + this.addToTreeQueue(); + + qx.ui.layout.BoxLayout.prototype.addToCustomQueues.call(this, vHint); +} + +qx.Proto.removeFromCustomQueues = function(vHint) +{ + this.removeFromTreeQueue(); + + qx.ui.layout.BoxLayout.prototype.removeFromCustomQueues.call(this, vHint); +} + + + + + + + + +/* +--------------------------------------------------------------------------- + DISPLAYBLE HANDLING +--------------------------------------------------------------------------- +*/ + +qx.Proto._modifyParent = function(propValue, propOldValue, propData) +{ + qx.ui.layout.BoxLayout.prototype._modifyParent.call(this, propValue, propOldValue, propData); + + // Be sure to update previous folder also if it is closed currently + // (plus/minus symbol) + if (propOldValue && + !propOldValue.isDisplayable() && + propOldValue.getParent() && + propOldValue.getParent().isDisplayable()) { + propOldValue.getParent().addToTreeQueue(); + } + + // Be sure to update new folder also if it is closed currently + // (plus/minus symbol) + if (propValue && + !propValue.isDisplayable() && + propValue.getParent() && + propValue.getParent().isDisplayable()) { + propValue.getParent().addToTreeQueue(); + } + + return true; +} + +qx.Proto._handleDisplayableCustom = function(vDisplayable, vParent, vHint) +{ + qx.ui.layout.BoxLayout.prototype._handleDisplayableCustom.call(this, + vDisplayable, + vParent, + vHint); + + if (vHint) + { + var vParentFolder = this.getParentFolder(); + var vPreviousParentFolder = this._previousParentFolder; + + if (vPreviousParentFolder) + { + if (this._wasLastVisibleChild) + { + vPreviousParentFolder._updateIndent(); + } + else if (!vPreviousParentFolder.hasContent()) + { + vPreviousParentFolder.addToTreeQueue(); + } + } + + if (vParentFolder && + vParentFolder.isDisplayable() && + vParentFolder._initialLayoutDone) { + vParentFolder.addToTreeQueue(); + } + + if (this.isLastVisibleChild()) + { + var vPrev = this.getPreviousVisibleSibling(); + + if (vPrev && + vPrev instanceof qx.ui.treefullcontrol.AbstractTreeElement) { + vPrev._updateIndent(); + } + } + + if (vDisplayable) { + this._updateIndent(); + } + } +} + + + + + + + +/* +--------------------------------------------------------------------------- + EVENT LISTENERS +--------------------------------------------------------------------------- +*/ + +qx.Proto._onmousedown = function(e) +{ + this.getTree().getManager().handleMouseDown(this, e); + e.stopPropagation(); +} + +qx.Proto._onmouseup = qx.util.Return.returnTrue; + + + + + +/* +--------------------------------------------------------------------------- + TREE FLUSH +--------------------------------------------------------------------------- +*/ + +qx.Proto.flushTree = function() +{ + // store information for update process + this._previousParentFolder = this.getParentFolder(); + this._wasLastVisibleChild = this.isLastVisibleChild(); + + // generate html for indent area + var vLevel = this.getLevel(); + var vTree = this.getTree(); + var vImage; + var vHtml = []; + var vCurrentObject = this; + var vMinLevel = 0; + var vMaxLevel = vLevel; + + // If we're displaying the open/close button for the root node (normal)... + if (vTree.getRootOpenClose()) { + // ... then we need one more level + vMaxLevel = vLevel + 1; + } + + // If we're not displaying the root node (creating virtual roots)... + if (vTree.hideNode()) { + // ... then start one level higher + vMinLevel = 1; + } + + for (var i=vMinLevel; i<vMaxLevel; i++) + { + vImage = vCurrentObject.getIndentSymbol(vTree.getUseTreeLines(), + i, + vMinLevel, + vMaxLevel); + + if (vImage) + { + vHtml.push("<img style=\"position:absolute;top:0px;left:"); + + // location of image; Root's image could be left of margin (invisible) + vHtml.push((vMaxLevel-i-1) * 19); + + vHtml.push("px\" src=\""); + vHtml.push(this.BASE_URI); + vHtml.push(vImage); + vHtml.push("."); + vHtml.push("gif"); + vHtml.push("\" />"); + } + + vCurrentObject = vCurrentObject.getParentFolder(); + } + + this._indentObject.setHtml(vHtml.join("")); + this._indentObject.setWidth((vMaxLevel - vMinLevel) * 19); +} + + + + + + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return true; + } + + if (this._indentObject) + { + this._indentObject.dispose(); + this._indentObject = null; + } + + if (this._iconObject) + { + this._iconObject.dispose(); + this._iconObject = null; + } + + if (this._labelObject) + { + this._labelObject.dispose(); + this._labelObject = null; + } + + this._previousParentFolder = null; + + this.removeEventListener("mousedown", this._onmousedown); + this.removeEventListener("mouseup", this._onmouseup); + + return qx.ui.layout.BoxLayout.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/Tree.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/Tree.js new file mode 100644 index 0000000000..912ede6d60 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/Tree.js @@ -0,0 +1,539 @@ +/* ************************************************************************ + + qooxdoo - the new era of web development + + http://qooxdoo.org + + Copyright: + 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org + 2006 by Derrell Lipman + + License: + LGPL 2.1: http://www.gnu.org/licenses/lgpl.html + + Authors: + * Sebastian Werner (wpbasti) + * Andreas Ecker (ecker) + * Derrell Lipman (derrell) + +************************************************************************ */ + +/* ************************************************************************ + +#module(ui_treefullcontrol) + +************************************************************************ */ + +/** + * qx.ui.treefullcontrol.Tree objects are tree root nodes but act like + * TreeFolder. + * + * @param treeRowStructure An instance of qx.ui.treefullcontrol.TreeRowStructure, + * defining the structure of this tree row. + */ +qx.OO.defineClass("qx.ui.treefullcontrol.Tree", qx.ui.treefullcontrol.TreeFolder, +function(treeRowStructure) +{ + qx.ui.treefullcontrol.TreeFolder.call(this, treeRowStructure); + + // ************************************************************************ + // INITILISIZE MANAGER + // ************************************************************************ + this._manager = new qx.manager.selection.TreeFullControlSelectionManager(this); + + + this._iconObject.setAppearance("tree-icon"); + this._labelObject.setAppearance("tree-label"); + + + // ************************************************************************ + // DEFAULT STATE + // ************************************************************************ + // The tree should be open by default + this.setOpen(true); + + // Fix vertical alignment of empty tree + this.addToFolder(); + + + // ************************************************************************ + // KEY EVENT LISTENER + // ************************************************************************ + this.addEventListener("keydown", this._onkeydown); + this.addEventListener("keypress", this._onkeypress); + this.addEventListener("keyup", this._onkeyup); +}); + + + + + +/* +--------------------------------------------------------------------------- + PROPERTIES +--------------------------------------------------------------------------- +*/ + +qx.OO.addProperty({ name : "useDoubleClick", + type : "boolean", + defaultValue : false, + getAlias : "useDoubleClick" + }); + +qx.OO.addProperty({ name : "useTreeLines", + type : "boolean", + defaultValue : true, + getAlias : "useTreeLines" + }); + +/*! + In specific applications, it is desirable to omit tree lines for only + certain indentation levels. This property provides an array wherein the + index of the array corresponds to the indentation level, counted from left + to right; and the value of that element, if it contains, specifically, the + boolean value <i>true</i>, indicates that tree lines at that indentation + level are to be omitted. Any value of that element other than <i>true</i>, + or if an indentation level's index does not exist in the array, means that + tree lines should be displayed for that indentation level. (There are some + minor code efficiencies that are realized if this array is empty, so after + having set an element to <i>true</i> and desiring to reset the default + behavior, you should 'delete' the element rather than setting it to some + value other than <i>true</i>.) + + If useTreeLines is <i>false</i>, then all tree lines are excluded and this + property is ignored. +*/ +qx.OO.addProperty({ name : "excludeSpecificTreeLines", + type : "object", + defaultValue : [] + }); + +/*! + Hide the root (Tree) node. This differs from the visibility property in + that this property hides *only* the current node, not the node's children. +*/ +qx.OO.addProperty({ name : "hideNode", + type : "boolean", + defaultValue : false, + getAlias : "hideNode" + }); + +/*! + Whether the Root should have an open/close button. This may also be + used in conjunction with the hideNode property to provide for virtual root + nodes. In the latter case, be very sure that the virtual root nodes are + expanded programatically, since there will be no open/close button for the + user to open them. +*/ +qx.OO.addProperty({ name : "rootOpenClose", + type : "boolean", + defaultValue : true + }); + + +/* +--------------------------------------------------------------------------- + MANAGER BINDING +--------------------------------------------------------------------------- +*/ + +qx.Proto.getManager = function() { + return this._manager; +} + +qx.Proto.getSelectedElement = function() { + return this.getManager().getSelectedItems()[0]; +} + + + + + + +/* +--------------------------------------------------------------------------- + QUEUE HANDLING +--------------------------------------------------------------------------- +*/ + +qx.Proto.addChildToTreeQueue = function(vChild) +{ + if (!vChild._isInTreeQueue && !vChild._isDisplayable) { + this.debug("Ignoring invisible child: " + vChild); + } + + if (!vChild._isInTreeQueue && vChild._isDisplayable) + { + qx.ui.core.Widget.addToGlobalWidgetQueue(this); + + if (!this._treeQueue) { + this._treeQueue = {}; + } + + this._treeQueue[vChild.toHashCode()] = vChild; + + vChild._isInTreeQueue = true; + } +} + +qx.Proto.removeChildFromTreeQueue = function(vChild) +{ + if (vChild._isInTreeQueue) + { + if (this._treeQueue) { + delete this._treeQueue[vChild.toHashCode()]; + } + + delete vChild._isInTreeQueue; + } +} + +qx.Proto.flushWidgetQueue = function() { + this.flushTreeQueue(); +} + +qx.Proto.flushTreeQueue = function() +{ + if (!qx.lang.Object.isEmpty(this._treeQueue)) + { + for (var vHashCode in this._treeQueue) + { + // this.debug("Flushing Tree Child: " + this._treeQueue[vHashCode]); + this._treeQueue[vHashCode].flushTree(); + delete this._treeQueue[vHashCode]._isInTreeQueue; + } + + delete this._treeQueue; + } +} + + + + + + + +/* +--------------------------------------------------------------------------- + MODIFIER +--------------------------------------------------------------------------- +*/ + +qx.Proto._modifyUseTreeLines = function(propValue, propOldValue, propData) +{ + if (this._initialLayoutDone) { + this._updateIndent(); + } + + return true; +} + +qx.Proto._modifyHideNode = function(propValue, propOldValue, propData) +{ + if (! propValue) { + this._horizontalLayout.setHeight(this._horizontalLayout.originalHeight); + this._horizontalLayout.show(); + } else { + this._horizontalLayout.originalHeight = this._horizontalLayout.getHeight(); + this._horizontalLayout.setHeight(0); + this._horizontalLayout.hide(); + } + + if (this._initialLayoutDone) { + this._updateIndent(); + } + + return true; +} + +qx.Proto._modifyRootOpenClose = function(propValue, propOldValue, propData) +{ + if (this._initialLayoutDone) { + this._updateIndent(); + } + + return true; +} + +// Override getter so we can return a clone of the array. Otherwise, the +// setter finds the identical array (after user modifications) and the modify +// function doesn't get called. +qx.Proto.getExcludeSpecificTreeLines = function() +{ + var vName = "excludeSpecificTreeLines"; + var vUpName = qx.lang.String.toFirstUp(vName); + var vStorageField = "_value" + vUpName; + + return this[vStorageField].slice(0); +} + +qx.Proto._modifyExcludeSpecificTreeLines = function(propValue, + propOldValue, + propData) +{ + if (this._initialLayoutDone) { + this._updateIndent(); + } + + return true; +} + + + + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getTree = function() { + return this; +} + +qx.Proto.getParentFolder = function() { + return null; +} + +qx.Proto.getLevel = function() { + return 0; +} + + + + + + + + +/* +--------------------------------------------------------------------------- + COMMON CHECKERS +--------------------------------------------------------------------------- +*/ + +qx.ui.treefullcontrol.Tree.isTreeFolder = function(vObject) { + return (vObject && + vObject instanceof qx.ui.treefullcontrol.TreeFolder && + !(vObject instanceof qx.ui.treefullcontrol.Tree)); +} + +qx.ui.treefullcontrol.Tree.isOpenTreeFolder = function(vObject) { + return (vObject instanceof qx.ui.treefullcontrol.TreeFolder && + vObject.getOpen() && + vObject.hasContent()); +} + + + + + + + +/* +--------------------------------------------------------------------------- + EVENT HANDLER +--------------------------------------------------------------------------- +*/ + +qx.Proto._onkeydown = function(e) +{ + var vManager = this.getManager(); + var vSelectedItem = vManager.getSelectedItem(); + + if (e.getKeyIdentifier() == "Enter") + { + e.preventDefault(); + if (qx.ui.treefullcontrol.Tree.isTreeFolder(vSelectedItem)) { + return vSelectedItem.toggle(); + } + } +} + + +qx.Proto._onkeypress = function(e) +{ + var vManager = this.getManager(); + var vSelectedItem = vManager.getSelectedItem(); + + switch(e.getKeyIdentifier()) + { + case "Left": + e.preventDefault(); + + if (qx.ui.treefullcontrol.Tree.isTreeFolder(vSelectedItem)) + { + if (!vSelectedItem.getOpen()) + { + var vParent = vSelectedItem.getParentFolder(); + if (vParent instanceof qx.ui.treefullcontrol.TreeFolder) { + if (!(vParent instanceof qx.ui.treefullcontrol.Tree)) { + vParent.close(); + } + + this.setSelectedElement(vParent); + } + } + else + { + return vSelectedItem.close(); + } + } + else if (vSelectedItem instanceof qx.ui.treefullcontrol.TreeFile) + { + var vParent = vSelectedItem.getParentFolder(); + if (vParent instanceof qx.ui.treefullcontrol.TreeFolder) { + if (!(vParent instanceof qx.ui.treefullcontrol.Tree)) { + vParent.close(); + } + + this.setSelectedElement(vParent); + } + } + + break; + + case "Right": + e.preventDefault(); + + if (qx.ui.treefullcontrol.Tree.isTreeFolder(vSelectedItem)) + { + if (!vSelectedItem.getOpen()) + { + return vSelectedItem.open(); + } + else if (vSelectedItem.hasContent()) + { + var vFirst = vSelectedItem.getFirstVisibleChildOfFolder(); + this.setSelectedElement(vFirst); + + if (vFirst instanceof qx.ui.tree.TreeFolder) { + vFirst.open(); + } + + return; + } + } + + break; + + default: + if (!this._fastUpdate) + { + this._fastUpdate = true; + this._oldItem = vSelectedItem; + } + + vManager.handleKeyPress(e); + } +}; + + +qx.Proto._onkeyup = function(e) +{ + if (this._fastUpdate) + { + var vNewItem = this.getManager().getSelectedItem(); + + if (! vNewItem) { + return; + } + + vNewItem.getIconObject().addState("selected"); + + delete this._fastUpdate; + delete this._oldItem; + } +} + +qx.Proto.getLastTreeChild = function() +{ + var vLast = this; + + while (vLast instanceof qx.ui.treefullcontrol.AbstractTreeElement) + { + if (!(vLast instanceof qx.ui.treefullcontrol.TreeFolder) || + !vLast.getOpen()) { + return vLast; + } + + vLast = vLast.getLastVisibleChildOfFolder(); + } + + return null; +} + +qx.Proto.getFirstTreeChild = function() { + return this; +} + +qx.Proto.setSelectedElement = function(vElement) +{ + var vManager = this.getManager(); + + vManager.setSelectedItem(vElement); + vManager.setLeadItem(vElement); +} + +/* Override getHierarchy: do not add label if root node is hidden */ +qx.Proto.getHierarchy = function(vArr) +{ + if (! this.hideNode() && this._labelObject) { + vArr.unshift(this._labelObject.getHtml()); + } + return vArr; +} + + +qx.Proto.getIndentSymbol = function(vUseTreeLines, vColumn, vLastColumn) +{ + if (vColumn == vLastColumn && + (this.hasContent() || this.getAlwaysShowPlusMinusSymbol())) + { + if (! vUseTreeLines) + { + return this.getOpen() ? "minus" : "plus"; + } + else + { + return this.getOpen() ? "only_minus" : "only_plus"; + } + } + else + { + return null; + } +} + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + this.removeEventListener("keydown", this._onkeydown); + this.removeEventListener("keypress", this._onkeypress); + this.removeEventListener("keyup", this._onkeyup); + + if (this._manager) + { + this._manager.dispose(); + this._manager = null; + } + + delete this._oldItem; + + return qx.ui.treefullcontrol.TreeFolder.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFile.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFile.js new file mode 100644 index 0000000000..bf38a87c47 --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFile.js @@ -0,0 +1,81 @@ +/* ************************************************************************ + + qooxdoo - the new era of web development + + http://qooxdoo.org + + Copyright: + 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org + 2006 by Derrell Lipman + + License: + LGPL 2.1: http://www.gnu.org/licenses/lgpl.html + + Authors: + * Sebastian Werner (wpbasti) + * Andreas Ecker (ecker) + * Derrell Lipman (derrell) + +************************************************************************ */ + +/* ************************************************************************ + +#module(ui_treefullcontrol) + +************************************************************************ */ + +/** + * qx.ui.treefullcontrol.TreeFile objects are terminal tree rows (i.e. no + * sub-trees) + * + * @param + * treeRowStructure - + * An instance of qx.ui.treefullcontrol.TreeRowStructure, defining the + * structure of this tree row. + */ +qx.OO.defineClass("qx.ui.treefullcontrol.TreeFile", qx.ui.treefullcontrol.AbstractTreeElement, +function(treeRowStructure) +{ + qx.ui.treefullcontrol.AbstractTreeElement.call(this, treeRowStructure); +}); + + + + +/* +--------------------------------------------------------------------------- + INDENT HELPER +--------------------------------------------------------------------------- +*/ + +qx.Proto.getIndentSymbol = function(vUseTreeLines, + vColumn, + vFirstColumn, + vLastColumn) +{ + var vLevel = this.getLevel(); + var vExcludeList = this.getTree().getExcludeSpecificTreeLines(); + var vExclude = vExcludeList[vLastColumn - vColumn - 1]; + + if (vUseTreeLines && ! (vExclude === true)) + { + if (vColumn == vFirstColumn) + { + return this.isLastChild() ? "end" : "cross"; + } + else + { + return "line"; + } + } + + return null; +} + +qx.Proto._updateIndent = function() { + this.addToTreeQueue(); +} + +qx.Proto.getItems = function() { + return [this]; +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFolder.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFolder.js new file mode 100644 index 0000000000..93a50c27bd --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeFolder.js @@ -0,0 +1,651 @@ +/* ************************************************************************ + + qooxdoo - the new era of web development + + http://qooxdoo.org + + Copyright: + 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org + 2006 by Derrell Lipman + + License: + LGPL 2.1: http://www.gnu.org/licenses/lgpl.html + + Authors: + * Sebastian Werner (wpbasti) + * Andreas Ecker (ecker) + * Derrell Lipman (derrell) + +************************************************************************ */ + +/* ************************************************************************ + +#module(ui_treefullcontrol) + +************************************************************************ */ + +/** + * qx.ui.treefullcontrol.TreeFolder objects are tree rows which may contain + * sub-trees + * + * @param + * treeRowStructure - + * An instance of qx.ui.treefullcontrol.TreeRowStructure, defining the + * structure of this tree row. + * + * @event treeOpenWithContent {qx.event.type.DataEvent} + * @event treeOpenWhileEmpty {qx.event.type.DataEvent} + * @event treeClose {qx.event.type.DataEvent} + */ +qx.OO.defineClass("qx.ui.treefullcontrol.TreeFolder", qx.ui.treefullcontrol.AbstractTreeElement, +function(treeRowStructure) +{ + qx.ui.treefullcontrol.AbstractTreeElement.call(this, treeRowStructure); + + // Save the tree row field order. We'll need it to create children structure. + this._treeRowStructureFields = treeRowStructure._fields; + + this._iconObject.setAppearance("tree-folder-icon"); + this._labelObject.setAppearance("tree-folder-label"); + + this.addEventListener("dblclick", this._ondblclick); + + // Remapping of add/remove methods + this.add = this.addToFolder; + this.addBefore = this.addBeforeToFolder; + this.addAfter = this.addAfterToFolder; + this.addAt = this.addAtToFolder; + this.addAtBegin = this.addAtBeginToFolder; + this.addAtEnd = this.addAtEndToFolder; +}); + + + +/* +--------------------------------------------------------------------------- + PROPERTIES +--------------------------------------------------------------------------- +*/ + + +qx.OO.changeProperty({ name : "appearance", + type : "string", + defaultValue : "tree-folder" + }); + +qx.OO.changeProperty({ name : "icon", + type : "string" + }); + +qx.OO.changeProperty({ name : "iconSelected", + type : "string" + }); + +qx.OO.addProperty({ name : "open", + type : "boolean", + defaultValue : false + }); + +qx.OO.addProperty({ name : "alwaysShowPlusMinusSymbol", + type : "boolean", + defaultValue : false + }); + + + + +/* +--------------------------------------------------------------------------- + UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.hasContent = function() { + return (this._containerObject && + this._containerObject.getChildrenLength() > 0); +} + +qx.Proto.open = function() +{ + if (this.getOpen()) { + return; + } + + if (this.hasContent()) + { + // If there are listeners waiting for a treeOpenWithContent event... + if (this.getTree().hasEventListeners("treeOpenWithContent")) { + // ... then issue the event + this.getTree().dispatchEvent(new qx.event.type.DataEvent("treeOpenWithContent", this), true); + } + + this.getTopLevelWidget().setGlobalCursor("progress"); + qx.client.Timer.once(this._openCallback, this, 0); + } + else + { + // If there are listeners waiting for a treeOpenWithContent event... + if (this.getTree().hasEventListeners("treeOpenWhileEmpty")) { + // ... then issue the event + this.getTree().dispatchEvent(new qx.event.type.DataEvent("treeOpenWhileEmpty", this), true); + } + + this.setOpen(true); + } +} + +qx.Proto.close = function() +{ + // If there are listeners waiting for a treeClose event... + if (this.getTree().hasEventListeners("treeClose")) { + // ... then issue the event + this.getTree().dispatchEvent(new qx.event.type.DataEvent("treeClose", this), true); + } + + this.setOpen(false); +} + +qx.Proto.toggle = function() +{ + this.getOpen() ? this.close() : this.open(); +} + +qx.Proto._openCallback = function() +{ + this.setOpen(true); + qx.ui.core.Widget.flushGlobalQueues(); + this.getTopLevelWidget().setGlobalCursor(null); +} + + + + + + + + +/* +--------------------------------------------------------------------------- + CHILDREN HANDLING +--------------------------------------------------------------------------- +*/ + +qx.Proto._createChildrenStructure = function() +{ + this.setAppearance(this instanceof qx.ui.treefullcontrol.Tree + ? "tree-container" + : "tree-folder-container"); + + if (!this._horizontalLayout) + { + this.setOrientation("vertical"); + + // Create a horizontal layout for this tree row + this._horizontalLayout = new qx.ui.layout.HorizontalBoxLayout; + this._horizontalLayout.setWidth(null); + this._horizontalLayout.setParent(this); + this._horizontalLayout.setAnonymous(true); + this._horizontalLayout.setAppearance(this instanceof qx.ui.treefullcontrol.Tree + ? "tree" + : "tree-folder"); + + // Move the row fields into the horizontal layout + for (var i = 0; i < this._treeRowStructureFields.length; i++) + { + this._treeRowStructureFields[i].setParent(this._horizontalLayout); + } + + // We don't need the tree row structure any more. + this._treeRowStructureFields = null; + } + + if (!this._containerObject) + { + // Create a veritcal box layout for all of this folder's children + this._containerObject = new qx.ui.layout.VerticalBoxLayout; + this._containerObject.setWidth(null); + this._containerObject.setAnonymous(true); + + // it should be faster to first handle display, + // because the default display value is true and if we first + // setup the parent the logic do all to make the + // widget first visible and then, if the folder is not + // opened again invisible. + this._containerObject.setDisplay(this.getOpen()); + this._containerObject.setParent(this); + + // remap remove* functions + this.remapChildrenHandlingTo(this._containerObject); + } +} + +qx.Proto._handleChildMove = function(vChild, vRelationIndex, vRelationChild) +{ + if (vChild.isDisplayable()) + { + var vChildren = this._containerObject.getChildren(); + var vOldChildIndex = vChildren.indexOf(vChild); + + if (vOldChildIndex != -1) + { + if (vRelationChild) { + vRelationIndex = vChildren.indexOf(vRelationChild); + } + + if (vRelationIndex == vChildren.length-1) + { + vChild._updateIndent(); + + // Update indent of previous last child + this._containerObject.getLastVisibleChild()._updateIndent(); + } + else if (vChild._wasLastVisibleChild) + { + vChild._updateIndent(); + + // Update indent for new last child + var vPreviousSibling = vChild.getPreviousVisibleSibling(); + if (vPreviousSibling) { + vPreviousSibling._updateIndent(); + } + } + } + } +} + +qx.Proto.addToFolder = function() +{ + this._createChildrenStructure(); + + if (this._containerObject) { + return this._containerObject.add.apply(this._containerObject, arguments); + } +} + +qx.Proto.addBeforeToFolder = function(vChild, vBefore) +{ + this._createChildrenStructure(); + + if (this._containerObject) + { + this._handleChildMove(vChild, null, vBefore); + return this._containerObject.addBefore.apply(this._containerObject, + arguments); + } +} + +qx.Proto.addAfterToFolder = function(vChild, vAfter) +{ + this._createChildrenStructure(); + + if (this._containerObject) + { + this._handleChildMove(vChild, null, vAfter); + return this._containerObject.addAfter.apply(this._containerObject, + arguments); + } +} + +qx.Proto.addAtToFolder = function(vChild, vIndex) +{ + this._createChildrenStructure(); + + if (this._containerObject) + { + this._handleChildMove(vChild, vIndex); + return this._containerObject.addAt.apply(this._containerObject, arguments); + } +} + +qx.Proto.addAtBeginToFolder = function(vChild) { + return this.addAtToFolder(vChild, 0); +} + +qx.Proto.addAtEndToFolder = function(vChild) +{ + this._createChildrenStructure(); + + if (this._containerObject) + { + var vLast = this._containerObject.getLastChild(); + + if (vLast) + { + this._handleChildMove(vChild, null, vLast); + return this._containerObject.addAfter.call(this._containerObject, + vChild, + vLast); + } + else + { + return this.addAtBeginToFolder(vChild); + } + } +} + +qx.Proto._remappingChildTable = [ "remove", "removeAt", "removeAll" ]; + + + + + + +/* +--------------------------------------------------------------------------- + CHILDREN UTILITIES +--------------------------------------------------------------------------- +*/ + +qx.Proto.getContainerObject = function() +{ + return this._containerObject; +} + +qx.Proto.getHorizontalLayout = function() +{ + return this._horizontalLayout; +} + +qx.Proto.getFirstVisibleChildOfFolder = function() +{ + if (this._containerObject) { + return this._containerObject.getFirstChild(); + } +} + +qx.Proto.getLastVisibleChildOfFolder = function() +{ + if (this._containerObject) { + return this._containerObject.getLastChild(); + } +} + +qx.Proto.getItems = function() +{ + var a = [this]; + + if (this._containerObject) + { + var ch = this._containerObject.getVisibleChildren(); + + for (var i=0, chl=ch.length; i<chl; i++) { + a = a.concat(ch[i].getItems()); + } + } + + return a; +} + + + + + + + +/* +--------------------------------------------------------------------------- + MODIFIER +--------------------------------------------------------------------------- +*/ + +qx.Proto._evalCurrentIcon = function() +{ + if (this.getSelected()) { + return this.getIconSelected() || "icon/16/folder-open.png"; + } else { + return this.getIcon() || "icon/16/folder.png"; + } +} + +qx.Proto._modifyOpen = function(propValue, propOldValue, propData) +{ + // we need the whole indent process if certain tree lines are to be excluded + if (this.getTree().getExcludeSpecificTreeLines().length > 0) { + this._updateIndent(); + } else { + this._updateLastColumn(); + } + + if (this._containerObject) { + this._containerObject.setDisplay(propValue); + } + + return true; +} + +qx.Proto._modifyAlwaysShowPlusMinusSymbol = function(propValue, propOldValue, propData) +{ + var t = this.getTree(); + if (t) { + // we need the whole indent process if only certain tree lines are to be + // excluded + if (t.getExcludeSpecificTreeLines().length > 0) { + this._updateIndent(); + } else { + this._updateLastColumn(); + } + } + + return true; +} + +qx.Proto._updateLastColumn = function() +{ + if (this._indentObject) + { + var vElement = this._indentObject.getElement(); + + if (vElement && vElement.firstChild) { + vElement.firstChild.src = + (this.BASE_URI + + this.getIndentSymbol(this.getTree().getUseTreeLines(), 0, 0, 0) + + ".gif"); + } + } +} + + + + + + + +/* +--------------------------------------------------------------------------- + EVENT LISTENERS +--------------------------------------------------------------------------- +*/ + +qx.Proto._onmousedown = function(e) +{ + var vOriginalTarget = e.getOriginalTarget(); + + switch(vOriginalTarget) + { + case this._indentObject: + if (this._indentObject.getElement().firstChild == e.getDomTarget()) + { + this.getTree().getManager().handleMouseDown(this, e); + this.toggle(); + } + + break; + + case this._containerObject: + break; + + case this: + if (this._containerObject) { + break; + } + + // no break here + + default: + this.getTree().getManager().handleMouseDown(this, e); + } + + e.stopPropagation(); +} + +qx.Proto._onmouseup = function(e) +{ + var vOriginalTarget = e.getOriginalTarget(); + + switch(vOriginalTarget) + { + case this._indentObject: + case this._containerObject: + case this: + break; + + default: + if (!this.getTree().getUseDoubleClick()) { + this.open(); + } + } +} + +qx.Proto._ondblclick = function(e) +{ + if (!this.getTree().getUseDoubleClick()) { + return; + } + + this.toggle(); + e.stopPropagation(); +} + + + + + + + +/* +--------------------------------------------------------------------------- + INDENT HELPER +--------------------------------------------------------------------------- +*/ + +qx.Proto.getIndentSymbol = function(vUseTreeLines, + vColumn, + vFirstColumn, + vLastColumn) +{ + var vLevel = this.getLevel(); + var vExcludeList = this.getTree().getExcludeSpecificTreeLines(); + var vExclude = vExcludeList[vLastColumn - vColumn - 1]; + + if (vColumn == vFirstColumn) + { + if (this.hasContent() || this.getAlwaysShowPlusMinusSymbol()) + { + // If tree lines were not requested, don't display them + if (!vUseTreeLines) + { + return this.getOpen() ? "minus" : "plus"; + } + + + // If this is the first level under the root... + if (vLevel == 1) { + // ... and the root is not being displayed and this is the first + // child... + var vParentFolder = this.getParentFolder(); + if (vParentFolder && + !vParentFolder._horizontalLayout.getVisibility() && + this.isFirstChild()) + { + //... then if this is also the last (i.e. only) child, use no tree + // lines; otherwise, use descender lines but no ascender. + if (this.isLastChild() || vExclude === true) + { + return this.getOpen() ? "only_minus" : "only_plus"; + } + else + { + return this.getOpen() ? "start_minus" : "start_plus"; + } + } + } + + if (vExclude === true) + { + return this.getOpen() ? "only_minus" : "only_plus"; + } + else if (this.isLastChild()) + { + return this.getOpen() ? "end_minus" : "end_plus"; + } + else + { + return this.getOpen() ? "cross_minus" : "cross_plus"; + } + } + else if (vUseTreeLines && ! (vExclude === true)) + { + return this.isLastChild() ? "end" : "cross"; + } + } + else + { + if (vUseTreeLines && ! this.isLastChild()) { + if (vExclude === true) { + return null; + } + return "line"; + } + return null; + } +} + +qx.Proto._updateIndent = function() +{ + // Intentionally bypass superclass; the _updateIndent we want is in TreeFile + qx.ui.treefullcontrol.TreeFile.prototype._updateIndent.call(this); + + if (!this._containerObject) { + return; + } + + var ch = this._containerObject.getVisibleChildren(); + for (var i=0, l=ch.length; i<l; i++) { + ch[i]._updateIndent(); + } +} + + + + + + + +/* +--------------------------------------------------------------------------- + DISPOSER +--------------------------------------------------------------------------- +*/ + +qx.Proto.dispose = function() +{ + if (this.getDisposed()) { + return; + } + + this.removeEventListener("dblclick", this._ondblclick); + + if (this._horizontalLayout) + { + this._horizontalLayout.dispose(); + this._horizontalLayout = null; + } + + if (this._containerObject) + { + this._containerObject.dispose(); + this._containerObject = null; + } + + return qx.ui.treefullcontrol.AbstractTreeElement.prototype.dispose.call(this); +} diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeRowStructure.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeRowStructure.js new file mode 100644 index 0000000000..4fc32ef31e --- /dev/null +++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/treefullcontrol/TreeRowStructure.js @@ -0,0 +1,260 @@ +/* ************************************************************************ + + qooxdoo - the new era of web development + + http://qooxdoo.org + + Copyright: + 2006 by Derrell Lipman + + License: + LGPL 2.1: http://www.gnu.org/licenses/lgpl.html + + Authors: + * Derrell Lipman (derrell) + +************************************************************************ */ + +/* ************************************************************************ + +#module(ui_treefullcontrol) + +************************************************************************ */ + +/** + * The structure of a tree row. + * + * This is a singleton class. The constructor is not accessed by users; + * instead, to obtain the one and only TreeRowStructure object, call either + * + * qx.ui.treefullcontrol.TreeRowStructure.newRow() + * + * or + * + * qx.ui.treefullcontrol.TreeRowStructure.standard(). + * + * The structure of a tree row is provided by a + * qx.ui.treefullcontrol.TreeRowStructure. The order of elements added to + * this object is the order in which they will be presented in a tree row. + * + * The three standard parts of a tree: the indentation (and its associated + * tree-lines, if enabled), the icon (selected or unselected), and the label + * are added to the structure in the desired order by calling, respectively, + * the methods addIndent(), addIcon() and addLabel(). + * + * By default, indentation will appear at the beginning of the tree row. This + * can be changed by calling the addIndent() method after having calling other + * add*() methods on this object. If indentation is to be at the beginning of + * the tree row, simply do not call addIndent(). + * + * Any other object which is valid within a qx.ui.layout.HorizontalBoxLayout + * may be added to the structure using addObject(). If the object has no + * special treatment, it may be made anonymous with obj.SetAnonymous(true). + * Otherwise, all handling for the object should be done by the application. + * + * A "standard" (traditional) tree row would be generated like this: + * + * treeRowStructure = qx.ui.treefullcontrol.TreeRowStructure.standard("Trash"); + * + * which equates to issuing these commands: + * + * treeRowStructure = qx.ui.treefullcontrol.TreeRowStructure.newRow(); + * + * //treeRowStructure.addIndent() // defaults to here; no need to call + * treeRowStructure.addIcon(); + * treeRowStructure.addLabel("Trash"); + * + * The former method is typically preferred. + * + * An example of a more sophisticated structure: + * + * treeRowStructure = qx.ui.treefullcontrol.TreeRowStructure.newRow(); + * + * // A left-justified icon + * obj = new qx.ui.basic.Image("icon/16/alarm.png"); + * treeRowStructure.addObject(obj, true); + * + * // Here's our indentation and tree-lines + * treeRowStructure.addIndent(); + * + * // The standard tree icon follows + * treeRowStructure.addIcon("icon/16/desktop.png","icon/16/dictionary.png"); + * + * // Right after the tree icon is a checkbox + * obj = new qx.ui.form.CheckBox(null, 23, null, false); + * obj.setPadding(0, 0); + * treeRowStructure.addObject(obj, true); + * + * // The label + * treeRowStructure.addLabel("Trash"); + * + * // All else should be right justified + * obj = new qx.ui.basic.HorizontalSpacer; + * treeRowStructure.addObject(obj, true); + * + * // Add a file size, date and mode + * obj = new qx.ui.basic.Label("23kb"); + * obj.setWidth(50); + * treeRowStructure.addObject(obj, true); + * obj = new qx.ui.basic.Label("11 Sept 1959"); + * obj.setWidth(150); + * treeRowStructure.addObject(obj, true); + * obj = new qx.ui.basic.Label("-rw-r--r--"); + * obj.setWidth(80); + * treeRowStructure.addObject(obj, true); + */ + +qx.OO.defineClass("qx.ui.treefullcontrol.TreeRowStructure", qx.core.Object, +function() +{ + qx.core.Object.call(this); +}); + + +/** + * Prepare to define a new row. + * + * This reinitializes the singleton TreeRowStructure so that it is ready to + * define a new tree row. + * + * @return The singleton itself, purely for convenience. + */ +qx.Proto.newRow = function() +{ + /* Create the indent, icon, and label objects */ + this._indentObject = new qx.ui.embed.HtmlEmbed; + this._iconObject = new qx.ui.basic.Image; + this._labelObject = new qx.ui.basic.Label; + + /* Create an object to hold the ordering of row objects */ + this._fields = new Array; + + /* Create an object to hold the icon names */ + this._icons = new Object; + + /* Initially assume that indentation goes at the beginning of the row */ + this._fields.push(this._indentObject); + + /* Set initial flags */ + this._indentAdded = false; + this._iconAdded = false; + this._labelAdded = false; + + /* Return the singleton (from which we were called) */ + return this; +} + +/** + * Define a new row with the 'standard' structure. + * + * This reinitializes the singleton TreeRowStructure to the state of a + * standard'or traditional tree row: + * - indentation + * - icon + * - label + * + * The icon parameters may be omitted in which case the defaults will be + * used. If the label parameter is omitted, no label will appear. + * + * @param vLabel {string} The label text + * @param vIcon {string} Relative path to the 'non-selected' icon + * @param vIconSelected {string} Relative path to the 'selected' icon + * + * @return The singleton itself, purely for convenience. + */ +qx.Proto.standard = function(vLabel, vIcon, vIconSelected) +{ + this.newRow(); + this.addIcon(vIcon, vIconSelected); + this.addLabel(vLabel); + + return this; +} + +qx.Proto.addIndent = function() +{ + /* If the assumed indent object is in use... */ + if (! this._indentAdded) + { + /* ... then remove it. */ + this._fields.shift(); + this._indentAdded = true; + } + else + { + throw new Error("Indent object added more than once."); + } + + /* Add the indentation to the structure */ + this._fields.push(this._indentObject); +} + +qx.Proto.addIcon = function(vIcon, vIconSelected) +{ + /* Ensure only one standard icon is added */ + if (! this._iconAdded) + { + this._iconAdded = true; + } + else + { + throw new Error("Icon object added more than once."); + } + + /* Track the two icon names */ + this._icons.unselected = vIcon; + this._icons.selected = vIconSelected; + + /* Add the icon to the structure */ + this._fields.push(this._iconObject); +} + +qx.Proto.addLabel = function(vLabel) +{ + /* Ensure only one standard label is added */ + if (! this._labelAdded) + { + this._labelAdded = true; + } + else + { + throw new Error("Label added more than once."); + } + + /* Track the label text */ + this._label = vLabel; + + /* Add the label to the structure */ + this._fields.push(this._labelObject); +} + +/* + * Add an object to the tree row structure. For convenience, vAnonymous can + * be provided, and if a boolean value is provided, vObj.setAnonymous() is + * called with the provided value. If the object has already been + * setAnonymous or if there is no need to do so, then provide no value for + * vAnonymous or pass 'null'. + */ +qx.Proto.addObject = function(vObj, vAnonymous) +{ + /* Is requested, set this object's anonymous state */ + if (typeof vAnonymous == "boolean") + { + vObj.setAnonymous(vAnonymous); + } + + /* Add this user-specified object to the structure */ + this._fields.push(vObj); +} + + +/* +--------------------------------------------------------------------------- + DEFER SINGLETON INSTANCE +--------------------------------------------------------------------------- +*/ + +/** + * Singleton Instance Getter + */ +qx.Class.getInstance = qx.util.Return.returnInstance; |