DndFromDojo.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. define("dojox/mdnd/adapter/DndFromDojo", ["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/array",
  2. "dojo/_base/html","dojo/_base/window","dojox/mdnd/AreaManager","dojo/dnd/Manager"],function(dojo){
  3. var dfd = dojo.declare(
  4. "dojox.mdnd.adapter.DndFromDojo",
  5. null,
  6. {
  7. // summary
  8. // Allow communication between Dojo dnd items and DojoX D&D areas
  9. // dropIndicatorSize: Object
  10. // size by default of dropIndicator (display only into a D&D Area)
  11. dropIndicatorSize : {'w':0,'h':50},
  12. // dropIndicatorSize: Object
  13. // size by default of dropIndicator (display only into a D&D Area)
  14. dropIndicatorSize: {'w':0,'h':50},
  15. // _areaManager: Object
  16. // Reference to the current DojoX Dnd Manager
  17. _areaManager: null,
  18. // _dojoManager
  19. // Reference to the current Dojo Manager
  20. _dojoManager: null,
  21. // _currentArea: Object
  22. // The current Area on mouse over
  23. _currentArea: null,
  24. // _oldArea: Object
  25. // The old area the mouse has passed over
  26. _oldArea: null,
  27. // _moveHandler: Object
  28. // The handler of mouse connection
  29. _moveHandler: null,
  30. // _subscribeHandler: Array
  31. // The list of dojo dnd topics
  32. _subscribeHandler: null,
  33. constructor: function(){
  34. this._areaManager = dojox.mdnd.areaManager();
  35. this._dojoManager = dojo.dnd.manager();
  36. this._currentArea = null;
  37. this._moveHandler = null;
  38. this.subscribeDnd();
  39. },
  40. subscribeDnd: function(){
  41. // summary:
  42. // Subscribe to somes topics of dojo drag and drop.
  43. //console.log(("dojox.mdnd.adapter.DndFromDojo ::: subscribeDnd");
  44. this._subscribeHandler = [
  45. dojo.subscribe("/dnd/start",this,"onDragStart"),
  46. dojo.subscribe("/dnd/drop/before", this, "onDrop"),
  47. dojo.subscribe("/dnd/cancel",this,"onDropCancel"),
  48. dojo.subscribe("/dnd/source/over",this,"onDndSource")
  49. ]
  50. },
  51. unsubscribeDnd: function(){
  52. // summary:
  53. // Unsubscribe to some topics of dojo drag and drop.
  54. //console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd");
  55. dojo.forEach(this._subscribeHandler, dojo.unsubscribe);
  56. },
  57. _getHoverArea: function(/*Object*/ coords){
  58. // summary:
  59. // Get a D&D dojoX area as a DOM node positioned under a specific point.
  60. // coords:
  61. // Object containing the coordinates x and y (mouse position)
  62. // tags:
  63. // protected
  64. //console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea");
  65. var x = coords.x;
  66. var y = coords.y;
  67. this._oldArea = this._currentArea;
  68. this._currentArea = null;
  69. var areas = this._areaManager._areaList;
  70. for(var i = 0; i < areas.length; i++){
  71. var area = areas[i];
  72. var startX = area.coords.x;
  73. var endX = startX + area.node.offsetWidth;
  74. var startY = area.coords.y;
  75. var endY = startY + area.node.offsetHeight;
  76. // check if the coordinates mouse is in a D&D Area
  77. if(startX <= x && x <= endX && startY <= y && y <= endY){
  78. this._areaManager._oldIndexArea = this._areaManager._currentIndexArea;
  79. this._areaManager._currentIndexArea = i;
  80. this._currentArea = area.node;
  81. break;
  82. }
  83. }
  84. if(this._currentArea != this._oldArea){
  85. if(this._currentArea == null){
  86. // case when the dragNode was in a D&D area but it's out now.
  87. this.onDragExit();
  88. }
  89. else if(this._oldArea == null){
  90. // case when the dragNode was out a D&D area but it's in now.
  91. this.onDragEnter();
  92. }
  93. else{
  94. // case when the dragNode was in a D&D area and enter in an other D&D area directly.
  95. this.onDragExit();
  96. this.onDragEnter();
  97. }
  98. }
  99. //console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea",this._dojoManager.avatar.node,this._currentArea,this._oldArea);
  100. },
  101. onDragStart: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
  102. // summary:
  103. // Occurs when the "/dnd/start" topic is published.
  104. // source:
  105. // the source which provides items
  106. // nodes:
  107. // the list of transferred items
  108. // copy:
  109. // copy items, if true, move items otherwise
  110. // tags:
  111. // callback
  112. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragStart");
  113. // catch the dragNode to get the type when it's necessary.
  114. this._dragNode = nodes[0];
  115. this._copy = copy; this._source = source;
  116. // Connect the onMouseMove :
  117. // It's usefull to activate the detection of a D&D area and the dropIndicator place only if
  118. // the dragNode is out of a the source dojo. The classic behaviour of the dojo source is kept.
  119. this._outSourceHandler = dojo.connect(this._dojoManager, "outSource", this, function(){
  120. //dojo.disconnect(this._outSourceHandler);
  121. if(this._moveHandler == null){
  122. this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
  123. }
  124. });
  125. },
  126. onMouseMove: function(/*DOMEvent*/e){
  127. // summary:
  128. // Occurs when the user moves the mouse.
  129. // e:
  130. // the DOM event
  131. // tags:
  132. // callback
  133. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onMouseMove");
  134. // calculate the coordonates of the mouse.
  135. var coords = {
  136. 'x': e.pageX,
  137. 'y': e.pageY
  138. };
  139. this._getHoverArea(coords);
  140. // if a D&D area has been found and if it's accepted to drop this type of dragged node
  141. if(this._currentArea && this._areaManager._accept){
  142. // specific case : a dropIndicator can be hidden (see onDndSource method)
  143. if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
  144. this._areaManager._dropIndicator.node.style.visibility = "";
  145. dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  146. }
  147. // place the dropIndicator in D&D Area with a default size.
  148. this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize);
  149. }
  150. },
  151. onDragEnter: function(){
  152. // summary:
  153. // Occurs when the user drages an DOJO dnd item inside a D&D dojoX area.
  154. // tags:
  155. // callback
  156. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragEnter");
  157. // Check if the type of dragged node is accepted in the selected D&D dojoX Area.
  158. var _dndType = this._dragNode.getAttribute("dndType");
  159. // need to have an array as type
  160. var type = (_dndType) ? _dndType.split(/\s*,\s*/) : ["text"];
  161. this._areaManager._isAccepted(type, this._areaManager._areaList[this._areaManager._currentIndexArea].accept);
  162. // if the D&D dojoX Area accepts the drop, change the color of Avatar.
  163. if(this._dojoManager.avatar){
  164. if(this._areaManager._accept){
  165. dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  166. }
  167. else{
  168. dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  169. }
  170. }
  171. },
  172. onDragExit: function(){
  173. // summary:
  174. // Occurs when the user leaves a D&D dojoX area after dragging an DOJO dnd item over it.
  175. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragExit");
  176. // if the dragged node exits of a D&D dojoX Area :
  177. this._areaManager._accept = false;
  178. // change color of avatar
  179. if(this._dojoManager.avatar){
  180. dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  181. }
  182. // reset all variables and remove the dropIndicator.
  183. if(this._currentArea == null){
  184. this._areaManager._dropMode.refreshItems(this._areaManager._areaList[this._areaManager._oldIndexArea], this._areaManager._oldDropIndex, this.dropIndicatorSize, false);
  185. this._areaManager._resetAfterDrop();
  186. }
  187. else{
  188. this._areaManager._dropIndicator.remove();
  189. }
  190. },
  191. isAccepted: function(/*Node*/node, /*Object*/accept){
  192. // summary:
  193. // Check if a dragNode is accepted into a dojo target.
  194. // node:
  195. // The dragged node.
  196. // accept:
  197. // Object containing the type accepted for a target dojo.
  198. // returns:
  199. // true if the dragged node is accepted in the target dojo.
  200. //console.log("dojox.mdnd.adapter.DndFromDojo ::: isAccepted");
  201. var type = (node.getAttribute("dndType")) ? node.getAttribute("dndType") : "text";
  202. if(type && type in accept)
  203. return true; // Boolean
  204. else
  205. return false; // Boolean
  206. },
  207. onDndSource: function(/*Object*/ source){
  208. // summary:
  209. // Called when the mouse enters or exits of a source dojo.
  210. // source:
  211. // the dojo source/target
  212. // tags:
  213. // callback
  214. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDndSource",source);
  215. // Only the case : "source dojo into a D&D dojoX Area" is treated.
  216. if(this._currentArea == null){
  217. return;
  218. }
  219. if(source){
  220. // Enter in a source/target dojo.
  221. // test if the type of draggedNode is accepted :
  222. var accept = false;
  223. if(this._dojoManager.target == source){
  224. accept = true;
  225. }
  226. else{
  227. accept = this.isAccepted(this._dragNode, source.accept);
  228. }
  229. if(accept){
  230. // disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area.
  231. dojo.disconnect(this._moveHandler);
  232. this._currentArea = this._moveHandler = null;
  233. // hidden the visibility of dojoX dropIndicator to prevent an offset when the dropIndicator disappears.
  234. // test if drop indicator is visible before applaying hidden style.
  235. var dropIndicator = this._areaManager._dropIndicator.node;
  236. if(dropIndicator && dropIndicator.parentNode !== null && dropIndicator.parentNode.nodeType == 1)
  237. dropIndicator.style.visibility = "hidden";
  238. }
  239. else{
  240. // if the type of dragged node is not accepted in the target dojo, the color of avatar
  241. // have to be the same that the color of D&D dojoX Area acceptance.
  242. this._resetAvatar();
  243. }
  244. }
  245. else{
  246. // Exit of a source/target dojo.
  247. // reconnect the onMouseMove to enabled the search of a drop zone in the D&D dojox Area.
  248. if(!this._moveHandler)
  249. this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
  250. this._resetAvatar();
  251. }
  252. },
  253. _resetAvatar: function(){
  254. // summary:
  255. // Function executed in onDndSource function to set the avatar
  256. // acceptance according to the dojox DnD AreaManager Acceptance.
  257. // It is used when The mouse exit a source/target dojo or if the
  258. // dragged node is not accepted in dojo source / target.
  259. // tags:
  260. // protected
  261. //console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar");
  262. if(this._dojoManager.avatar){
  263. if(this._areaManager._accept){
  264. dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  265. }
  266. else{
  267. dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
  268. }
  269. }
  270. },
  271. onDropCancel: function(){
  272. // summary:
  273. // Occurs when the "/dnd/cancel" topic is published.
  274. // tags:
  275. // callback
  276. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDropCancel");
  277. if(this._currentArea == null){
  278. // the dragged node is not in the D&D dojox Area => Cancel
  279. this._areaManager._resetAfterDrop();
  280. dojo.disconnect(this._moveHandler);
  281. dojo.disconnect(this._outSourceHandler);
  282. this._currentArea = this._moveHandler = this._outSourceHandler = null;
  283. }
  284. else{
  285. // the dragged node is in the D&D dojox Area
  286. // (catch when dragged node exits of a source/target dojo and stays in the same D&D dojox Area)
  287. // dojo cancel the drop but it's authorized in the D&D Area
  288. if(this._areaManager._accept){
  289. this.onDrop(this._source, [this._dragNode], this._copy, this._currentArea);
  290. }
  291. else{
  292. this._currentArea = null;
  293. dojo.disconnect(this._outSourceHandler);
  294. dojo.disconnect(this._moveHandler);
  295. this._moveHandler = this._outSourceHandler = null;
  296. }
  297. }
  298. },
  299. onDrop: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
  300. // summary:
  301. // Occurs when the user leaves a D&D dojox area after dragging an DOJO dnd item over it.
  302. // source:
  303. // the source which provides items
  304. // nodes:
  305. // the list of transferred items
  306. // copy:
  307. // copy items, if true, move items otherwise
  308. // tags:
  309. // callback
  310. //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea);
  311. dojo.disconnect(this._moveHandler);
  312. dojo.disconnect(this._outSourceHandler);
  313. this._moveHandler = this._outSourceHandler = null;
  314. if(this._currentArea){
  315. var dropIndex = this._areaManager._currentDropIndex;
  316. dojo.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]);
  317. this._currentArea = null;
  318. }
  319. if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
  320. this._areaManager._dropIndicator.node.style.visibility = "";
  321. }
  322. this._areaManager._resetAfterDrop();
  323. }
  324. });
  325. dojox.mdnd.adapter._dndFromDojo = null;
  326. dojox.mdnd.adapter._dndFromDojo = new dojox.mdnd.adapter.DndFromDojo();
  327. return dfd;
  328. });