OverDropMode.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.mdnd.dropMode.OverDropMode"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.mdnd.dropMode.OverDropMode"] = true;
  8. dojo.provide("dojox.mdnd.dropMode.OverDropMode");
  9. dojo.require("dojox.mdnd.AreaManager");
  10. dojo.declare(
  11. "dojox.mdnd.dropMode.OverDropMode",
  12. null,
  13. {
  14. // summary:
  15. // Default class to find the nearest target only if the mouse is over an area.
  16. // _oldXPoint: Integer
  17. // used to save a X position
  18. _oldXPoint: null,
  19. // _oldYPoint: Integer
  20. // used to save a Y position
  21. _oldYPoint: null,
  22. // _oldBehaviour: Integer
  23. // see getDragpoint()
  24. _oldBehaviour: "up",
  25. constructor: function(){
  26. //console.log("dojox.mdnd.dropMode.OverDropMode ::: constructor");
  27. this._dragHandler = [
  28. dojo.connect(dojox.mdnd.areaManager(), "onDragEnter", function(coords, size){
  29. var m = dojox.mdnd.areaManager();
  30. if(m._oldIndexArea == -1){
  31. m._oldIndexArea = m._lastValidIndexArea;
  32. }
  33. })
  34. ];
  35. },
  36. addArea: function(/*Array*/areas, /*Object*/object){
  37. // summary:
  38. // Add a D&D Area into an array sorting by the x position.
  39. // areas:
  40. // array of areas
  41. // object:
  42. // data type of a DndArea
  43. // returns:
  44. // a sorted area
  45. //console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
  46. var length = areas.length,
  47. position = dojo.position(object.node, true);
  48. object.coords = {'x':position.x, 'y':position.y};
  49. if(length == 0){
  50. areas.push(object);
  51. }
  52. else{
  53. var x = object.coords.x;
  54. for(var i = 0; i < length; i++){
  55. if(x < areas[i].coords.x){
  56. for(var j = length-1; j >= i; j--)
  57. areas[j + 1] = areas[j];
  58. areas[i] = object;
  59. break;
  60. }
  61. }
  62. if(i == length){
  63. areas.push(object);
  64. }
  65. }
  66. return areas; // Array
  67. },
  68. updateAreas: function(/*Array*/areaList){
  69. // summary:
  70. // refresh areas position and size to determinate the nearest area to drop an item
  71. // description:
  72. // the area position (and size) is equal to the postion of the domNode associated.
  73. // areaList:
  74. // array of areas
  75. //console.log("dojox.mdnd.dropMode.OverDropMode ::: updateAreas");
  76. var length = areaList.length;
  77. for(var i = 0; i < length; i++){
  78. this._updateArea(areaList[i]);
  79. }
  80. },
  81. _updateArea : function(/*Object*/area){
  82. // summary:
  83. // update the D&D area object (i.e. update coordinates of its DOM node)
  84. // area:
  85. // the D&D area.
  86. // tags:
  87. // protected
  88. //console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
  89. var position = dojo.position(area.node, true);
  90. area.coords.x = position.x;
  91. area.coords.x2 = position.x + position.w;
  92. area.coords.y = position.y;
  93. },
  94. initItems: function(/*Object*/area){
  95. // summary:
  96. // initialize the horizontal line in order to determinate the drop zone.
  97. // area:
  98. // the D&D area.
  99. //console.log("dojox.mdnd.dropMode.OverDropMode ::: initItems");
  100. dojo.forEach(area.items, function(obj){
  101. //get the vertical middle of the item
  102. var node = obj.item.node;
  103. var position = dojo.position(node, true);
  104. var y = position.y + position.h/2;
  105. obj.y = y;
  106. });
  107. area.initItems = true;
  108. },
  109. refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
  110. // summary:
  111. // take into account the drop indicator DOM element in order to compute horizontal lines
  112. // area:
  113. // a D&D area object
  114. // indexItem:
  115. // index of a draggable item
  116. // size:
  117. // dropIndicator size
  118. // added:
  119. // boolean to know if a dropIndicator has been added or deleted
  120. //console.log("dojox.mdnd.dropMode.OverDropMode ::: refreshItems", area, indexItem, size, added);
  121. if(indexItem == -1){
  122. return;
  123. }
  124. else if(area && size && size.h){
  125. var height = size.h;
  126. if(area.margin){
  127. height += area.margin.t;
  128. }
  129. var length = area.items.length;
  130. for(var i = indexItem; i < length; i++){
  131. var item = area.items[i];
  132. if(added){
  133. item.y += height;
  134. }
  135. else{
  136. item.y -= height;
  137. }
  138. }
  139. }
  140. },
  141. getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
  142. // summary:
  143. // return coordinates of the draggable item.
  144. // - For X point : the x position of mouse
  145. // - For Y point : the y position of mouse
  146. // returns:
  147. // an object of coordinates
  148. // examples:{'x':10,'y':10}
  149. // coords:
  150. // an object encapsulating X and Y position
  151. // size:
  152. // an object encapsulating width and height values
  153. // mousePosition:
  154. // coordinates of mouse
  155. //console.log("dojox.mdnd.OverDropMode ::: getDragPoint");
  156. return { // Object
  157. 'x': mousePosition.x,
  158. 'y': mousePosition.y
  159. }
  160. },
  161. getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
  162. // summary:
  163. // get the nearest D&D area.
  164. // areaList:
  165. // a list of D&D areas objects
  166. // coords:
  167. // coordinates [x,y] of the dragItem (see getDragPoint())
  168. // currentIndexArea:
  169. // an index representing the active D&D area
  170. //returns:
  171. // the index of the D&D area
  172. //console.log("dojox.mdnd.dropMode.OverDropMode ::: getTargetArea");
  173. var index = 0;
  174. var x = coords.x;
  175. var y = coords.y;
  176. var end = areaList.length;
  177. var start = 0, direction = "right", compute = false;
  178. if(currentIndexArea == -1 || arguments.length < 3){
  179. // first time : Need to search the nearest area in all areas.
  180. compute = true;
  181. }
  182. else{
  183. // check if it's always the same area
  184. if(this._checkInterval(areaList, currentIndexArea, x, y)){
  185. index = currentIndexArea;
  186. }
  187. else{
  188. if(this._oldXPoint < x){
  189. start = currentIndexArea + 1;
  190. }
  191. else{
  192. start = currentIndexArea - 1;
  193. end = 0;
  194. direction = "left";
  195. }
  196. compute = true;
  197. }
  198. }
  199. if(compute){
  200. if(direction === "right"){
  201. for(var i = start; i < end; i++){
  202. if(this._checkInterval(areaList, i, x, y)){
  203. index = i;
  204. break;
  205. }
  206. }
  207. if(i == end){
  208. index = -1;
  209. }
  210. }
  211. else{
  212. for(var i = start; i >= end; i--){
  213. if(this._checkInterval(areaList, i, x, y)){
  214. index = i;
  215. break;
  216. }
  217. }
  218. if(i == end-1){
  219. index = -1;
  220. }
  221. }
  222. }
  223. this._oldXPoint = x;
  224. return index; // Integer
  225. },
  226. _checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x, /*Coord*/y){
  227. // summary:
  228. // check if the dragNode is in the interval.
  229. // returns:
  230. // true if the dragNode is in intervall
  231. // areaList:
  232. // a list of D&D areas objects
  233. // index:
  234. // index of a D&D area (to get the interval)
  235. // x:
  236. // coordinate x, of the dragNode (see getDragPoint())
  237. // tags:
  238. // protected
  239. //console.log("dojox.mdnd.dropMode.OverDropMode ::: _checkInterval");
  240. var area = areaList[index];
  241. var node = area.node;
  242. var coords = area.coords;
  243. var startX = coords.x;
  244. var endX = coords.x2;
  245. var startY = coords.y;
  246. var endY = startY + node.offsetHeight;
  247. if(startX <= x && x <= endX && startY <= y && y <= endY){
  248. return true;
  249. }
  250. return false; // Boolean
  251. },
  252. getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
  253. // summary:
  254. // Return the index where the drop has to be placed.
  255. // targetArea:
  256. // a D&D area object.
  257. // coords:
  258. // coordinates [x,y] of the draggable item.
  259. // returns:
  260. // a number or -1 if the area has no children or the drop index represents the last position in to the area
  261. //console.log("dojox.mdnd.dropMode.OverDropMode ::: getDropIndex");
  262. var length = targetArea.items.length;
  263. var coordinates = targetArea.coords;
  264. var y = coords.y;
  265. if(length > 0){
  266. // course all children in the target area.
  267. for(var i = 0; i < length; i++){
  268. // compare y value with y value of children
  269. if(y < targetArea.items[i].y){
  270. return i; // integer
  271. }
  272. else{
  273. if(i == length-1){
  274. return -1; // integer
  275. }
  276. }
  277. }
  278. }
  279. return -1; //integer
  280. },
  281. destroy: function(){
  282. dojo.forEach(this._dragHandler, dojo.disconnect);
  283. }
  284. });
  285. (function(){
  286. dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.OverDropMode();
  287. }());
  288. }