366 lines
12 KiB
JavaScript
366 lines
12 KiB
JavaScript
//>>built
|
|
define("dojox/mdnd/adapter/DndFromDojo", ["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/array",
|
|
"dojo/_base/html","dojo/_base/window","dojox/mdnd/AreaManager","dojo/dnd/Manager"],function(dojo){
|
|
var dfd = dojo.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},
|
|
|
|
// 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 = dojox.mdnd.areaManager();
|
|
this._dojoManager = dojo.dnd.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 = [
|
|
dojo.subscribe("/dnd/start",this,"onDragStart"),
|
|
dojo.subscribe("/dnd/drop/before", this, "onDrop"),
|
|
dojo.subscribe("/dnd/cancel",this,"onDropCancel"),
|
|
dojo.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");
|
|
dojo.forEach(this._subscribeHandler, dojo.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 usefull 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 = dojo.connect(this._dojoManager, "outSource", this, function(){
|
|
//dojo.disconnect(this._outSourceHandler);
|
|
if(this._moveHandler == null){
|
|
this._moveHandler = dojo.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 = "";
|
|
dojo.addClass(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){
|
|
dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
|
|
}
|
|
else{
|
|
dojo.removeClass(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){
|
|
dojo.removeClass(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.
|
|
dojo.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 = dojo.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){
|
|
dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
|
|
}
|
|
else{
|
|
dojo.removeClass(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();
|
|
dojo.disconnect(this._moveHandler);
|
|
dojo.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;
|
|
dojo.disconnect(this._outSourceHandler);
|
|
dojo.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);
|
|
dojo.disconnect(this._moveHandler);
|
|
dojo.disconnect(this._outSourceHandler);
|
|
this._moveHandler = this._outSourceHandler = null;
|
|
if(this._currentArea){
|
|
var dropIndex = this._areaManager._currentDropIndex;
|
|
dojo.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;
|
|
});
|