OverDropMode.js 8.0 KB

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