/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml */ /** * Tree model does all the drawing, visual node management etc. * Throws events about clicks on it, so someone may catch them and process * Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller */ /** * TODO: use domNode.cloneNode instead of createElement for grid * Should be faster (lyxsus) */ dojo.provide("dojo.widget.Tree"); dojo.require("dojo.event.*"); dojo.require("dojo.io.*"); dojo.require("dojo.widget.HtmlWidget"); dojo.require("dojo.widget.TreeNode"); // make it a tag dojo.widget.tags.addParseTreeHandler("dojo:Tree"); dojo.widget.Tree = function() { dojo.widget.HtmlWidget.call(this); this.eventNames = {}; this.tree = this; this.DNDAcceptTypes = []; this.actionsDisabled = []; } dojo.inherits(dojo.widget.Tree, dojo.widget.HtmlWidget); dojo.lang.extend(dojo.widget.Tree, { widgetType: "Tree", eventNamesDefault: { // new child does not get domNode filled in (only template draft) // until addChild->createDOMNode is called(program way) OR createDOMNode (html-way) // hook events to operate on new DOMNode, create dropTargets etc createDOMNode: "createDOMNode", // tree created.. Perform tree-wide actions if needed treeCreate: "treeCreate", treeDestroy: "treeDestroy", // expand icon clicked treeClick: "treeClick", // node icon clicked iconClick: "iconClick", // node title clicked titleClick: "titleClick", moveFrom: "moveFrom", moveTo: "moveTo", addChild: "addChild", removeNode: "removeNode", expand: "expand", collapse: "collapse" }, isContainer: true, DNDMode: "off", lockLevel: 0, // lock ++ unlock --, so nested locking works fine strictFolders: true, DNDModes: { BETWEEN: 1, ONTO: 2 }, DNDAcceptTypes: "", templateCssPath: dojo.uri.dojoUri("src/widget/templates/images/Tree/Tree.css"), templateString: '
', isExpanded: true, // consider this "root node" to be always expanded isTree: true, objectId: "", // autoCreate if not "off" // used to get the autocreated controller ONLY. // generally, tree DOES NOT KNOW about its CONTROLLER, it just doesn't care // controller gets messages via dojo.event controller: "", // autoCreate if not "off" // used to get the autocreated selector ONLY. // generally, tree DOES NOT KNOW its SELECTOR // binding is made with dojo.event selector: "", // used ONLY at initialization time menu: "", // autobind menu if menu's widgetId is set here expandLevel: "", // expand to level automatically // // these icons control the grid and expando buttons for the whole tree // blankIconSrc: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_blank.gif"), gridIconSrcT: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_t.gif"), // for non-last child grid gridIconSrcL: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_l.gif"), // for last child grid gridIconSrcV: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_v.gif"), // vertical line gridIconSrcP: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_p.gif"), // for under parent item child icons gridIconSrcC: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_c.gif"), // for under child item child icons gridIconSrcX: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_x.gif"), // grid for sole root item gridIconSrcY: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_y.gif"), // grid for last rrot item gridIconSrcZ: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_grid_z.gif"), // for under root parent item child icon expandIconSrcPlus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_plus.gif"), expandIconSrcMinus: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_expand_minus.gif"), expandIconSrcLoading: dojo.uri.dojoUri("src/widget/templates/images/Tree/treenode_loading.gif"), iconWidth: 18, iconHeight: 18, // // tree options // showGrid: true, showRootGrid: true, actionIsDisabled: function(action) { var _this = this; return dojo.lang.inArray(_this.actionsDisabled, action) }, actions: { ADDCHILD: "ADDCHILD" }, getInfo: function() { var info = { widgetId: this.widgetId, objectId: this.objectId } return info; }, initializeController: function() { if (this.controller != "off") { if (this.controller) { this.controller = dojo.widget.byId(this.controller); } else { // create default controller here dojo.require("dojo.widget.TreeBasicController"); this.controller = dojo.widget.createWidget("TreeBasicController", { DNDController: (this.DNDMode ? "create" : ""), dieWithTree: true } ); } this.controller.listenTree(this); // controller listens to my events } else { this.controller = null; } }, initializeSelector: function() { if (this.selector != "off") { if (this.selector) { this.selector = dojo.widget.byId(this.selector); } else { // create default controller here dojo.require("dojo.widget.TreeSelector"); this.selector = dojo.widget.createWidget("TreeSelector", {dieWithTree: true}); } this.selector.listenTree(this); } else { this.selector = null; } }, initialize: function(args, frag){ var _this = this; for(name in this.eventNamesDefault) { if (dojo.lang.isUndefined(this.eventNames[name])) { this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name]; } } for(var i=0; i