New file |
0,0 → 1,177 |
if(!dojo._hasResource["dojo.dnd.Manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dojo.dnd.Manager"] = true; |
dojo.provide("dojo.dnd.Manager"); |
|
dojo.require("dojo.dnd.common"); |
dojo.require("dojo.dnd.autoscroll"); |
dojo.require("dojo.dnd.Avatar"); |
|
dojo.dnd.Manager = function(){ |
// summary: the manager of DnD operations (usually a singleton) |
this.avatar = null; |
this.source = null; |
this.nodes = []; |
this.copy = true; |
this.target = null; |
this.canDropFlag = false; |
this.events = []; |
}; |
|
dojo.extend(dojo.dnd.Manager, { |
// avatar's offset from the mouse |
OFFSET_X: 16, |
OFFSET_Y: 16, |
// methods |
overSource: function(source){ |
// summary: called when a source detected a mouse-over conditiion |
// source: Object: the reporter |
if(this.avatar){ |
this.target = (source && source.targetState != "Disabled") ? source : null; |
this.avatar.update(); |
} |
dojo.publish("/dnd/source/over", [source]); |
}, |
outSource: function(source){ |
// summary: called when a source detected a mouse-out conditiion |
// source: Object: the reporter |
if(this.avatar){ |
if(this.target == source){ |
this.target = null; |
this.canDropFlag = false; |
this.avatar.update(); |
dojo.publish("/dnd/source/over", [null]); |
} |
}else{ |
dojo.publish("/dnd/source/over", [null]); |
} |
}, |
startDrag: function(source, nodes, copy){ |
// summary: called to initiate the DnD operation |
// source: Object: the source which provides items |
// nodes: Array: the list of transferred items |
// copy: Boolean: copy items, if true, move items otherwise |
this.source = source; |
this.nodes = nodes; |
this.copy = Boolean(copy); // normalizing to true boolean |
this.avatar = this.makeAvatar(); |
dojo.body().appendChild(this.avatar.node); |
dojo.publish("/dnd/start", [source, nodes, this.copy]); |
this.events = [ |
dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"), |
dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"), |
dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"), |
dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp") |
]; |
var c = "dojoDnd" + (copy ? "Copy" : "Move"); |
dojo.addClass(dojo.body(), c); |
}, |
canDrop: function(flag){ |
// summary: called to notify if the current target can accept items |
var canDropFlag = this.target && flag; |
if(this.canDropFlag != canDropFlag){ |
this.canDropFlag = canDropFlag; |
this.avatar.update(); |
} |
}, |
stopDrag: function(){ |
// summary: stop the DnD in progress |
dojo.removeClass(dojo.body(), "dojoDndCopy"); |
dojo.removeClass(dojo.body(), "dojoDndMove"); |
dojo.forEach(this.events, dojo.disconnect); |
this.events = []; |
this.avatar.destroy(); |
this.avatar = null; |
this.source = null; |
this.nodes = []; |
}, |
makeAvatar: function(){ |
// summary: makes the avatar, it is separate to be overwritten dynamically, if needed |
return new dojo.dnd.Avatar(this); |
}, |
updateAvatar: function(){ |
// summary: updates the avatar, it is separate to be overwritten dynamically, if needed |
this.avatar.update(); |
}, |
// mouse event processors |
onMouseMove: function(e){ |
// summary: event processor for onmousemove |
// e: Event: mouse event |
var a = this.avatar; |
if(a){ |
//dojo.dnd.autoScrollNodes(e); |
dojo.dnd.autoScroll(e); |
dojo.marginBox(a.node, {l: e.pageX + this.OFFSET_X, t: e.pageY + this.OFFSET_Y}); |
var copy = Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e))); |
if(this.copy != copy){ |
this._setCopyStatus(copy); |
} |
} |
}, |
onMouseUp: function(e){ |
// summary: event processor for onmouseup |
// e: Event: mouse event |
if(this.avatar && (!("mouseButton" in this.source) || this.source.mouseButton == e.button)){ |
if(this.target && this.canDropFlag){ |
var params = [this.source, this.nodes, Boolean(this.source.copyState(dojo.dnd.getCopyKeyState(e))), this.target]; |
dojo.publish("/dnd/drop/before", params); |
dojo.publish("/dnd/drop", params); |
}else{ |
dojo.publish("/dnd/cancel"); |
} |
this.stopDrag(); |
} |
}, |
// keyboard event processors |
onKeyDown: function(e){ |
// summary: event processor for onkeydown: |
// watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag |
// e: Event: keyboard event |
if(this.avatar){ |
switch(e.keyCode){ |
case dojo.keys.CTRL: |
var copy = Boolean(this.source.copyState(true)); |
if(this.copy != copy){ |
this._setCopyStatus(copy); |
} |
break; |
case dojo.keys.ESCAPE: |
dojo.publish("/dnd/cancel"); |
this.stopDrag(); |
break; |
} |
} |
}, |
onKeyUp: function(e){ |
// summary: event processor for onkeyup, watching for CTRL for copy/move status |
// e: Event: keyboard event |
if(this.avatar && e.keyCode == dojo.keys.CTRL){ |
var copy = Boolean(this.source.copyState(false)); |
if(this.copy != copy){ |
this._setCopyStatus(copy); |
} |
} |
}, |
// utilities |
_setCopyStatus: function(copy){ |
// summary: changes the copy status |
// copy: Boolean: the copy status |
this.copy = copy; |
this.source._markDndStatus(this.copy); |
this.updateAvatar(); |
dojo.removeClass(dojo.body(), "dojoDnd" + (this.copy ? "Move" : "Copy")); |
dojo.addClass(dojo.body(), "dojoDnd" + (this.copy ? "Copy" : "Move")); |
} |
}); |
|
// summary: the manager singleton variable, can be overwritten, if needed |
dojo.dnd._manager = null; |
|
dojo.dnd.manager = function(){ |
// summary: returns the current DnD manager, creates one if it is not created yet |
if(!dojo.dnd._manager){ |
dojo.dnd._manager = new dojo.dnd.Manager(); |
} |
return dojo.dnd._manager; // Object |
}; |
|
} |