Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,519 @@ +/* + 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 +*/ + +dojo.provide("dojo.dnd.HtmlDragAndDrop"); + +dojo.require("dojo.dnd.HtmlDragManager"); +dojo.require("dojo.dnd.DragAndDrop"); + +dojo.require("dojo.html.*"); +dojo.require("dojo.html.display"); +dojo.require("dojo.html.util"); +dojo.require("dojo.html.selection"); +dojo.require("dojo.html.iframe"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.lfx.*"); +dojo.require("dojo.event.*"); + +dojo.declare("dojo.dnd.HtmlDragSource", dojo.dnd.DragSource, { + dragClass: "", // CSS classname(s) applied to node when it is being dragged + + onDragStart: function(){ + var dragObj = new dojo.dnd.HtmlDragObject(this.dragObject, this.type); + if(this.dragClass){ + dragObj.dragClass = this.dragClass; + } + + if(this.constrainToContainer){ + dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode); + } + + return dragObj; + }, + + setDragHandle: function(node){ + node = dojo.byId(node); + dojo.dnd.dragManager.unregisterDragSource(this); + this.domNode = node; + dojo.dnd.dragManager.registerDragSource(this); + }, + + setDragTarget: function(node){ + this.dragObject = node; + }, + + constrainTo: function(container){ + this.constrainToContainer = true; + if(container){ + this.constrainingContainer = container; + } + }, + + /* + * + * see dojo.dnd.DragSource.onSelected + */ + onSelected: function(){ + for(var i=0; i<this.dragObjects.length; i++){ + dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragSource(this.dragObjects[i])); + } + }, + + /** + * Register elements that should be dragged along with + * the actual DragSource. + * + * Example usage: + * var dragSource = new dojo.dnd.HtmlDragSource(...); + * // add a single element + * dragSource.addDragObjects(dojo.byId('id1')); + * // add multiple elements to drag along + * dragSource.addDragObjects('id2', dojo.byId('id3')); + * + * el A dom node to add to the drag list. + */ + addDragObjects: function(/*DOMNode*/ el){ + for(var i=0; i<arguments.length; i++){ + this.dragObjects.push(dojo.byId(arguments[i])); + } + } + }, + + function(node, type){ + node = dojo.byId(node); + this.dragObjects = []; + this.constrainToContainer = false; + if(node){ + this.domNode = node; + this.dragObject = node; + // set properties that might have been clobbered by the mixin + this.type = (type)||(this.domNode.nodeName.toLowerCase()); + dojo.dnd.DragSource.prototype.reregister.call(this); + } + } +); + +dojo.declare("dojo.dnd.HtmlDragObject", + dojo.dnd.DragObject, + { + dragClass: "", + opacity: 0.5, + createIframe: true, // workaround IE6 bug + + // if true, node will not move in X and/or Y direction + disableX: false, + disableY: false, + + createDragNode: function() { + var node = this.domNode.cloneNode(true); + if(this.dragClass) { dojo.html.addClass(node, this.dragClass); } + if(this.opacity < 1) { dojo.html.setOpacity(node, this.opacity); } + var ltn = node.tagName.toLowerCase(); + var isTr = (ltn == "tr"); + if((isTr)||(ltn == "tbody")){ + // dojo.debug("Dragging table row") + // Create a table for the cloned row + var doc = this.domNode.ownerDocument; + var table = doc.createElement("table"); + if(isTr){ + var tbody = doc.createElement("tbody"); + table.appendChild(tbody); + tbody.appendChild(node); + }else{ + table.appendChild(node); + } + + // Set a fixed width to the cloned TDs + var tmpSrcTr = ((isTr) ? this.domNode : this.domNode.firstChild); + var tmpDstTr = ((isTr) ? node : node.firstChild); + var domTds = tdp.childNodes; + var cloneTds = tmpDstTr.childNodes; + for(var i = 0; i < domTds.length; i++){ + if((cloneTds[i])&&(cloneTds[i].style)){ + cloneTds[i].style.width = dojo.html.getContentBox(domTds[i]).width + "px"; + } + } + node = table; + } + + if((dojo.render.html.ie55||dojo.render.html.ie60) && this.createIframe){ + with(node.style) { + top="0px"; + left="0px"; + } + var outer = document.createElement("div"); + outer.appendChild(node); + this.bgIframe = new dojo.html.BackgroundIframe(outer); + outer.appendChild(this.bgIframe.iframe); + node = outer; + } + node.style.zIndex = 999; + + return node; + }, + + onDragStart: function(e){ + dojo.html.clearSelection(); + + this.scrollOffset = dojo.html.getScroll().offset; + this.dragStartPosition = dojo.html.getAbsolutePosition(this.domNode, true); + + this.dragOffset = {y: this.dragStartPosition.y - e.pageY, + x: this.dragStartPosition.x - e.pageX}; + + this.dragClone = this.createDragNode(); + + this.containingBlockPosition = this.domNode.offsetParent ? + dojo.html.getAbsolutePosition(this.domNode.offsetParent, true) : {x:0, y:0}; + + if(this.constrainToContainer){ + this.constraints = this.getConstraints(); + } + + // set up for dragging + with(this.dragClone.style){ + position = "absolute"; + top = this.dragOffset.y + e.pageY + "px"; + left = this.dragOffset.x + e.pageX + "px"; + } + + dojo.body().appendChild(this.dragClone); + + dojo.event.topic.publish('dragStart', { source: this } ); + }, + + /** Return min/max x/y (relative to document.body) for this object) **/ + getConstraints: function(){ + if(this.constrainingContainer.nodeName.toLowerCase() == 'body'){ + var viewport = dojo.html.getViewport(); + var width = viewport.width; + var height = viewport.height; + var scroll = dojo.html.getScroll().offset; + var x = scroll.x; + var y = scroll.y; + }else{ + var content = dojo.html.getContentBox(this.constrainingContainer); + width = content.width; + height = content.height; + x = + this.containingBlockPosition.x + + dojo.html.getPixelValue(this.constrainingContainer, "padding-left", true) + + dojo.html.getBorderExtent(this.constrainingContainer, "left"); + y = + this.containingBlockPosition.y + + dojo.html.getPixelValue(this.constrainingContainer, "padding-top", true) + + dojo.html.getBorderExtent(this.constrainingContainer, "top"); + } + + // TODO: should handle left/top/right/bottom margin separately; left/top should affect minX/minY + var mb = dojo.html.getMarginBox(this.domNode); + return { + minX: x, + minY: y, + maxX: x + width - mb.width, + maxY: y + height - mb.height + } + }, + + updateDragOffset: function(){ + var scroll = dojo.html.getScroll().offset; + if(scroll.y != this.scrollOffset.y){ + var diff = scroll.y - this.scrollOffset.y; + this.dragOffset.y += diff; + this.scrollOffset.y = scroll.y; + } + if(scroll.x != this.scrollOffset.x){ + var diff = scroll.x - this.scrollOffset.x; + this.dragOffset.x += diff; + this.scrollOffset.x = scroll.x; + } + }, + + /** Moves the node to follow the mouse */ + onDragMove: function(e){ + this.updateDragOffset(); + var x = this.dragOffset.x + e.pageX; + var y = this.dragOffset.y + e.pageY; + + if (this.constrainToContainer) { + if (x < this.constraints.minX) { x = this.constraints.minX; } + if (y < this.constraints.minY) { y = this.constraints.minY; } + if (x > this.constraints.maxX) { x = this.constraints.maxX; } + if (y > this.constraints.maxY) { y = this.constraints.maxY; } + } + + this.setAbsolutePosition(x, y); + + dojo.event.topic.publish('dragMove', { source: this } ); + }, + + /** + * Set the position of the drag clone. (x,y) is relative to <body>. + */ + setAbsolutePosition: function(x, y){ + // The drag clone is attached to document.body so this is trivial + if(!this.disableY) { this.dragClone.style.top = y + "px"; } + if(!this.disableX) { this.dragClone.style.left = x + "px"; } + }, + + + /** + * If the drag operation returned a success we remove the clone of + * ourself from the original position. If the drag operation returned + * failure we slide back over to where we came from and end the operation + * with a little grace. + */ + onDragEnd: function(e){ + switch(e.dragStatus){ + + case "dropSuccess": + dojo.html.removeNode(this.dragClone); + this.dragClone = null; + break; + + case "dropFailure": // slide back to the start + var startCoords = dojo.html.getAbsolutePosition(this.dragClone, true); + // offset the end so the effect can be seen + var endCoords = { left: this.dragStartPosition.x + 1, + top: this.dragStartPosition.y + 1}; + + // animate + var anim = dojo.lfx.slideTo(this.dragClone, endCoords, 300); + var dragObject = this; + dojo.event.connect(anim, "onEnd", function(e){ + // pause for a second (not literally) and disappear + // dojo.lang.setTimeout(function() { + dojo.html.removeNode(dragObject.dragClone); + // Allow drag clone to be gc'ed + dragObject.dragClone = null; + // }, + // 50); + }); + anim.play(); + break; + } + + dojo.event.topic.publish('dragEnd', { source: this } ); + }, + + constrainTo: function(container){ + this.constrainToContainer=true; + if(container){ + this.constrainingContainer = container; + }else{ + this.constrainingContainer = this.domNode.parentNode; + } + } + }, + function(node, type){ + this.domNode = dojo.byId(node); + this.type = type; + this.constrainToContainer = false; + this.dragSource = null; + // this.register(); + dojo.dnd.DragObject.prototype.register.call(this); + } +); + +dojo.declare("dojo.dnd.HtmlDropTarget", + dojo.dnd.DropTarget, + { + vertical: false, + onDragOver: function(e){ + if(!this.accepts(e.dragObjects)){ return false; } + + // cache the positions of the child nodes + this.childBoxes = []; + for(var i = 0, child; i < this.domNode.childNodes.length; i++){ + child = this.domNode.childNodes[i]; + if(child.nodeType != dojo.html.ELEMENT_NODE){ continue; } + var pos = dojo.html.getAbsolutePosition(child, true); + var inner = dojo.html.getBorderBox(child); + this.childBoxes.push({top: pos.y, bottom: pos.y+inner.height, + left: pos.x, right: pos.x+inner.width, height: inner.height, + width: inner.width, node: child}); + } + + // TODO: use dummy node + + return true; + }, + + _getNodeUnderMouse: function(e){ + // find the child + for(var i = 0, child; i < this.childBoxes.length; i++){ + with(this.childBoxes[i]){ + if (e.pageX >= left && e.pageX <= right && + e.pageY >= top && e.pageY <= bottom){ return i; } + } + } + + return -1; + }, + + createDropIndicator: function(){ + this.dropIndicator = document.createElement("div"); + with(this.dropIndicator.style){ + position = "absolute"; + zIndex = 999; + if(this.vertical){ + borderLeftWidth = "1px"; + borderLeftColor = "black"; + borderLeftStyle = "solid"; + height = dojo.html.getBorderBox(this.domNode).height + "px"; + top = dojo.html.getAbsolutePosition(this.domNode, true).y + "px"; + }else{ + borderTopWidth = "1px"; + borderTopColor = "black"; + borderTopStyle = "solid"; + width = dojo.html.getBorderBox(this.domNode).width + "px"; + left = dojo.html.getAbsolutePosition(this.domNode, true).x + "px"; + } + } + }, + + onDragMove: function(e, dragObjects){ + var i = this._getNodeUnderMouse(e); + + if(!this.dropIndicator){ + this.createDropIndicator(); + } + + var gravity = this.vertical ? dojo.html.gravity.WEST : dojo.html.gravity.NORTH; + var hide = false; + if(i < 0){ + if(this.childBoxes.length){ + var before = (dojo.html.gravity(this.childBoxes[0].node, e) & gravity); + if(before){ hide = true; } + }else{ + var before = true; + } + }else{ + var child = this.childBoxes[i]; + var before = (dojo.html.gravity(child.node, e) & gravity); + if(child.node === dragObjects[0].dragSource.domNode){ + hide = true; + }else{ + var currentPosChild = before ? + (i>0?this.childBoxes[i-1]:child) : + (i<this.childBoxes.length-1?this.childBoxes[i+1]:child); + if(currentPosChild.node === dragObjects[0].dragSource.domNode){ + hide = true; + } + } + } + + if(hide){ + this.dropIndicator.style.display="none"; + return; + }else{ + this.dropIndicator.style.display=""; + } + + this.placeIndicator(e, dragObjects, i, before); + + if(!dojo.html.hasParent(this.dropIndicator)) { + dojo.body().appendChild(this.dropIndicator); + } + }, + + /** + * Position the horizontal line that indicates "insert between these two items" + */ + placeIndicator: function(e, dragObjects, boxIndex, before) { + var targetProperty = this.vertical ? "left" : "top"; + var child; + if(boxIndex < 0){ + if(this.childBoxes.length){ + child = before ? this.childBoxes[0] + : this.childBoxes[this.childBoxes.length - 1]; + }else{ + this.dropIndicator.style[targetProperty] = dojo.html.getAbsolutePosition(this.domNode, true)[this.vertical?"x":"y"] + "px"; + } + }else{ + child = this.childBoxes[boxIndex]; + } + if(child){ + this.dropIndicator.style[targetProperty] = (before ? child[targetProperty] : child[this.vertical?"right":"bottom"]) + "px"; + if(this.vertical){ + this.dropIndicator.style.height = child.height + "px"; + this.dropIndicator.style.top = child.top + "px"; + }else{ + this.dropIndicator.style.width = child.width + "px"; + this.dropIndicator.style.left = child.left + "px"; + } + } + }, + + onDragOut: function(e) { + if(this.dropIndicator) { + dojo.html.removeNode(this.dropIndicator); + delete this.dropIndicator; + } + }, + + /** + * Inserts the DragObject as a child of this node relative to the + * position of the mouse. + * + * @return true if the DragObject was inserted, false otherwise + */ + onDrop: function(e){ + this.onDragOut(e); + + var i = this._getNodeUnderMouse(e); + + var gravity = this.vertical ? dojo.html.gravity.WEST : dojo.html.gravity.NORTH; + if(i < 0){ + if(this.childBoxes.length){ + if(dojo.html.gravity(this.childBoxes[0].node, e) & gravity){ + return this.insert(e, this.childBoxes[0].node, "before"); + }else{ + return this.insert(e, this.childBoxes[this.childBoxes.length-1].node, "after"); + } + } + return this.insert(e, this.domNode, "append"); + } + + var child = this.childBoxes[i]; + if(dojo.html.gravity(child.node, e) & gravity){ + return this.insert(e, child.node, "before"); + }else{ + return this.insert(e, child.node, "after"); + } + }, + + insert: function(e, refNode, position){ + var node = e.dragObject.domNode; + + if(position == "before"){ + return dojo.html.insertBefore(node, refNode); + }else if(position == "after"){ + return dojo.html.insertAfter(node, refNode); + }else if(position == "append"){ + refNode.appendChild(node); + return true; + } + + return false; + } + }, + + function(node, types){ + if(arguments.length == 0){ return; } + this.domNode = dojo.byId(node); + dojo.dnd.DropTarget.call(this); + if(types && dojo.lang.isString(types)) { + types = [types]; + } + this.acceptedTypes = types || []; + dojo.dnd.dragManager.registerDropTarget(this); + } +); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragAndDrop.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,85 @@ +/* + 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 +*/ + +dojo.provide("dojo.dnd.HtmlDragCopy"); +dojo.require("dojo.dnd.*"); + +dojo.declare("dojo.dnd.HtmlDragCopySource", dojo.dnd.HtmlDragSource, +function(node, type, copyOnce){ + this.copyOnce = copyOnce; + this.makeCopy = true; +}, +{ + onDragStart: function(){ + var dragObj = new dojo.dnd.HtmlDragCopyObject(this.dragObject, this.type, this); + if(this.dragClass) { dragObj.dragClass = this.dragClass; } + + if (this.constrainToContainer) { + dragObj.constrainTo(this.constrainingContainer || this.domNode.parentNode); + } + + return dragObj; + }, + onSelected: function() { + for (var i=0; i<this.dragObjects.length; i++) { + dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragCopySource(this.dragObjects[i])); + } + } +}); + +dojo.declare("dojo.dnd.HtmlDragCopyObject", dojo.dnd.HtmlDragObject, +function(dragObject, type, source){ + this.copySource = source; +}, +{ + onDragStart: function(e) { + dojo.dnd.HtmlDragCopyObject.superclass.onDragStart.apply(this, arguments); + if(this.copySource.makeCopy) { + this.sourceNode = this.domNode; + this.domNode = this.domNode.cloneNode(true); + } + }, + onDragEnd: function(e){ + switch(e.dragStatus){ + case "dropFailure": // slide back to the start + var startCoords = dojo.html.getAbsolutePosition(this.dragClone, true); + // offset the end so the effect can be seen + var endCoords = { left: this.dragStartPosition.x + 1, + top: this.dragStartPosition.y + 1}; + + // animate + var anim = dojo.lfx.slideTo(this.dragClone, endCoords, 500, dojo.lfx.easeOut); + var dragObject = this; + dojo.event.connect(anim, "onEnd", function (e) { + // pause for a second (not literally) and disappear + dojo.lang.setTimeout(function() { + dojo.html.removeNode(dragObject.dragClone); + dragObject.dragClone = null; + if(dragObject.copySource.makeCopy) { + dojo.html.removeNode(dragObject.domNode); + dragObject.domNode = dragObject.sourceNode; + dragObject.sourceNode = null; + } + }, + 200); + }); + anim.play(); + dojo.event.topic.publish('dragEnd', { source: this } ); + return; + } + dojo.dnd.HtmlDragCopyObject.superclass.onDragEnd.apply(this, arguments); + this.copySource.dragObject = this.domNode; + if(this.copySource.copyOnce){ + this.copySource.makeCopy = false; + } + new dojo.dnd.HtmlDragCopySource(this.sourceNode, this.type, this.copySource.copyOnce); + this.sourceNode = null; + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragCopy.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,506 @@ +/* + 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 +*/ + +dojo.provide("dojo.dnd.HtmlDragManager"); +dojo.require("dojo.dnd.DragAndDrop"); +dojo.require("dojo.event.*"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.html.common"); +dojo.require("dojo.html.layout"); + +// NOTE: there will only ever be a single instance of HTMLDragManager, so it's +// safe to use prototype properties for book-keeping. +dojo.declare("dojo.dnd.HtmlDragManager", dojo.dnd.DragManager, { + /** + * There are several sets of actions that the DnD code cares about in the + * HTML context: + * 1.) mouse-down -> + * (draggable selection) + * (dragObject generation) + * mouse-move -> + * (draggable movement) + * (droppable detection) + * (inform droppable) + * (inform dragObject) + * mouse-up + * (inform/destroy dragObject) + * (inform draggable) + * (inform droppable) + * 2.) mouse-down -> mouse-down + * (click-hold context menu) + * 3.) mouse-click -> + * (draggable selection) + * shift-mouse-click -> + * (augment draggable selection) + * mouse-down -> + * (dragObject generation) + * mouse-move -> + * (draggable movement) + * (droppable detection) + * (inform droppable) + * (inform dragObject) + * mouse-up + * (inform draggable) + * (inform droppable) + * 4.) mouse-up + * (clobber draggable selection) + */ + disabled: false, // to kill all dragging! + nestedTargets: false, + mouseDownTimer: null, // used for click-hold operations + dsCounter: 0, + dsPrefix: "dojoDragSource", + + // dimension calculation cache for use durring drag + dropTargetDimensions: [], + + currentDropTarget: null, + // currentDropTargetPoints: null, + previousDropTarget: null, + _dragTriggered: false, + + selectedSources: [], + dragObjects: [], + dragSources: [], + + // mouse position properties + currentX: null, + currentY: null, + lastX: null, + lastY: null, + mouseDownX: null, + mouseDownY: null, + threshold: 7, + + dropAcceptable: false, + + cancelEvent: function(e){ e.stopPropagation(); e.preventDefault();}, + + // method over-rides + registerDragSource: function(ds){ + //dojo.profile.start("register DragSource"); + + if(ds["domNode"]){ + // FIXME: dragSource objects SHOULD have some sort of property that + // references their DOM node, we shouldn't just be passing nodes and + // expecting it to work. + //dojo.profile.start("register DragSource 1"); + var dp = this.dsPrefix; + var dpIdx = dp+"Idx_"+(this.dsCounter++); + ds.dragSourceId = dpIdx; + this.dragSources[dpIdx] = ds; + ds.domNode.setAttribute(dp, dpIdx); + //dojo.profile.end("register DragSource 1"); + + //dojo.profile.start("register DragSource 2"); + + // so we can drag links + if(dojo.render.html.ie){ + //dojo.profile.start("register DragSource IE"); + + dojo.event.browser.addListener(ds.domNode, "ondragstart", this.cancelEvent); + // terribly slow + //dojo.event.connect(ds.domNode, "ondragstart", this.cancelEvent); + //dojo.profile.end("register DragSource IE"); + + } + //dojo.profile.end("register DragSource 2"); + + } + //dojo.profile.end("register DragSource"); + }, + + unregisterDragSource: function(ds){ + if (ds["domNode"]){ + var dp = this.dsPrefix; + var dpIdx = ds.dragSourceId; + delete ds.dragSourceId; + delete this.dragSources[dpIdx]; + ds.domNode.setAttribute(dp, null); + if(dojo.render.html.ie){ + dojo.event.browser.removeListener(ds.domNode, "ondragstart", this.cancelEvent); + } + } + }, + + registerDropTarget: function(dt){ + this.dropTargets.push(dt); + }, + + unregisterDropTarget: function(dt){ + var index = dojo.lang.find(this.dropTargets, dt, true); + if (index>=0) { + this.dropTargets.splice(index, 1); + } + }, + + /** + * Get the DOM element that is meant to drag. + * Loop through the parent nodes of the event target until + * the element is found that was created as a DragSource and + * return it. + * + * @param event object The event for which to get the drag source. + */ + getDragSource: function(e){ + var tn = e.target; + if(tn === dojo.body()){ return; } + var ta = dojo.html.getAttribute(tn, this.dsPrefix); + while((!ta)&&(tn)){ + tn = tn.parentNode; + if((!tn)||(tn === dojo.body())){ return; } + ta = dojo.html.getAttribute(tn, this.dsPrefix); + } + return this.dragSources[ta]; + }, + + onKeyDown: function(e){ + }, + + onMouseDown: function(e){ + if(this.disabled) { return; } + + // only begin on left click + if(dojo.render.html.ie) { + if(e.button != 1) { return; } + } else if(e.which != 1) { + return; + } + + var target = e.target.nodeType == dojo.html.TEXT_NODE ? + e.target.parentNode : e.target; + + // do not start drag involvement if the user is interacting with + // a form element. + if(dojo.html.isTag(target, "button", "textarea", "input", "select", "option")) { + return; + } + + // find a selection object, if one is a parent of the source node + var ds = this.getDragSource(e); + + // this line is important. if we aren't selecting anything then + // we need to return now, so preventDefault() isn't called, and thus + // the event is propogated to other handling code + if(!ds){ return; } + + if(!dojo.lang.inArray(this.selectedSources, ds)){ + this.selectedSources.push(ds); + ds.onSelected(); + } + + this.mouseDownX = e.pageX; + this.mouseDownY = e.pageY; + + // Must stop the mouse down from being propogated, or otherwise can't + // drag links in firefox. + // WARNING: preventing the default action on all mousedown events + // prevents user interaction with the contents. + e.preventDefault(); + + dojo.event.connect(document, "onmousemove", this, "onMouseMove"); + }, + + onMouseUp: function(e, cancel){ + // if we aren't dragging then ignore the mouse-up + // (in particular, don't call preventDefault(), because other + // code may need to process this event) + if(this.selectedSources.length==0){ + return; + } + + this.mouseDownX = null; + this.mouseDownY = null; + this._dragTriggered = false; + // e.preventDefault(); + e.dragSource = this.dragSource; + // let ctrl be used for multiselect or another action + // if I use same key to trigger treeV3 node selection and here, + // I have bugs with drag'n'drop. why ?? no idea.. + if((!e.shiftKey)&&(!e.ctrlKey)){ + //if(!e.shiftKey){ + if(this.currentDropTarget) { + this.currentDropTarget.onDropStart(); + } + dojo.lang.forEach(this.dragObjects, function(tempDragObj){ + var ret = null; + if(!tempDragObj){ return; } + if(this.currentDropTarget) { + e.dragObject = tempDragObj; + + // NOTE: we can't get anything but the current drop target + // here since the drag shadow blocks mouse-over events. + // This is probelematic for dropping "in" something + var ce = this.currentDropTarget.domNode.childNodes; + if(ce.length > 0){ + e.dropTarget = ce[0]; + while(e.dropTarget == tempDragObj.domNode){ + e.dropTarget = e.dropTarget.nextSibling; + } + }else{ + e.dropTarget = this.currentDropTarget.domNode; + } + if(this.dropAcceptable){ + ret = this.currentDropTarget.onDrop(e); + }else{ + this.currentDropTarget.onDragOut(e); + } + } + + e.dragStatus = this.dropAcceptable && ret ? "dropSuccess" : "dropFailure"; + // decouple the calls for onDragEnd, so they don't block the execution here + // ie. if the onDragEnd would call an alert, the execution here is blocked until the + // user has confirmed the alert box and then the rest of the dnd code is executed + // while the mouse doesnt "hold" the dragged object anymore ... and so on + dojo.lang.delayThese([ + function() { + // in FF1.5 this throws an exception, see + // http://dojotoolkit.org/pipermail/dojo-interest/2006-April/006751.html + try{ + tempDragObj.dragSource.onDragEnd(e) + } catch(err) { + // since the problem seems passing e, we just copy all + // properties and try the copy ... + var ecopy = {}; + for (var i in e) { + if (i=="type") { // the type property contains the exception, no idea why... + ecopy.type = "mouseup"; + continue; + } + ecopy[i] = e[i]; + } + tempDragObj.dragSource.onDragEnd(ecopy); + } + } + , function() {tempDragObj.onDragEnd(e)}]); + }, this); + + this.selectedSources = []; + this.dragObjects = []; + this.dragSource = null; + if(this.currentDropTarget) { + this.currentDropTarget.onDropEnd(); + } + } else { + //dojo.debug("special click"); + } + + dojo.event.disconnect(document, "onmousemove", this, "onMouseMove"); + this.currentDropTarget = null; + }, + + onScroll: function(){ + //dojo.profile.start("DNDManager updateoffset"); + for(var i = 0; i < this.dragObjects.length; i++) { + if(this.dragObjects[i].updateDragOffset) { + this.dragObjects[i].updateDragOffset(); + } + } + //dojo.profile.end("DNDManager updateoffset"); + + // TODO: do not recalculate, only adjust coordinates + if (this.dragObjects.length) { + this.cacheTargetLocations(); + } + }, + + _dragStartDistance: function(x, y){ + if((!this.mouseDownX)||(!this.mouseDownX)){ + return; + } + var dx = Math.abs(x-this.mouseDownX); + var dx2 = dx*dx; + var dy = Math.abs(y-this.mouseDownY); + var dy2 = dy*dy; + return parseInt(Math.sqrt(dx2+dy2), 10); + }, + + cacheTargetLocations: function(){ + dojo.profile.start("cacheTargetLocations"); + + this.dropTargetDimensions = []; + dojo.lang.forEach(this.dropTargets, function(tempTarget){ + var tn = tempTarget.domNode; + //only cache dropTarget which can accept current dragSource + if(!tn || !tempTarget.accepts([this.dragSource])){ return; } + var abs = dojo.html.getAbsolutePosition(tn, true); + var bb = dojo.html.getBorderBox(tn); + this.dropTargetDimensions.push([ + [abs.x, abs.y], // upper-left + // lower-right + [ abs.x+bb.width, abs.y+bb.height ], + tempTarget + ]); + //dojo.debug("Cached for "+tempTarget) + }, this); + + dojo.profile.end("cacheTargetLocations"); + + //dojo.debug("Cache locations") + }, + + onMouseMove: function(e){ + if((dojo.render.html.ie)&&(e.button != 1)){ + // Oooops - mouse up occurred - e.g. when mouse was not over the + // window. I don't think we can detect this for FF - but at least + // we can be nice in IE. + this.currentDropTarget = null; + this.onMouseUp(e, true); + return; + } + + // if we've got some sources, but no drag objects, we need to send + // onDragStart to all the right parties and get things lined up for + // drop target detection + + if( (this.selectedSources.length)&& + (!this.dragObjects.length) ){ + var dx; + var dy; + if(!this._dragTriggered){ + this._dragTriggered = (this._dragStartDistance(e.pageX, e.pageY) > this.threshold); + if(!this._dragTriggered){ return; } + dx = e.pageX - this.mouseDownX; + dy = e.pageY - this.mouseDownY; + } + + // the first element is always our dragSource, if there are multiple + // selectedSources (elements that move along) then the first one is the master + // and for it the events will be fired etc. + this.dragSource = this.selectedSources[0]; + + dojo.lang.forEach(this.selectedSources, function(tempSource){ + if(!tempSource){ return; } + var tdo = tempSource.onDragStart(e); + if(tdo){ + tdo.onDragStart(e); + + // "bump" the drag object to account for the drag threshold + tdo.dragOffset.y += dy; + tdo.dragOffset.x += dx; + tdo.dragSource = tempSource; + + this.dragObjects.push(tdo); + } + }, this); + + /* clean previous drop target in dragStart */ + this.previousDropTarget = null; + + this.cacheTargetLocations(); + } + + // FIXME: we need to add dragSources and dragObjects to e + dojo.lang.forEach(this.dragObjects, function(dragObj){ + if(dragObj){ dragObj.onDragMove(e); } + }); + + // if we have a current drop target, check to see if we're outside of + // it. If so, do all the actions that need doing. + if(this.currentDropTarget){ + //dojo.debug(dojo.html.hasParent(this.currentDropTarget.domNode)) + var c = dojo.html.toCoordinateObject(this.currentDropTarget.domNode, true); + // var dtp = this.currentDropTargetPoints; + var dtp = [ + [c.x,c.y], [c.x+c.width, c.y+c.height] + ]; + } + + if((!this.nestedTargets)&&(dtp)&&(this.isInsideBox(e, dtp))){ + if(this.dropAcceptable){ + this.currentDropTarget.onDragMove(e, this.dragObjects); + } + }else{ + // FIXME: need to fix the event object! + // see if we can find a better drop target + var bestBox = this.findBestTarget(e); + + if(bestBox.target === null){ + if(this.currentDropTarget){ + this.currentDropTarget.onDragOut(e); + this.previousDropTarget = this.currentDropTarget; + this.currentDropTarget = null; + // this.currentDropTargetPoints = null; + } + this.dropAcceptable = false; + return; + } + + if(this.currentDropTarget !== bestBox.target){ + if(this.currentDropTarget){ + this.previousDropTarget = this.currentDropTarget; + this.currentDropTarget.onDragOut(e); + } + this.currentDropTarget = bestBox.target; + // this.currentDropTargetPoints = bestBox.points; + e.dragObjects = this.dragObjects; + this.dropAcceptable = this.currentDropTarget.onDragOver(e); + + }else{ + if(this.dropAcceptable){ + this.currentDropTarget.onDragMove(e, this.dragObjects); + } + } + } + }, + + findBestTarget: function(e) { + var _this = this; + var bestBox = new Object(); + bestBox.target = null; + bestBox.points = null; + dojo.lang.every(this.dropTargetDimensions, function(tmpDA) { + if(!_this.isInsideBox(e, tmpDA)){ + return true; + } + + bestBox.target = tmpDA[2]; + bestBox.points = tmpDA; + // continue iterating only if _this.nestedTargets == true + return Boolean(_this.nestedTargets); + }); + + return bestBox; + }, + + isInsideBox: function(e, coords){ + if( (e.pageX > coords[0][0])&& + (e.pageX < coords[1][0])&& + (e.pageY > coords[0][1])&& + (e.pageY < coords[1][1]) ){ + return true; + } + return false; + }, + + onMouseOver: function(e){ + }, + + onMouseOut: function(e){ + } +}); + +dojo.dnd.dragManager = new dojo.dnd.HtmlDragManager(); + +// global namespace protection closure +(function(){ + var d = document; + var dm = dojo.dnd.dragManager; + //TODO: when focus manager is ready, dragManager should be rewritten to use it + // set up event handlers on the document (or no?) + dojo.event.connect(d, "onkeydown", dm, "onKeyDown"); + dojo.event.connect(d, "onmouseover", dm, "onMouseOver"); + dojo.event.connect(d, "onmouseout", dm, "onMouseOut"); + dojo.event.connect(d, "onmousedown", dm, "onMouseDown"); + dojo.event.connect(d, "onmouseup", dm, "onMouseUp"); + // TODO: process scrolling of elements, not only window (focus manager would + // probably come to rescue here as well) + dojo.event.connect(window, "onscroll", dm, "onScroll"); +})(); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragManager.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,89 @@ +/* + 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 +*/ + +dojo.provide("dojo.dnd.HtmlDragMove"); +dojo.require("dojo.dnd.*"); + +dojo.declare("dojo.dnd.HtmlDragMoveSource", dojo.dnd.HtmlDragSource, { + onDragStart: function(){ + var dragObj = new dojo.dnd.HtmlDragMoveObject(this.dragObject, this.type); + if (this.constrainToContainer) { + dragObj.constrainTo(this.constrainingContainer); + } + return dragObj; + }, + /* + * see dojo.dnd.HtmlDragSource.onSelected + */ + onSelected: function() { + for (var i=0; i<this.dragObjects.length; i++) { + dojo.dnd.dragManager.selectedSources.push(new dojo.dnd.HtmlDragMoveSource(this.dragObjects[i])); + } + } +}); + +dojo.declare("dojo.dnd.HtmlDragMoveObject", dojo.dnd.HtmlDragObject, { + onDragStart: function(e){ + dojo.html.clearSelection(); + + this.dragClone = this.domNode; + + // Record drag start position, where "position" is simply the top/left style values for + // the node (the meaning of top/left is dependent on whether node is position:absolute or + // position:relative, and also on the container). + // Not sure if we should support moving nodes that aren't position:absolute, + // but supporting it for now + if(dojo.html.getComputedStyle(this.domNode, 'position') != 'absolute'){ + this.domNode.style.position = "relative"; + } + var left = parseInt(dojo.html.getComputedStyle(this.domNode, 'left')); + var top = parseInt(dojo.html.getComputedStyle(this.domNode, 'top')); + this.dragStartPosition = { + x: isNaN(left) ? 0 : left, + y: isNaN(top) ? 0 : top + }; + + this.scrollOffset = dojo.html.getScroll().offset; + + // used to convert mouse position into top/left value for node + this.dragOffset = {y: this.dragStartPosition.y - e.pageY, + x: this.dragStartPosition.x - e.pageX}; + + // since the DragObject's position is relative to the containing block, for our purposes + // the containing block's position is just (0,0) + this.containingBlockPosition = {x:0, y:0}; + + if (this.constrainToContainer) { + this.constraints = this.getConstraints(); + } + + // shortly the browser will fire an onClick() event, + // but since this was really a drag, just squelch it + dojo.event.connect(this.domNode, "onclick", this, "_squelchOnClick"); + }, + + onDragEnd: function(e){ + }, + + setAbsolutePosition: function(x, y){ + // summary: Set the top & left style attributes of the drag node (TODO: function is poorly named) + if(!this.disableY) { this.domNode.style.top = y + "px"; } + if(!this.disableX) { this.domNode.style.left = x + "px"; } + }, + + _squelchOnClick: function(e){ + // summary + // this function is called to squelch this onClick() event because + // it's the result of a drag (ie, it's not a real click) + + dojo.event.browser.stopEvent(e); + dojo.event.disconnect(this.domNode, "onclick", this, "_squelchOnClick"); + } +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/HtmlDragMove.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,28 @@ +/* + 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 +*/ + +dojo.provide("dojo.dnd.Sortable"); +dojo.require("dojo.dnd.*"); + +dojo.dnd.Sortable = function () {} + +dojo.lang.extend(dojo.dnd.Sortable, { + + ondragstart: function (e) { + var dragObject = e.target; + while (dragObject.parentNode && dragObject.parentNode != this) { + dragObject = dragObject.parentNode; + } + // TODO: should apply HtmlDropTarget interface to self + // TODO: should apply HtmlDragObject interface? + return dragObject; + } + +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/Sortable.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,475 @@ +/* + 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 +*/ + +/** + * TreeDrag* specialized on managing subtree drags + * It selects nodes and visualises what's going on, + * but delegates real actions upon tree to the controller + * + * This code is considered a part of controller +*/ + +dojo.provide("dojo.dnd.TreeDragAndDrop"); + +dojo.require("dojo.dnd.HtmlDragAndDrop"); +dojo.require("dojo.lang.func"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.html.layout"); + +dojo.dnd.TreeDragSource = function(node, syncController, type, treeNode){ + this.controller = syncController; + this.treeNode = treeNode; + + dojo.dnd.HtmlDragSource.call(this, node, type); +} + +dojo.inherits(dojo.dnd.TreeDragSource, dojo.dnd.HtmlDragSource); + +dojo.lang.extend(dojo.dnd.TreeDragSource, { + onDragStart: function(){ + /* extend adds functions to prototype */ + var dragObject = dojo.dnd.HtmlDragSource.prototype.onDragStart.call(this); + //dojo.debugShallow(dragObject) + + dragObject.treeNode = this.treeNode; + + dragObject.onDragStart = dojo.lang.hitch(dragObject, function(e) { + + /* save selection */ + this.savedSelectedNode = this.treeNode.tree.selector.selectedNode; + if (this.savedSelectedNode) { + this.savedSelectedNode.unMarkSelected(); + } + + var result = dojo.dnd.HtmlDragObject.prototype.onDragStart.apply(this, arguments); + + + /* remove background grid from cloned object */ + var cloneGrid = this.dragClone.getElementsByTagName('img'); + for(var i=0; i<cloneGrid.length; i++) { + cloneGrid.item(i).style.backgroundImage='url()'; + } + + return result; + + + }); + + dragObject.onDragEnd = function(e) { + + /* restore selection */ + if (this.savedSelectedNode) { + this.savedSelectedNode.markSelected(); + } + //dojo.debug(e.dragStatus); + + return dojo.dnd.HtmlDragObject.prototype.onDragEnd.apply(this, arguments); + } + //dojo.debug(dragObject.domNode.outerHTML) + + + return dragObject; + }, + + onDragEnd: function(e){ + + + var res = dojo.dnd.HtmlDragSource.prototype.onDragEnd.call(this, e); + + + return res; + } +}); + +// ....................................... + +dojo.dnd.TreeDropTarget = function(domNode, controller, type, treeNode){ + + this.treeNode = treeNode; + this.controller = controller; // I will sync-ly process drops + + dojo.dnd.HtmlDropTarget.apply(this, [domNode, type]); +} + +dojo.inherits(dojo.dnd.TreeDropTarget, dojo.dnd.HtmlDropTarget); + +dojo.lang.extend(dojo.dnd.TreeDropTarget, { + + autoExpandDelay: 1500, + autoExpandTimer: null, + + + position: null, + + indicatorStyle: "2px black solid", + + showIndicator: function(position) { + + // do not change style too often, cause of blinking possible + if (this.position == position) { + return; + } + + //dojo.debug(position) + + this.hideIndicator(); + + this.position = position; + + if (position == "before") { + this.treeNode.labelNode.style.borderTop = this.indicatorStyle; + } else if (position == "after") { + this.treeNode.labelNode.style.borderBottom = this.indicatorStyle; + } else if (position == "onto") { + this.treeNode.markSelected(); + } + + + }, + + hideIndicator: function() { + this.treeNode.labelNode.style.borderBottom=""; + this.treeNode.labelNode.style.borderTop=""; + this.treeNode.unMarkSelected(); + this.position = null; + }, + + + + // is the target possibly ok ? + // This function is run on dragOver, but drop possibility is also determined by position over node + // that's why acceptsWithPosition is called + // doesnt take index into account ( can change while moving mouse w/o changing target ) + + + /** + * Coarse (tree-level) access check. + * We can't determine real accepts status w/o position + */ + onDragOver: function(e){ +//dojo.debug("onDragOver for "+e); + + + var accepts = dojo.dnd.HtmlDropTarget.prototype.onDragOver.apply(this, arguments); + + //dojo.debug("TreeDropTarget.onDragOver accepts:"+accepts) + + if (accepts && this.treeNode.isFolder && !this.treeNode.isExpanded) { + this.setAutoExpandTimer(); + } + + return accepts; + }, + + /* Parent.onDragOver calls this function to get accepts status */ + accepts: function(dragObjects) { + + var accepts = dojo.dnd.HtmlDropTarget.prototype.accepts.apply(this, arguments); + + if (!accepts) return false; + + var sourceTreeNode = dragObjects[0].treeNode; + + if (dojo.lang.isUndefined(sourceTreeNode) || !sourceTreeNode || !sourceTreeNode.isTreeNode) { + dojo.raise("Source is not TreeNode or not found"); + } + + if (sourceTreeNode === this.treeNode) return false; + + return true; + }, + + + + setAutoExpandTimer: function() { + // set up autoexpand timer + var _this = this; + + var autoExpand = function () { + if (dojo.dnd.dragManager.currentDropTarget === _this) { + _this.controller.expand(_this.treeNode); + } + } + + this.autoExpandTimer = dojo.lang.setTimeout(autoExpand, _this.autoExpandDelay); + }, + + + getDNDMode: function() { + return this.treeNode.tree.DNDMode; + }, + + + getAcceptPosition: function(e, sourceTreeNode) { + + var DNDMode = this.getDNDMode(); + + if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO && + // check if ONTO is allowed localy + !( + !this.treeNode.actionIsDisabled(dojo.widget.TreeNode.prototype.actions.ADDCHILD) // check dynamically cause may change w/o regeneration of dropTarget + && sourceTreeNode.parent !== this.treeNode + && this.controller.canMove(sourceTreeNode, this.treeNode) + ) + ) { + // disable ONTO if can't move + DNDMode &= ~dojo.widget.Tree.prototype.DNDModes.ONTO; + } + + + var position = this.getPosition(e, DNDMode); + + //dojo.debug(DNDMode & +" : "+position); + + + // if onto is here => it was allowed before, no accept check is needed + if (position=="onto" || + (!this.isAdjacentNode(sourceTreeNode, position) + && this.controller.canMove(sourceTreeNode, this.treeNode.parent) + ) + ) { + return position; + } else { + return false; + } + + }, + + onDragOut: function(e) { + this.clearAutoExpandTimer(); + + this.hideIndicator(); + }, + + + clearAutoExpandTimer: function() { + if (this.autoExpandTimer) { + clearTimeout(this.autoExpandTimer); + this.autoExpandTimer = null; + } + }, + + + + onDragMove: function(e, dragObjects){ + + var sourceTreeNode = dragObjects[0].treeNode; + + var position = this.getAcceptPosition(e, sourceTreeNode); + + if (position) { + this.showIndicator(position); + } + + }, + + isAdjacentNode: function(sourceNode, position) { + + if (sourceNode === this.treeNode) return true; + if (sourceNode.getNextSibling() === this.treeNode && position=="before") return true; + if (sourceNode.getPreviousSibling() === this.treeNode && position=="after") return true; + + return false; + }, + + + /* get DNDMode and see which position e fits */ + getPosition: function(e, DNDMode) { + var node = dojo.byId(this.treeNode.labelNode); + var mousey = e.pageY || e.clientY + dojo.body().scrollTop; + var nodey = dojo.html.getAbsolutePosition(node).y; + var height = dojo.html.getBorderBox(node).height; + + var relY = mousey - nodey; + var p = relY / height; + + var position = ""; // "" <=> forbidden + if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO + && DNDMode & dojo.widget.Tree.prototype.DNDModes.BETWEEN) { + if (p<=0.3) { + position = "before"; + } else if (p<=0.7) { + position = "onto"; + } else { + position = "after"; + } + } else if (DNDMode & dojo.widget.Tree.prototype.DNDModes.BETWEEN) { + if (p<=0.5) { + position = "before"; + } else { + position = "after"; + } + } + else if (DNDMode & dojo.widget.Tree.prototype.DNDModes.ONTO) { + position = "onto"; + } + + + return position; + }, + + + + getTargetParentIndex: function(sourceTreeNode, position) { + + var index = position == "before" ? this.treeNode.getParentIndex() : this.treeNode.getParentIndex()+1; + if (this.treeNode.parent === sourceTreeNode.parent + && this.treeNode.getParentIndex() > sourceTreeNode.getParentIndex()) { + index--; // dragging a node is different for simple move bacause of before-after issues + } + + return index; + }, + + + onDrop: function(e){ + // onDragOut will clean position + + + var position = this.position; + +//dojo.debug(position); + + this.onDragOut(e); + + var sourceTreeNode = e.dragObject.treeNode; + + if (!dojo.lang.isObject(sourceTreeNode)) { + dojo.raise("TreeNode not found in dragObject") + } + + if (position == "onto") { + return this.controller.move(sourceTreeNode, this.treeNode, 0); + } else { + var index = this.getTargetParentIndex(sourceTreeNode, position); + return this.controller.move(sourceTreeNode, this.treeNode.parent, index); + } + + //dojo.debug('drop2'); + + + + } + + +}); + + + +dojo.dnd.TreeDNDController = function(treeController) { + + // I use this controller to perform actions + this.treeController = treeController; + + this.dragSources = {}; + + this.dropTargets = {}; + +} + +dojo.lang.extend(dojo.dnd.TreeDNDController, { + + + listenTree: function(tree) { + //dojo.debug("Listen tree "+tree); + dojo.event.topic.subscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode"); + dojo.event.topic.subscribe(tree.eventNames.moveFrom, this, "onMoveFrom"); + dojo.event.topic.subscribe(tree.eventNames.moveTo, this, "onMoveTo"); + dojo.event.topic.subscribe(tree.eventNames.addChild, this, "onAddChild"); + dojo.event.topic.subscribe(tree.eventNames.removeNode, this, "onRemoveNode"); + dojo.event.topic.subscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy"); + }, + + + unlistenTree: function(tree) { + //dojo.debug("Listen tree "+tree); + dojo.event.topic.unsubscribe(tree.eventNames.createDOMNode, this, "onCreateDOMNode"); + dojo.event.topic.unsubscribe(tree.eventNames.moveFrom, this, "onMoveFrom"); + dojo.event.topic.unsubscribe(tree.eventNames.moveTo, this, "onMoveTo"); + dojo.event.topic.unsubscribe(tree.eventNames.addChild, this, "onAddChild"); + dojo.event.topic.unsubscribe(tree.eventNames.removeNode, this, "onRemoveNode"); + dojo.event.topic.unsubscribe(tree.eventNames.treeDestroy, this, "onTreeDestroy"); + }, + + onTreeDestroy: function(message) { + this.unlistenTree(message.source); + // I'm not widget so don't use destroy() call and dieWithTree + }, + + onCreateDOMNode: function(message) { + this.registerDNDNode(message.source); + }, + + onAddChild: function(message) { + this.registerDNDNode(message.child); + }, + + onMoveFrom: function(message) { + var _this = this; + dojo.lang.forEach( + message.child.getDescendants(), + function(node) { _this.unregisterDNDNode(node); } + ); + }, + + onMoveTo: function(message) { + var _this = this; + dojo.lang.forEach( + message.child.getDescendants(), + function(node) { _this.registerDNDNode(node); } + ); + }, + + /** + * Controller(node model) creates DNDNodes because it passes itself to node for synchroneous drops processing + * I can't process DnD with events cause an event can't return result success/false + */ + registerDNDNode: function(node) { + if (!node.tree.DNDMode) return; + +//dojo.debug("registerDNDNode "+node); + + /* I drag label, not domNode, because large domNodes are very slow to copy and large to drag */ + + var source = null; + var target = null; + + if (!node.actionIsDisabled(node.actions.MOVE)) { + //dojo.debug("reg source") + var source = new dojo.dnd.TreeDragSource(node.labelNode, this, node.tree.widgetId, node); + this.dragSources[node.widgetId] = source; + } + + var target = new dojo.dnd.TreeDropTarget(node.labelNode, this.treeController, node.tree.DNDAcceptTypes, node); + + this.dropTargets[node.widgetId] = target; + + }, + + + unregisterDNDNode: function(node) { + + if (this.dragSources[node.widgetId]) { + dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]); + delete this.dragSources[node.widgetId]; + } + + if (this.dropTargets[node.widgetId]) { + dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]); + delete this.dropTargets[node.widgetId]; + } + } + + + + + +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDrop.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDropV3.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDropV3.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDropV3.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/dnd/TreeDragAndDropV3.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,403 @@ +/* + 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 +*/ + +/** + * TreeDrag* specialized on managing subtree drags + * It selects nodes and visualises what's going on, + * but delegates real actions upon tree to the controller + * + * This code is considered a part of controller +*/ + +dojo.provide("dojo.dnd.TreeDragAndDropV3"); + +dojo.require("dojo.dnd.HtmlDragAndDrop"); +dojo.require("dojo.lang.func"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.Deferred"); +dojo.require("dojo.html.layout"); + +// FIXME: if controller can't move then skip node on move start +dojo.dnd.TreeDragSourceV3 = function(node, syncController, type, treeNode){ + //dojo.profile.start("TreeDragSourceV3 "+treeNode); + this.controller = syncController; + this.treeNode = treeNode; + + dojo.dnd.HtmlDragSource.call(this, node, type); + //dojo.profile.end("TreeDragSourceV3 "+treeNode); +} + +dojo.inherits(dojo.dnd.TreeDragSourceV3, dojo.dnd.HtmlDragSource); + + +// ....................................... + +dojo.dnd.TreeDropTargetV3 = function(domNode, controller, type, treeNode){ + + this.treeNode = treeNode; + this.controller = controller; // I will sync-ly process drops + + dojo.dnd.HtmlDropTarget.call(this, domNode, type); +} + +dojo.inherits(dojo.dnd.TreeDropTargetV3, dojo.dnd.HtmlDropTarget); + +dojo.lang.extend(dojo.dnd.TreeDropTargetV3, { + + autoExpandDelay: 1500, + autoExpandTimer: null, + + + position: null, + + indicatorStyle: "2px black groove", + + showIndicator: function(position) { + + // do not change style too often, cause of blinking possible + if (this.position == position) { + return; + } + + //dojo.debug("set position for "+this.treeNode) + + this.hideIndicator(); + + this.position = position; + + var node = this.treeNode; + + + node.contentNode.style.width = dojo.html.getBorderBox(node.labelNode).width + "px"; + + if (position == "onto") { + node.contentNode.style.border = this.indicatorStyle; + } else { + // FIXME: bottom-top or highlight should cover ONLY top/bottom or div itself, + // not span whole line (try Dnd) + // FAILURE: Can't put span inside div: multiline bottom-top will span multiple lines + if (position == "before") { + node.contentNode.style.borderTop = this.indicatorStyle; + } else if (position == "after") { + node.contentNode.style.borderBottom = this.indicatorStyle; + } + } + }, + + hideIndicator: function() { + this.treeNode.contentNode.style.borderBottom = ""; + this.treeNode.contentNode.style.borderTop = ""; + this.treeNode.contentNode.style.border = ""; + this.treeNode.contentNode.style.width="" + this.position = null; + }, + + + + // is the target possibly ok ? + // This function is run on dragOver, but drop possibility is also determined by position over node + // that's why acceptsWithPosition is called + // doesnt take index into account ( can change while moving mouse w/o changing target ) + /** + * Coarse (tree-level) access check. + * We can't determine real accepts status w/o position + */ + onDragOver: function(e){ + //dojo.debug("onDragOver for "+e); + + var accepts = dojo.dnd.HtmlDropTarget.prototype.onDragOver.apply(this, arguments); + + //dojo.debug("TreeDropTarget.onDragOver accepts:"+accepts) + + if (accepts && this.treeNode.isFolder && !this.treeNode.isExpanded) { + this.setAutoExpandTimer(); + } + + if (accepts) { + this.cacheNodeCoords(); + } + + + return accepts; + }, + + /* Parent.onDragOver calls this function to get accepts status */ + accepts: function(dragObjects) { + + var accepts = dojo.dnd.HtmlDropTarget.prototype.accepts.apply(this, arguments); + + //dojo.debug("accepts "+accepts); + + if (!accepts) return false; + + for(var i=0; i<dragObjects.length; i++) { + // there may be NO treeNode + var sourceTreeNode = dragObjects[i].treeNode; + + if (sourceTreeNode === this.treeNode) return false; + } + + return true; + }, + + + + setAutoExpandTimer: function() { + // set up autoexpand timer + var _this = this; + + var autoExpand = function () { + if (dojo.dnd.dragManager.currentDropTarget === _this) { + _this.controller.expand(_this.treeNode); + // SLOW. Coordinates will not be recalculated if collapse occurs, or + // other (generic) resize. So that's a kind of hack. + dojo.dnd.dragManager.cacheTargetLocations(); + } + } + + this.autoExpandTimer = dojo.lang.setTimeout(autoExpand, _this.autoExpandDelay); + }, + + + + getAcceptPosition: function(e, dragObjects) { + + + var DndMode = this.treeNode.tree.DndMode; + + // dis |
Free forum by Nabble | Edit this page |