DragSource.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.dd.DragSource
  8. * @extends Ext.dd.DDProxy A simple class that provides the basic implementation
  9. * needed to make any element draggable.
  10. * @constructor
  11. * @param {Mixed}
  12. * el The container element
  13. * @param {Object}
  14. * config
  15. */
  16. Ext.dd.DragSource = function(el, config) {
  17. this.el = Ext.get(el);
  18. if (!this.dragData) {
  19. this.dragData = {};
  20. }
  21. Ext.apply(this, config);
  22. if (!this.proxy) {
  23. this.proxy = new Ext.dd.StatusProxy();
  24. }
  25. Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom,
  26. this.ddGroup || this.group, {
  27. dragElId : this.proxy.id,
  28. resizeFrame : false,
  29. isTarget : false,
  30. scroll : this.scroll === true
  31. });
  32. this.dragging = false;
  33. };
  34. Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
  35. /**
  36. * @cfg {String} ddGroup A named drag drop group to which this object
  37. * belongs. If a group is specified, then this object will only
  38. * interact with other drag drop objects in the same group (defaults to
  39. * undefined).
  40. */
  41. /**
  42. * @cfg {String} dropAllowed The CSS class returned to the drag source when
  43. * drop is allowed (defaults to "x-dd-drop-ok").
  44. */
  45. dropAllowed : "x-dd-drop-ok",
  46. /**
  47. * @cfg {String} dropNotAllowed The CSS class returned to the drag source
  48. * when drop is not allowed (defaults to "x-dd-drop-nodrop").
  49. */
  50. dropNotAllowed : "x-dd-drop-nodrop",
  51. /**
  52. * Returns the data object associated with this drag source
  53. *
  54. * @return {Object} data An object containing arbitrary data
  55. */
  56. getDragData : function(e) {
  57. return this.dragData;
  58. },
  59. // private
  60. onDragEnter : function(e, id) {
  61. var target = Ext.dd.DragDropMgr.getDDById(id);
  62. this.cachedTarget = target;
  63. if (this.beforeDragEnter(target, e, id) !== false) {
  64. if (target.isNotifyTarget) {
  65. var status = target.notifyEnter(this, e, this.dragData);
  66. this.proxy.setStatus(status);
  67. } else {
  68. this.proxy.setStatus(this.dropAllowed);
  69. }
  70. if (this.afterDragEnter) {
  71. /**
  72. * An empty function by default, but provided so that you can
  73. * perform a custom action when the dragged item enters the drop
  74. * target by providing an implementation.
  75. *
  76. * @param {Ext.dd.DragDrop}
  77. * target The drop target
  78. * @param {Event}
  79. * e The event object
  80. * @param {String}
  81. * id The id of the dragged element
  82. * @method afterDragEnter
  83. */
  84. this.afterDragEnter(target, e, id);
  85. }
  86. }
  87. },
  88. /**
  89. * An empty function by default, but provided so that you can perform a
  90. * custom action before the dragged item enters the drop target and
  91. * optionally cancel the onDragEnter.
  92. *
  93. * @param {Ext.dd.DragDrop}
  94. * target The drop target
  95. * @param {Event}
  96. * e The event object
  97. * @param {String}
  98. * id The id of the dragged element
  99. * @return {Boolean} isValid True if the drag event is valid, else false to
  100. * cancel
  101. */
  102. beforeDragEnter : function(target, e, id) {
  103. return true;
  104. },
  105. // private
  106. alignElWithMouse : function() {
  107. Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
  108. this.proxy.sync();
  109. },
  110. // private
  111. onDragOver : function(e, id) {
  112. var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
  113. if (this.beforeDragOver(target, e, id) !== false) {
  114. if (target.isNotifyTarget) {
  115. var status = target.notifyOver(this, e, this.dragData);
  116. this.proxy.setStatus(status);
  117. }
  118. if (this.afterDragOver) {
  119. /**
  120. * An empty function by default, but provided so that you can
  121. * perform a custom action while the dragged item is over the
  122. * drop target by providing an implementation.
  123. *
  124. * @param {Ext.dd.DragDrop}
  125. * target The drop target
  126. * @param {Event}
  127. * e The event object
  128. * @param {String}
  129. * id The id of the dragged element
  130. * @method afterDragOver
  131. */
  132. this.afterDragOver(target, e, id);
  133. }
  134. }
  135. },
  136. /**
  137. * An empty function by default, but provided so that you can perform a
  138. * custom action while the dragged item is over the drop target and
  139. * optionally cancel the onDragOver.
  140. *
  141. * @param {Ext.dd.DragDrop}
  142. * target The drop target
  143. * @param {Event}
  144. * e The event object
  145. * @param {String}
  146. * id The id of the dragged element
  147. * @return {Boolean} isValid True if the drag event is valid, else false to
  148. * cancel
  149. */
  150. beforeDragOver : function(target, e, id) {
  151. return true;
  152. },
  153. // private
  154. onDragOut : function(e, id) {
  155. var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
  156. if (this.beforeDragOut(target, e, id) !== false) {
  157. if (target.isNotifyTarget) {
  158. target.notifyOut(this, e, this.dragData);
  159. }
  160. this.proxy.reset();
  161. if (this.afterDragOut) {
  162. /**
  163. * An empty function by default, but provided so that you can
  164. * perform a custom action after the dragged item is dragged out
  165. * of the target without dropping.
  166. *
  167. * @param {Ext.dd.DragDrop}
  168. * target The drop target
  169. * @param {Event}
  170. * e The event object
  171. * @param {String}
  172. * id The id of the dragged element
  173. * @method afterDragOut
  174. */
  175. this.afterDragOut(target, e, id);
  176. }
  177. }
  178. this.cachedTarget = null;
  179. },
  180. /**
  181. * An empty function by default, but provided so that you can perform a
  182. * custom action before the dragged item is dragged out of the target
  183. * without dropping, and optionally cancel the onDragOut.
  184. *
  185. * @param {Ext.dd.DragDrop}
  186. * target The drop target
  187. * @param {Event}
  188. * e The event object
  189. * @param {String}
  190. * id The id of the dragged element
  191. * @return {Boolean} isValid True if the drag event is valid, else false to
  192. * cancel
  193. */
  194. beforeDragOut : function(target, e, id) {
  195. return true;
  196. },
  197. // private
  198. onDragDrop : function(e, id) {
  199. var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
  200. if (this.beforeDragDrop(target, e, id) !== false) {
  201. if (target.isNotifyTarget) {
  202. if (target.notifyDrop(this, e, this.dragData)) { // valid
  203. // drop?
  204. this.onValidDrop(target, e, id);
  205. } else {
  206. this.onInvalidDrop(target, e, id);
  207. }
  208. } else {
  209. this.onValidDrop(target, e, id);
  210. }
  211. if (this.afterDragDrop) {
  212. /**
  213. * An empty function by default, but provided so that you can
  214. * perform a custom action after a valid drag drop has occurred
  215. * by providing an implementation.
  216. *
  217. * @param {Ext.dd.DragDrop}
  218. * target The drop target
  219. * @param {Event}
  220. * e The event object
  221. * @param {String}
  222. * id The id of the dropped element
  223. * @method afterDragDrop
  224. */
  225. this.afterDragDrop(target, e, id);
  226. }
  227. }
  228. delete this.cachedTarget;
  229. },
  230. /**
  231. * An empty function by default, but provided so that you can perform a
  232. * custom action before the dragged item is dropped onto the target and
  233. * optionally cancel the onDragDrop.
  234. *
  235. * @param {Ext.dd.DragDrop}
  236. * target The drop target
  237. * @param {Event}
  238. * e The event object
  239. * @param {String}
  240. * id The id of the dragged element
  241. * @return {Boolean} isValid True if the drag drop event is valid, else
  242. * false to cancel
  243. */
  244. beforeDragDrop : function(target, e, id) {
  245. return true;
  246. },
  247. // private
  248. onValidDrop : function(target, e, id) {
  249. this.hideProxy();
  250. if (this.afterValidDrop) {
  251. /**
  252. * An empty function by default, but provided so that you can
  253. * perform a custom action after a valid drop has occurred by
  254. * providing an implementation.
  255. *
  256. * @param {Object}
  257. * target The target DD
  258. * @param {Event}
  259. * e The event object
  260. * @param {String}
  261. * id The id of the dropped element
  262. * @method afterInvalidDrop
  263. */
  264. this.afterValidDrop(target, e, id);
  265. }
  266. },
  267. // private
  268. getRepairXY : function(e, data) {
  269. return this.el.getXY();
  270. },
  271. // private
  272. onInvalidDrop : function(target, e, id) {
  273. this.beforeInvalidDrop(target, e, id);
  274. if (this.cachedTarget) {
  275. if (this.cachedTarget.isNotifyTarget) {
  276. this.cachedTarget.notifyOut(this, e, this.dragData);
  277. }
  278. this.cacheTarget = null;
  279. }
  280. this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair,
  281. this);
  282. if (this.afterInvalidDrop) {
  283. /**
  284. * An empty function by default, but provided so that you can
  285. * perform a custom action after an invalid drop has occurred by
  286. * providing an implementation.
  287. *
  288. * @param {Event}
  289. * e The event object
  290. * @param {String}
  291. * id The id of the dropped element
  292. * @method afterInvalidDrop
  293. */
  294. this.afterInvalidDrop(e, id);
  295. }
  296. },
  297. // private
  298. afterRepair : function() {
  299. if (Ext.enableFx) {
  300. this.el.highlight(this.hlColor || "c3daf9");
  301. }
  302. this.dragging = false;
  303. },
  304. /**
  305. * An empty function by default, but provided so that you can perform a
  306. * custom action after an invalid drop has occurred.
  307. *
  308. * @param {Ext.dd.DragDrop}
  309. * target The drop target
  310. * @param {Event}
  311. * e The event object
  312. * @param {String}
  313. * id The id of the dragged element
  314. * @return {Boolean} isValid True if the invalid drop should proceed, else
  315. * false to cancel
  316. */
  317. beforeInvalidDrop : function(target, e, id) {
  318. return true;
  319. },
  320. // private
  321. handleMouseDown : function(e) {
  322. if (this.dragging) {
  323. return;
  324. }
  325. var data = this.getDragData(e);
  326. if (data && this.onBeforeDrag(data, e) !== false) {
  327. this.dragData = data;
  328. this.proxy.stop();
  329. Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
  330. }
  331. },
  332. /**
  333. * An empty function by default, but provided so that you can perform a
  334. * custom action before the initial drag event begins and optionally cancel
  335. * it.
  336. *
  337. * @param {Object}
  338. * data An object containing arbitrary data to be shared with
  339. * drop targets
  340. * @param {Event}
  341. * e The event object
  342. * @return {Boolean} isValid True if the drag event is valid, else false to
  343. * cancel
  344. */
  345. onBeforeDrag : function(data, e) {
  346. return true;
  347. },
  348. /**
  349. * An empty function by default, but provided so that you can perform a
  350. * custom action once the initial drag event has begun. The drag cannot be
  351. * canceled from this function.
  352. *
  353. * @param {Number}
  354. * x The x position of the click on the dragged object
  355. * @param {Number}
  356. * y The y position of the click on the dragged object
  357. */
  358. onStartDrag : Ext.emptyFn,
  359. // private override
  360. startDrag : function(x, y) {
  361. this.proxy.reset();
  362. this.dragging = true;
  363. this.proxy.update("");
  364. this.onInitDrag(x, y);
  365. this.proxy.show();
  366. },
  367. // private
  368. onInitDrag : function(x, y) {
  369. var clone = this.el.dom.cloneNode(true);
  370. clone.id = Ext.id(); // prevent duplicate ids
  371. this.proxy.update(clone);
  372. this.onStartDrag(x, y);
  373. return true;
  374. },
  375. /**
  376. * Returns the drag source's underlying {@link Ext.dd.StatusProxy}
  377. *
  378. * @return {Ext.dd.StatusProxy} proxy The StatusProxy
  379. */
  380. getProxy : function() {
  381. return this.proxy;
  382. },
  383. /**
  384. * Hides the drag source's {@link Ext.dd.StatusProxy}
  385. */
  386. hideProxy : function() {
  387. this.proxy.hide();
  388. this.proxy.reset(true);
  389. this.dragging = false;
  390. },
  391. // private
  392. triggerCacheRefresh : function() {
  393. Ext.dd.DDM.refreshCache(this.groups);
  394. },
  395. // private - override to prevent hiding
  396. b4EndDrag : function(e) {
  397. },
  398. // private - override to prevent moving
  399. endDrag : function(e) {
  400. this.onEndDrag(this.dragData, e);
  401. },
  402. // private
  403. onEndDrag : function(data, e) {
  404. },
  405. // private - pin to cursor
  406. autoOffset : function(x, y) {
  407. this.setDelta(-12, -20);
  408. }
  409. });