Index: lams_common/src/flash/it/sephiroth/TreeDnd.as
===================================================================
diff -u
--- lams_common/src/flash/it/sephiroth/TreeDnd.as (revision 0)
+++ lams_common/src/flash/it/sephiroth/TreeDnd.as (revision 888c4202eadf7a4a065b3fbc6bcda0cf5353e206)
@@ -0,0 +1,588 @@
+import it.sephiroth.iTreeDnd
+import mx.events.EventDispatcher
+import mx.core.UIComponent
+
+
+[Event("double_click")]
+[Event("drag_start")]
+[Event("drag_complete")]
+[Event("drag_fail")]
+[InspectableList("enabled","visible","dragRules","rowHeight")]
+
+
+/**
+ * Drag and Drop extension for Macromedia Tree component.
+ * It allows you to define different rules for dragging items and folder
+ * into a tree component
+ * @author alessandro crugnola
+ * @version 1.5
+ */
+class it.sephiroth.TreeDnd extends UIComponent implements iTreeDnd
+{
+ // define component specific variables
+ static var symbolName:String = "TreeDnd"
+ static var symbolOwner:Object = TreeDnd
+ private var className:String = "TreeDnd"
+
+ static var componentVersion:String = "1.5";
+ // define private variables
+ private var label:MovieClip
+ private var tree:mx.controls.Tree
+ private var icon:MovieClip
+ private var tree_listener:Object
+ private var controller_mc:MovieClip
+ private var boundingBox_mc:MovieClip
+ private var tfList:Object
+ private var __dropTarget:Array
+ private var _iconFunction:Function
+ private var __rowHeight:Number = 20
+ private var __dropFunction:Function
+ private var __dragFunction:Function
+
+ private var TREEDEPTH:Number = 10
+ private var CONTDEPTH:Number = 11
+ private var ICONDEPTH:Number = 12
+
+ var addEventListener:Function
+ var removeEventListener:Function
+ var dispatchEvent:Function
+
+ /**
+ * deny drag a folder.
+ * Each of treednd constant can be used associated with multiple other constants
+ * @usage import it.sephiroth.TreeDnd
+ * myDndTree.dragRules = TreeDnd.DENYDRAGFOLDER | TreeDnd.DENYDROPITEM
+ *
+ */
+ static var DENYDRAGFOLDER:Number = 1
+ /** deny drag an item node */
+ static var DENYDRAGITEM:Number = 2
+ /** deny drop into an item */
+ static var DENYDROPITEM:Number = 4
+ /** everything is allowed */
+ static var DEFAULT:Number = 0
+ /** deny drop through nodes, only into is allowed */
+ static var DENYDROPUPSIDEDOWN:Number = 8
+ /** deny all */
+ static var DENYALL:Number = DENYDRAGITEM | DENYDRAGFOLDER | DENYDROPITEM | DENYDROPUPSIDEDOWN
+
+ private var __options:Number = DEFAULT
+
+ /**
+ * constructor
+ */
+ function TreeDnd()
+ {
+ }
+
+ /**
+ * internal, set enabled on off
+ * @param enabled
+ */
+ private function setEnabled(enabled:Boolean):Void
+ {
+ super.setEnabled();
+ tree.enabled = enabled
+ }
+
+ // ******************************************
+ // Private methods
+ // ******************************************
+
+ /**
+ * override UIComponent init constructor
+ * @return Void
+ */
+ private function init():Void
+ {
+ super.init();
+ var width = __width
+ var height = __height
+ __options = DEFAULT
+ boundingBox_mc._visible = false
+ boundingBox_mc._width = boundingBox_mc._height = 0;
+ // create the objects to be used in the component
+ createClassObject(mx.controls.Tree, "tree", TREEDEPTH, {_width : width, _height : height})
+ controller_mc = createEmptyObject("controller_mc", CONTDEPTH);
+ // initialize the event object
+ EventDispatcher.initialize( this );
+ initTreeListener();
+ setEnabled(enabled)
+ tree.rowHeight = __rowHeight
+ }
+
+
+ /**
+ *
+ * @param Void
+ * @return Void
+ */
+ function size(Void) : Void
+ {
+ super.size();
+ tree.setSize( __width, __height, true );
+ }
+
+
+ /**
+ *
+ * @param Void
+ * @return Void
+ */
+ function draw(Void):Void{
+ super.draw();
+ }
+
+ /**
+ * Initialize Tree listeners and Tree MovieClip controller
+ * @usage
+ * @return Void
+ */
+ private function initTreeListener():Void
+ {
+ // Tree listeners
+ tfList = new Object();
+ tfList.selectedItem = undefined
+ tfList.selectedIndex = undefined
+ tfList._parent = this
+ tfList._time = getTimer();
+ tfList._oldItem = undefined
+ // tree itemRollOver
+ tfList.itemRollOver = function( evt ){
+ var item = this._parent.tree.getItemAt(evt.index)
+ if( item != undefined )
+ {
+ var opt:Number = this._parent.dragRules
+ var opt_1:Number = opt
+ if(opt >= TreeDnd.DENYDROPUPSIDEDOWN){
+ opt_1 = opt ^ TreeDnd.DENYDROPUPSIDEDOWN
+ }
+ if( this._parent.__dragFunction != undefined){
+ if(!this._parent.__dragFunction( item )){
+ this.itemRollOut()
+ return
+ }
+ } else {
+ if( (opt_1 == DENYDRAGFOLDER or opt_1 == (DENYDRAGFOLDER | DENYDROPITEM) or opt_1 == (DENYDRAGITEM | DENYDRAGFOLDER) or opt == DENYALL) and this._parent.tree.getIsBranch( item ))
+ {
+ this.itemRollOut()
+ return
+ } else if( !this._parent.tree.getIsBranch( item ) and (opt_1 == DENYDRAGITEM or opt == DENYALL or opt_1 == (DENYDRAGITEM | DENYDROPITEM) or opt_1 == (DENYDRAGITEM | DENYDRAGFOLDER)))
+ {
+ this.itemRollOut()
+ return
+ }
+ }
+ this.selectedItem = item
+ this.selectedIndex = evt.index
+ } else {
+ this.itemRollOut();
+ }
+ }
+
+ // tree itemRollOut
+ tfList.itemRollOut = function(evt:Object)
+ {
+ this.selectedItem = undefined
+ this.selectedIndex = undefined
+ }
+
+ tfList.change = function( evt:Object)
+ {
+ if( (getTimer() - this._time) < 300)
+ {
+ if( evt.target.selectedItem == this._oldItem)
+ {
+ this._parent.dispatchEvent({type:"double_click", target: this._parent.tree});
+ }
+ }
+ this._oldItem = evt.target.selectedItem
+ this._time = getTimer()
+ }
+
+ // add tree listeners
+ tree.addEventListener("change", tfList)
+ tree.addEventListener("itemRollOver", tfList)
+ tree.addEventListener("itemRollOut", tfList)
+
+ // controller functions
+ controller_mc.tree = tree
+ controller_mc.item = undefined
+ controller_mc.index = undefined
+ controller_mc.__canDrop = false
+ controller_mc.__canDropTarget = false
+ controller_mc.__dropTargetMc = undefined
+ controller_mc.__dropIndex = undefined
+ controller_mc.__targetNode = undefined
+ controller_mc.__dragStart = false
+ controller_mc.onMouseDown = function(){
+ this.__dragStart = false
+ this.item = this._parent.tfList.selectedItem
+ this.index = this._parent.tfList.selectedIndex
+ this.added = false
+ this.__targetNode = undefined
+ this.points = new Array( this._xmouse, this._ymouse);
+ if( this.item == undefined ){
+ return;
+ }
+ this.onEnterFrame = function(){
+ /**
+ * canDrop:
+ * -1 => deny always
+ * 0 => deny if dropIndex == undefined
+ * 1 => allow
+ */
+ this.clear();
+ var canDrop:Number = -1
+ var dropIndex:Number = undefined
+ var opt:Number = this._parent.dragRules
+ var opt_1:Number = opt
+ this.__canDropTarget = false
+ this.__dropTargetMc = undefined
+ if(opt >= TreeDnd.DENYDROPUPSIDEDOWN){
+ opt_1 = opt ^ TreeDnd.DENYDROPUPSIDEDOWN
+ }
+ var targetLabel:Boolean = false
+ var default_icon:String
+ var point:Object = new Object()
+ point.x = this._parent._xmouse
+ point.y = this._parent._ymouse
+ this._parent.localToGlobal( point )
+ if( !this.added ){
+ var x = this._xmouse
+ var y = this._ymouse
+ if(Math.abs( x - this.points[0] ) > 2 or Math.abs( y - this.points[1] ) > 2 ){
+ if( !this.added and this.item != undefined ){
+ this.__dragStart = true
+ this.added = true
+ this._parent.createIcon( )
+ this._parent.dispatchEvent({type:"drag_start", target:this.tree, sourceNode: this.item});
+ }
+ }
+ } else {
+ for(var a = 0; a < this.tree.rows.length; a++)
+ {
+ if( this.tree.rows[a].item != undefined)
+ {
+ //if( this.tree.rows[a].hitTest( this._parent._xmouse, this._parent._ymouse, true) )
+ if( this.tree.rows[a].hitTest( point.x, point.y, true) )
+ {
+ var item = this.tree.rows[a]
+ this.__targetNode = item
+ if( item.item == this.item ){
+ // if the same item, then DENY
+ canDrop = 0;
+ // If trying to DROP an item inside itself, DENY
+ } else if ( this._parent.isSubNode(this.item , item.item ) ){
+ canDrop = -1;
+ } else {
+ if( this._parent.__dropFunction != undefined ){
+ canDrop = this._parent.__dropFunction( this.item, this.__targetNode.node )
+ } else {
+ canDrop = 1;
+ // now core functions..
+ // check if item can be dropped and where it will be dropped!
+ // deny drop into item 3,4,5,6,7
+ if( (opt_1 >= (DENYDRAGITEM | DENYDRAGFOLDER) and opt <= DENYALL) and !this.tree.getIsBranch( item.node )){
+ if( opt == DENYALL ){
+ canDrop = -1
+ } else {
+ canDrop = 0;
+ }
+ }
+ }
+ }
+ if( item._ymouse > ((item.bG_mc._height/2) + item.bG_mc._height/4) and opt < DENYDROPUPSIDEDOWN && (this._parent.tree._ymouse + item._height < this._parent.tree._height))
+ {
+ this.beginFill(this._parent.getStyle("separatorColor") ? this._parent.getStyle("separatorColor") : 0x666666,100)
+ this.drawRect( 0, item._y + item.bG_mc._height, this._parent.tree.width - (this._parent.tree.vSB.width ? this._parent.tree.vSB.width : 0) - 1, item._y + item.bG_mc._height + 1 )
+ this.endFill();
+ // try to retrieve the item index
+ if( this.tree.getIsBranch( item.node ) )
+ {
+ if( this.tree.getIsOpen( item.node ))
+ {
+ // it's the first element of the branch
+ dropIndex = item.rowIndex
+ }
+ }
+ dropIndex = item.rowIndex
+ }
+ break;
+ }
+ }
+ }
+ // Now apply permissions to dragging icon
+ if( canDrop == 1 )
+ {
+ targetLabel = true
+ this.__canDrop = true
+ } else if(canDrop == 0)
+ {
+ if(dropIndex == undefined)
+ {
+ targetLabel = false
+ this.__canDrop = false
+ } else {
+ targetLabel = true
+ this.__canDrop = true
+ }
+ } else {
+ targetLabel = false
+ this.__canDrop = false
+ }
+ this.__dropIndex = dropIndex
+ default_icon = this._parent._iconFunction( targetLabel )
+
+ // dropTarget
+ if(this._parent.dropTarget != undefined){
+ for(var a in this._parent.dropTarget){
+ if(this._parent.dropTarget[a].hitTest(point.x, point.y, true))
+ {
+ targetLabel = true
+ this.__canDropTarget = true
+ this.__dropTargetMc = this._parent.dropTarget[a]
+ break;
+ }
+ }
+ }
+
+ if( default_icon == undefined )
+ {
+ default_icon = targetLabel ? "icon_allow_drag" : "icon_deny_drag"
+ }
+ if( this._parent.icon[default_icon]._name != default_icon or this._parent.icon[default_icon] == undefined)
+ {
+ this._parent.icon.attachMovie( default_icon, default_icon , 1 )
+ }
+ }
+
+ var _mouseP = new Object();
+ _mouseP.x = this._parent._xmouse
+ _mouseP.y = this._parent._ymouse
+ //this._parent.globalToLocal( _mouseP )
+ this._parent.icon._x = _mouseP.x + 5
+ this._parent.icon._y = _mouseP.y + 15
+ }
+ this.onEnterFrame();
+ }
+
+ /**
+ * mouse up, drag and drop end
+ */
+ controller_mc.onMouseUp = function(){
+ delete this.onEnterFrame
+ if( this.__dragStart != true ){
+ return;
+ }
+ if( this.__canDrop == true )
+ {
+ var node = this.tree.getItemAt(this.index)
+ var cloned = node.cloneNode(true)
+ if( this.__dropIndex != undefined )
+ {
+ if( this.tree.getIsBranch( this.__targetNode.item ) and this.tree.getIsOpen( this.__targetNode.item ))
+ {
+ node.removeNode()
+ this.__targetNode.item.addTreeNodeAt(0, cloned )
+ } else {
+ if(this.__targetNode.item.nextSibling == null)
+ {
+ node.removeNode()
+ this.__targetNode.item.parentNode.addTreeNode( cloned )
+ } else {
+ if( node != this.__targetNode.item and node != this.__targetNode.item.nextSibling ) // fix by TAKATAMA, Hirokazu
+ {
+ node.removeNode()
+ this.__targetNode.item.parentNode.insertBefore( cloned, this.__targetNode.item.nextSibling )
+ this.tree.refresh()
+ }
+ }
+ }
+ } else {
+ node.removeNode()
+ this.__targetNode.item.addTreeNode( cloned )
+ }
+ this._parent.dispatchEvent({type:"drag_complete", target: this.tree, sourceNode: node, targetNode: this.__targetNode.item})
+ this.tree.dataProvider = this.tree.getDataProvider()
+ } else {
+ this._parent.dispatchEvent({type:"drag_fail", target: this.tree, sourceNode: node, targetNode: this.__targetNode.item})
+ }
+ if(this.__canDropTarget == true){
+ var node = this.tree.getItemAt(this.index)
+ this._parent.dispatchEvent({type:"drag_target", target: this.tree, sourceNode: node, targetMc: this.__dropTargetMc})
+ }
+ this.clear();
+ this.__canDrop = false
+ this.__dropIndex = undefined
+ this._parent.removeIcon()
+ this.points = new Array();
+ this.item = undefined
+ this.index = undefined
+ this.added = false
+ }
+ }
+
+
+ /**
+ * Internal, remove the dragging mouse icon
+ * @usage
+ * @return Void
+ */
+ private function removeIcon():Void
+ {
+ icon.removeMovieClip();
+ }
+
+
+ /**
+ * internal, create the dragging icon attaching from library
+ * @usage
+ * @return MovieClip
+ */
+ private function createIcon():MovieClip
+ {
+ return createEmptyObject( "icon", ICONDEPTH );
+ }
+
+
+ /**
+ * Verify that targetNode is a subnode of dragNode
+ * @usage TreeDnd.isSubNode( sourceNode, targetNode )
+ * @param dragNode (XMLNode)
+ * @param targetNode (XMLNode)
+ * @return Boolean
+ */
+ private function isSubNode( dragNode:XMLNode, targetNode:XMLNode):Boolean
+ {
+ var ret:Boolean = false;
+ while( targetNode.parentNode != undefined)
+ {
+ if(targetNode == dragNode)
+ {
+ ret = true;
+ break;
+ }
+ targetNode = targetNode.parentNode
+ }
+ return ret;
+ }
+
+
+ // ******************************************
+ // Getter / Setter
+ // ******************************************
+
+ /**
+ * Set the Tree Drag and Drop rules
+ * @usage TreeDnd.dragRules = TreeDnd.DENYDRAGITEM | TreeDnd.DENYDROPITEM
+ * @param value (Number)
+ * @return Void
+ */
+ [Inspectable(defaultValue=0,type=Number)]
+ public function set dragRules(value:Number)
+ {
+ if(value >= 0 and value <= DENYALL and value != undefined)
+ {
+ __options = value
+ } else {
+ throw new Error("IndexError: value must be an integer between " + DEFAULT + " and " + DENYALL);
+ }
+ /**
+ 0 DEFAULT -> Allow everything
+ 1 DENYDRAGFOLDER -> DENY drag folders
+ 2 DENYDRAGITEM -> DENY drag items
+ 4 DENYDROPITEM -> DENY drop into items
+ 5 DENYDRAGFOLDER | DENYDROPITEM -> Deny Drag folder & deny drop on items
+ 6 DENYDRAGITEM | DENYDROPITEM -> Deny drag item & deny drop item
+ 7 DENYALL -> Deny All
+ 3 DENYDRAGITEM | DENYDRAGFOLDER -> Deny All
+ 8 DENYDROPUPSIDEDOWN -> deny lines
+ */
+ }
+
+ /**
+ * return the current drag rules
+ * @usage
+ * @return Number
+ */
+ public function get dragRules():Number
+ {
+ return __options
+ }
+
+ // set icon function for display allow/deny dragging icon
+ public function set iconFunction(func:Function)
+ {
+ _iconFunction = func
+ }
+
+ public function get iconFunction():Function
+ {
+ return _iconFunction
+ }
+
+ // ******************************************
+ // Tree public functions
+ // ******************************************
+
+ /**
+ * Return a pointer to the current used Tree component
+ * @usage
+ * @return mx.controls.Tree the tree component used
+ */
+ public function getTree():mx.controls.Tree
+ {
+ return this.tree
+ }
+
+ public function set dropTarget(mc:Array):Void
+ {
+ this.__dropTarget = mc
+ }
+
+ public function get dropTarget():Array
+ {
+ return this.__dropTarget
+ }
+
+ [Inspectable(defaultValue=20,type=Number)]
+ public function set rowHeight(w:Number)
+ {
+ __rowHeight = w
+ this.tree.rowHeight = w
+ }
+
+ public function get rowHeight():Number
+ {
+ return __rowHeight
+ }
+
+ /**
+ * set a user defined drop function,
+ * this function must return a boolean
+ * @usage
+ * myDndTree.dropFunction = function(sourceNode:XMLNode, targetNode:XMLNode){
+ // in this way you can define a custom dragRule
+ * return sourceNode.attributes.name != targetNode.attributes.value
+ * }
+ *
+ */
+ public function set dropFunction(fn:Function){
+ __dropFunction = fn
+ }
+
+ /**
+ * user defined drag function, which decide if item
+ * can be dragged
+ * @usage
+ * myDndTree.dragFunction = function(item:XMLNode){
+ * return item.attributes.myattribue == 'some value'
+ * }
+ *
+ */
+ public function set dragFunction(fn:Function){
+ __dragFunction = fn
+ }
+
+}
\ No newline at end of file
Index: lams_common/src/flash/it/sephiroth/XML2Object.as
===================================================================
diff -u
--- lams_common/src/flash/it/sephiroth/XML2Object.as (revision 0)
+++ lams_common/src/flash/it/sephiroth/XML2Object.as (revision 888c4202eadf7a4a065b3fbc6bcda0cf5353e206)
@@ -0,0 +1,114 @@
+/**
+* @class it.sephiroth.XML2Object
+* @author Alessandro Crugnola
+
+* @version 1.0
+* @description return an object with the content of the XML translated
+
+* If a node has more than 1 child with the same name, an array is created with the children contents
+
+* The object created will have this structure:
+
+* - obj {
+
+* nodeName : {
+
+* attributes : an object containing the node attributes
+
+* data : an object containing the node contents
+
+* }
+
+* @usage data = new XML2Object().parseXML( anXML);
+*/
+class it.sephiroth.XML2Object extends XML {
+ private var oResult:Object = new Object ();
+ private var oXML:XML;
+
+ /**
+
+ * @method get xml
+
+ * @description return the xml passed in the parseXML method
+
+ * @usage theXML = XML2Object.xml
+
+ */
+ public function get xml():XML{
+ return oXML
+ }
+ /**
+ * @method public parseXML
+
+ * @description return the parsed Object
+
+ * @usage XML2Object.parseXML( theXMLtoParse );
+
+ * @param sFile XML
+
+ * @returns an Object with the contents of the passed XML
+ */
+ public function parseXML (sFile:XML):Object {
+ this.oResult = new Object ();
+ this.oXML = sFile;
+ this.oResult = this.translateXML();
+ return this.oResult;
+ }
+ /**
+ * @method private translateXML
+
+ * @description core of the XML2Object class
+ */
+ private function translateXML (from, path, name, position) {
+ var nodes, node, old_path;
+ if (path == undefined) {
+ path = this;
+ name = "oResult";
+ }
+ path = path[name];
+ if (from == undefined) {
+ from = new XML (this.xml);
+ from.ignoreWhite = true;
+ }
+ if (from.hasChildNodes ()) {
+ nodes = from.childNodes;
+ if (position != undefined) {
+ var old_path = path;
+ path = path[position];
+ }
+ while (nodes.length > 0) {
+ node = nodes.shift ();
+ if (node.nodeName != undefined) {
+ var __obj__ = new Object ();
+ __obj__.attributes = node.attributes;
+ __obj__.data = node.firstChild.nodeValue;
+ if (position != undefined) {
+ var old_path = path;
+ }
+ if (path[node.nodeName] != undefined) {
+ if (path[node.nodeName].__proto__ == Array.prototype) {
+ path[node.nodeName].push (__obj__);
+ name = node.nodeName;
+ position = path[node.nodeName].length - 1;
+ } else {
+ var copyObj = path[node.nodeName];
+ path[node.nodeName] = new Array ();
+ path[node.nodeName].push (copyObj);
+ path[node.nodeName].push (__obj__);
+ name = node.nodeName;
+ position = path[node.nodeName].length - 1;
+ }
+ } else {
+ path[node.nodeName] = __obj__;
+ name = node.nodeName;
+ position = undefined;
+ }
+ }
+ if (node.hasChildNodes ()) {
+ this.translateXML (node, path, name, position);
+ }
+ }
+ }
+ return this.oResult;
+ }
+}
Index: lams_common/src/flash/it/sephiroth/XML2Object_doc.html
===================================================================
diff -u
--- lams_common/src/flash/it/sephiroth/XML2Object_doc.html (revision 0)
+++ lams_common/src/flash/it/sephiroth/XML2Object_doc.html (revision 888c4202eadf7a4a065b3fbc6bcda0cf5353e206)
@@ -0,0 +1,88 @@
+
+
+
it.sephiroth.XML2Object Documentation
+ + +Author: Alessandro Crugnola
+
+ Last Modified: 01/20/04 12:51:09
Summary
+it.sephiroth.XML2Object Class:
+ +it.sephiroth.XML2Object Methods:
version: 1.0
+description:
+return an object with the content of the XML translated
+If a node has more than 1 child with the same name, an array is created with the children contents
+The object created will have this structure:
+ - obj {
+ nodeName : {
+ attributes : an object containing the node attributes
+ data : an object containing the node contents
+ }
+
usage:
data = new XML2Object().parseXML( anXML); + + +it.sephiroth.XML2Object Methods:
+description: + return the parsed Object +
+usage: XML2Object.parseXML( theXMLtoParse ); +
+parameters:
returns: an Object with the contents of the passed XML +
+ + +description: + core of the XML2Object class +
+usage: Documentation not provided.
+returns: Void.
+