drag.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * $Id: TinyMCE_DOMUtils.class.js 91 2006-10-02 14:53:22Z spocke $
  3. *
  4. * @author Moxiecode
  5. * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
  6. */
  7. mox.require([
  8. 'mox.DOM',
  9. 'mox.Event',
  10. 'mox.geom.Point',
  11. 'mox.geom.Rect',
  12. 'mox.List',
  13. 'mox.util.Dispatcher'
  14. ], function() {
  15. // Shorten class names
  16. var DOM = mox.DOM;
  17. var Event = mox.Event;
  18. var Point = mox.geom.Point;
  19. var Rect = mox.geom.Rect;
  20. var List = mox.List;
  21. var Dispatcher = mox.util.Dispatcher;
  22. /**#@+
  23. * @class This class is used to make items draggable.
  24. * @member mox.dom.Drag
  25. * @base mox.dom.Layer'
  26. */
  27. mox.create('mox.dom.Drag:mox.dom.Layer', {
  28. settings : null,
  29. started : false,
  30. startPos : null,
  31. startRect : null,
  32. boundery : null,
  33. eventDocs : null,
  34. dropRects : null,
  35. hoverRect : null,
  36. /**
  37. * Constructs a new draggable instance of the specified target element.
  38. *
  39. * @param {string} t Id of target element to make dragable.
  40. * @param {Object} s Optional name/value settings object.
  41. * @constructor
  42. */
  43. Drag : function(t, s) {
  44. var n, dr = this;
  45. this.parent(t, false);
  46. this.eventDocs = [document];
  47. // Default settings
  48. this.settings = {
  49. drag_handle : t,
  50. drop_points : '',
  51. ondrag : mox.bind(this, this.onDragEvent)
  52. };
  53. for (n in s)
  54. this.settings[n] = s[n];
  55. s = this.settings;
  56. this.setDropPoints(s.drop_points);
  57. List.map(s.drag_handle.split(','), function(i, v) {
  58. Event.add(DOM.get(v), 'mousedown', dr.onMouseDownDrag, dr);
  59. });
  60. this.onEnter = new Dispatcher(this);
  61. this.onLeave = new Dispatcher(this);
  62. this.onDragStart = new Dispatcher(this);
  63. this.onDragEnd = new Dispatcher(this);
  64. this.onDrag = new Dispatcher(this);
  65. this.onDrop = new Dispatcher(this);
  66. this.onOver = new Dispatcher(this);
  67. this.onMouseDown = new Dispatcher(this);
  68. },
  69. /**#@+
  70. * @method
  71. */
  72. /**
  73. * Starts the drag operation. This is automaticly done if the
  74. * user clicks the element or drag handle.
  75. *
  76. * @param {Element} he Optinal drag handle element. Will be passed to dragstart callback.
  77. */
  78. start : function(he) {
  79. if (!this.started) {
  80. this.updateRect();
  81. this.startRect = new Rect(this.x, this.y, this.w, this.h);
  82. this.addDocEvent('mousemove', this.onMouseMove, this);
  83. this.addDocEvent('mouseup', this.end, this);
  84. this.onDragStart.dispatch(he);
  85. this.started = true;
  86. }
  87. },
  88. /**
  89. * Ends the drag operation. This is automaticly done if the
  90. * user releases the mouse button.
  91. */
  92. end : function() {
  93. if (this.started) {
  94. this.removeDocEvent('mousemove', this.onMouseMove, this);
  95. this.removeDocEvent('mouseup', this.end, this);
  96. this.onDragEnd.dispatch();
  97. if (this.hoverRect)
  98. this.onDrop.dispatch(this.hoverRect.el);
  99. this.hoverRect = null;
  100. this.started = false;
  101. }
  102. },
  103. /**
  104. * Sets the boundery rectance of the draggable instance.
  105. * This boundery restricts where the user might drag the element.
  106. *
  107. * @param {Number} x X cordinate/Horizontal position.
  108. * @param {Number} y Y cordinate/Vertical position.
  109. * @param {Number} w Width of the rectange.
  110. * @param {Number} h Height of the rectange.
  111. */
  112. setBounderies : function(x, y, w, h) {
  113. return this.boundery = new Rect(x, y, w, h);
  114. },
  115. setDropPoints : function(e) {
  116. var i, r;
  117. if (!e)
  118. return;
  119. for (i=0, e = e.split(','), this.dropRects = []; i<e.length; i++) {
  120. r = DOM.getRect(e[i]);
  121. r.el = e[i];
  122. this.dropRects.push(r);
  123. }
  124. },
  125. onMouseMove : function(e) {
  126. var x, y, sr = this.startRect, sp = this.startPos, b = this.boundery, dx, dy;
  127. dx = e.screenX - sp.x;
  128. dy = e.screenY - sp.y;
  129. x = sr.x + dx;
  130. y = sr.y + dy;
  131. if (b) {
  132. if (x < b.x)
  133. x = b.x;
  134. if (y < b.y)
  135. y = b.y;
  136. if (x + this.w > b.x + b.w)
  137. x = (b.x + b.w) - this.w;
  138. if (y + this.h > b.y + b.h)
  139. y = (b.y + b.h) - this.h;
  140. }
  141. if (this.onDrag.dispatch(dx, dy, x, y) !== false)
  142. this.moveTo(x, y);
  143. this.handleHoverRect(dx, dy);
  144. return Event.cancel(e);
  145. },
  146. handleHoverRect : function(dx, dy) {
  147. var mx, my, i, l, dr = this.dropRects;
  148. if (dr) {
  149. mx = this.mouseDownPos.x + dx;
  150. my = this.mouseDownPos.y + dy;
  151. for (i=0, l=dr.length; i<l; i++) {
  152. if (dr[i].containsXY(mx, my)) {
  153. if (this.hoverRect != dr[i]) {
  154. if (this.hoverRect)
  155. this.onLeave.dispatch(this.hoverRect.el);
  156. this.onEnter.dispatch(dr[i].el);
  157. this.hoverRect = dr[i];
  158. }
  159. this.onOver.dispatch(dr[i].el);
  160. return;
  161. }
  162. }
  163. if (this.hoverRect) {
  164. this.onLeave.dispatch(this.hoverRect.el);
  165. this.hoverRect = null;
  166. }
  167. }
  168. },
  169. startDrag : function(e) {
  170. var mx, my;
  171. mx = !e.pageX ? e.x + document.body.scrollLeft : e.pageX;
  172. my = !e.pageY ? e.y + document.body.scrollTop : e.pageY;
  173. this.start(e.target);
  174. this.startPos = new Point(e.screenX, e.screenY);
  175. this.mouseDownPos = new Point(mx, my);
  176. },
  177. onMouseDownDrag : function(e) {
  178. this.onMouseDown.dispatch(e);
  179. this.startDrag(e, 'move');
  180. return Event.cancel(e);
  181. },
  182. addEventDoc : function(d) {
  183. this.eventDocs.push(d);
  184. },
  185. addDocEvent : function(n, f, s) {
  186. var i, dl = this.eventDocs;
  187. for (i=0; i<dl.length; i++)
  188. Event.add(dl[i], n, f, s);
  189. },
  190. removeDocEvent : function(n, f, s) {
  191. var i, dl = this.eventDocs;
  192. for (i=0; i<dl.length; i++)
  193. Event.remove(dl[i], n, f, s);
  194. }
  195. /**#@-*/
  196. });
  197. });