You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
12 KiB
367 lines
12 KiB
define(["dojo/_base/kernel", |
|
"dojo/_base/declare", |
|
"dojo/_base/connect", |
|
"dojo/_base/array", |
|
"dojo/dom-class", |
|
"dojo/_base/window", |
|
"dojox/mdnd/AreaManager", |
|
"dojo/dnd/Manager" |
|
],function(dojo, declare, connect, array, domClass, win, AreaManager, Manager){ |
|
var dfd = declare( |
|
"dojox.mdnd.adapter.DndFromDojo", |
|
null, |
|
{ |
|
// summary: |
|
// Allow communication between Dojo dnd items and DojoX D&D areas |
|
|
|
// dropIndicatorSize: Object |
|
// size by default of dropIndicator (display only into a D&D Area) |
|
dropIndicatorSize: {'w':0,'h':50}, |
|
|
|
// _areaManager: Object |
|
// Reference to the current DojoX Dnd Manager |
|
_areaManager: null, |
|
|
|
// _dojoManager |
|
// Reference to the current Dojo Manager |
|
_dojoManager: null, |
|
|
|
// _currentArea: Object |
|
// The current Area on mouse over |
|
_currentArea: null, |
|
|
|
// _oldArea: Object |
|
// The old area the mouse has passed over |
|
_oldArea: null, |
|
|
|
// _moveHandler: Object |
|
// The handler of mouse connection |
|
_moveHandler: null, |
|
|
|
// _subscribeHandler: Array |
|
// The list of dojo dnd topics |
|
_subscribeHandler: null, |
|
|
|
constructor: function(){ |
|
this._areaManager = AreaManager.areaManager(); |
|
this._dojoManager = Manager.manager(); |
|
this._currentArea = null; |
|
this._moveHandler = null; |
|
this.subscribeDnd(); |
|
}, |
|
|
|
subscribeDnd: function(){ |
|
// summary: |
|
// Subscribe to somes topics of dojo drag and drop. |
|
|
|
//console.log(("dojox.mdnd.adapter.DndFromDojo ::: subscribeDnd"); |
|
this._subscribeHandler = [ |
|
connect.subscribe("/dnd/start",this,"onDragStart"), |
|
connect.subscribe("/dnd/drop/before", this, "onDrop"), |
|
connect.subscribe("/dnd/cancel",this,"onDropCancel"), |
|
connect.subscribe("/dnd/source/over",this,"onDndSource") |
|
] |
|
}, |
|
|
|
unsubscribeDnd: function(){ |
|
// summary: |
|
// Unsubscribe to some topics of dojo drag and drop. |
|
|
|
//console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd"); |
|
array.forEach(this._subscribeHandler, connect.unsubscribe); |
|
}, |
|
|
|
_getHoverArea: function(/*Object*/ coords){ |
|
// summary: |
|
// Get a D&D dojoX area as a DOM node positioned under a specific point. |
|
// coords: |
|
// Object containing the coordinates x and y (mouse position) |
|
// tags: |
|
// protected |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea"); |
|
var x = coords.x; |
|
var y = coords.y; |
|
this._oldArea = this._currentArea; |
|
this._currentArea = null; |
|
var areas = this._areaManager._areaList; |
|
for(var i = 0; i < areas.length; i++){ |
|
var area = areas[i]; |
|
var startX = area.coords.x; |
|
var endX = startX + area.node.offsetWidth; |
|
var startY = area.coords.y; |
|
var endY = startY + area.node.offsetHeight; |
|
// check if the coordinates mouse is in a D&D Area |
|
if(startX <= x && x <= endX && startY <= y && y <= endY){ |
|
this._areaManager._oldIndexArea = this._areaManager._currentIndexArea; |
|
this._areaManager._currentIndexArea = i; |
|
this._currentArea = area.node; |
|
break; |
|
} |
|
} |
|
if(this._currentArea != this._oldArea){ |
|
if(this._currentArea == null){ |
|
// case when the dragNode was in a D&D area but it's out now. |
|
this.onDragExit(); |
|
} |
|
else if(this._oldArea == null){ |
|
// case when the dragNode was out a D&D area but it's in now. |
|
this.onDragEnter(); |
|
} |
|
else{ |
|
// case when the dragNode was in a D&D area and enter in an other D&D area directly. |
|
this.onDragExit(); |
|
this.onDragEnter(); |
|
} |
|
} |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea",this._dojoManager.avatar.node,this._currentArea,this._oldArea); |
|
}, |
|
|
|
onDragStart: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){ |
|
// summary: |
|
// Occurs when the "/dnd/start" topic is published. |
|
// source: |
|
// the source which provides items |
|
// nodes: |
|
// the list of transferred items |
|
// copy: |
|
// copy items, if true, move items otherwise |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragStart"); |
|
// catch the dragNode to get the type when it's necessary. |
|
this._dragNode = nodes[0]; |
|
this._copy = copy; this._source = source; |
|
// Connect the onMouseMove : |
|
// It's useful to activate the detection of a D&D area and the dropIndicator place only if |
|
// the dragNode is out of a the source dojo. The classic behaviour of the dojo source is kept. |
|
this._outSourceHandler = connect.connect(this._dojoManager, "outSource", this, function(){ |
|
//dojo.disconnect(this._outSourceHandler); |
|
if(this._moveHandler == null){ |
|
this._moveHandler = connect.connect(dojo.doc, "mousemove", this, "onMouseMove"); |
|
} |
|
}); |
|
}, |
|
|
|
onMouseMove: function(/*DOMEvent*/e){ |
|
// summary: |
|
// Occurs when the user moves the mouse. |
|
// e: |
|
// the DOM event |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onMouseMove"); |
|
// calculate the coordonates of the mouse. |
|
var coords = { |
|
'x': e.pageX, |
|
'y': e.pageY |
|
}; |
|
this._getHoverArea(coords); |
|
// if a D&D area has been found and if it's accepted to drop this type of dragged node |
|
if(this._currentArea && this._areaManager._accept){ |
|
// specific case : a dropIndicator can be hidden (see onDndSource method) |
|
if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){ |
|
this._areaManager._dropIndicator.node.style.visibility = ""; |
|
domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
// place the dropIndicator in D&D Area with a default size. |
|
this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize); |
|
} |
|
}, |
|
|
|
onDragEnter: function(){ |
|
// summary: |
|
// Occurs when the user drages an DOJO dnd item inside a D&D dojoX area. |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragEnter"); |
|
// Check if the type of dragged node is accepted in the selected D&D dojoX Area. |
|
var _dndType = this._dragNode.getAttribute("dndType"); |
|
// need to have an array as type |
|
var type = (_dndType) ? _dndType.split(/\s*,\s*/) : ["text"]; |
|
this._areaManager._isAccepted(type, this._areaManager._areaList[this._areaManager._currentIndexArea].accept); |
|
// if the D&D dojoX Area accepts the drop, change the color of Avatar. |
|
if(this._dojoManager.avatar){ |
|
if(this._areaManager._accept){ |
|
domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
else{ |
|
domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
} |
|
}, |
|
|
|
onDragExit: function(){ |
|
// summary: |
|
// Occurs when the user leaves a D&D dojoX area after dragging an DOJO dnd item over it. |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragExit"); |
|
// if the dragged node exits of a D&D dojoX Area : |
|
this._areaManager._accept = false; |
|
// change color of avatar |
|
if(this._dojoManager.avatar){ |
|
domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
// reset all variables and remove the dropIndicator. |
|
if(this._currentArea == null){ |
|
this._areaManager._dropMode.refreshItems(this._areaManager._areaList[this._areaManager._oldIndexArea], this._areaManager._oldDropIndex, this.dropIndicatorSize, false); |
|
this._areaManager._resetAfterDrop(); |
|
} |
|
else{ |
|
this._areaManager._dropIndicator.remove(); |
|
} |
|
}, |
|
|
|
isAccepted: function(/*Node*/node, /*Object*/accept){ |
|
// summary: |
|
// Check if a dragNode is accepted into a dojo target. |
|
// node: |
|
// The dragged node. |
|
// accept: |
|
// Object containing the type accepted for a target dojo. |
|
// returns: |
|
// true if the dragged node is accepted in the target dojo. |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: isAccepted"); |
|
var type = (node.getAttribute("dndType")) ? node.getAttribute("dndType") : "text"; |
|
if(type && type in accept) |
|
return true; // Boolean |
|
else |
|
return false; // Boolean |
|
}, |
|
|
|
onDndSource: function(/*Object*/ source){ |
|
// summary: |
|
// Called when the mouse enters or exits of a source dojo. |
|
// source: |
|
// the dojo source/target |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDndSource",source); |
|
// Only the case : "source dojo into a D&D dojoX Area" is treated. |
|
if(this._currentArea == null){ |
|
return; |
|
} |
|
if(source){ |
|
// Enter in a source/target dojo. |
|
// test if the type of draggedNode is accepted : |
|
var accept = false; |
|
if(this._dojoManager.target == source){ |
|
accept = true; |
|
} |
|
else{ |
|
accept = this.isAccepted(this._dragNode, source.accept); |
|
} |
|
if(accept){ |
|
// disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area. |
|
connect.disconnect(this._moveHandler); |
|
this._currentArea = this._moveHandler = null; |
|
// hidden the visibility of dojoX dropIndicator to prevent an offset when the dropIndicator disappears. |
|
// test if drop indicator is visible before applaying hidden style. |
|
var dropIndicator = this._areaManager._dropIndicator.node; |
|
if(dropIndicator && dropIndicator.parentNode !== null && dropIndicator.parentNode.nodeType == 1) |
|
dropIndicator.style.visibility = "hidden"; |
|
} |
|
else{ |
|
// if the type of dragged node is not accepted in the target dojo, the color of avatar |
|
// have to be the same that the color of D&D dojoX Area acceptance. |
|
this._resetAvatar(); |
|
} |
|
} |
|
else{ |
|
// Exit of a source/target dojo. |
|
// reconnect the onMouseMove to enabled the search of a drop zone in the D&D dojox Area. |
|
if(!this._moveHandler) |
|
this._moveHandler = connect.connect(dojo.doc, "mousemove", this, "onMouseMove"); |
|
|
|
this._resetAvatar(); |
|
} |
|
}, |
|
|
|
_resetAvatar: function(){ |
|
// summary: |
|
// Function executed in onDndSource function to set the avatar |
|
// acceptance according to the dojox DnD AreaManager Acceptance. |
|
// It is used when The mouse exit a source/target dojo or if the |
|
// dragged node is not accepted in dojo source / target. |
|
// tags: |
|
// protected |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar"); |
|
if(this._dojoManager.avatar){ |
|
if(this._areaManager._accept){ |
|
domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
else{ |
|
domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop"); |
|
} |
|
} |
|
}, |
|
|
|
onDropCancel: function(){ |
|
// summary: |
|
// Occurs when the "/dnd/cancel" topic is published. |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDropCancel"); |
|
if(this._currentArea == null){ |
|
// the dragged node is not in the D&D dojox Area => Cancel |
|
this._areaManager._resetAfterDrop(); |
|
connect.disconnect(this._moveHandler); |
|
connect.disconnect(this._outSourceHandler); |
|
this._currentArea = this._moveHandler = this._outSourceHandler = null; |
|
} |
|
else{ |
|
// the dragged node is in the D&D dojox Area |
|
// (catch when dragged node exits of a source/target dojo and stays in the same D&D dojox Area) |
|
// dojo cancel the drop but it's authorized in the D&D Area |
|
if(this._areaManager._accept){ |
|
this.onDrop(this._source, [this._dragNode], this._copy, this._currentArea); |
|
} |
|
else{ |
|
this._currentArea = null; |
|
connect.disconnect(this._outSourceHandler); |
|
connect.disconnect(this._moveHandler); |
|
this._moveHandler = this._outSourceHandler = null; |
|
} |
|
} |
|
}, |
|
|
|
onDrop: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){ |
|
// summary: |
|
// Occurs when the user leaves a D&D dojox area after dragging an DOJO dnd item over it. |
|
// source: |
|
// the source which provides items |
|
// nodes: |
|
// the list of transferred items |
|
// copy: |
|
// copy items, if true, move items otherwise |
|
// tags: |
|
// callback |
|
|
|
//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea); |
|
connect.disconnect(this._moveHandler); |
|
connect.disconnect(this._outSourceHandler); |
|
this._moveHandler = this._outSourceHandler = null; |
|
if(this._currentArea){ |
|
var dropIndex = this._areaManager._currentDropIndex; |
|
connect.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]); |
|
this._currentArea = null; |
|
} |
|
if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){ |
|
this._areaManager._dropIndicator.node.style.visibility = ""; |
|
} |
|
this._areaManager._resetAfterDrop(); |
|
} |
|
}); |
|
|
|
dojox.mdnd.adapter._dndFromDojo = null; |
|
dojox.mdnd.adapter._dndFromDojo = new dojox.mdnd.adapter.DndFromDojo(); |
|
return dfd; |
|
});
|
|
|