Moveable.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. define("dojo/dnd/Moveable", ["../main", "../Evented", "../touch", "./Mover"], function(dojo, Evented, touch) {
  2. // module:
  3. // dojo/dnd/Moveable
  4. // summary:
  5. // TODOC
  6. /*=====
  7. dojo.declare("dojo.dnd.__MoveableArgs", [], {
  8. // handle: Node||String
  9. // A node (or node's id), which is used as a mouse handle.
  10. // If omitted, the node itself is used as a handle.
  11. handle: null,
  12. // delay: Number
  13. // delay move by this number of pixels
  14. delay: 0,
  15. // skip: Boolean
  16. // skip move of form elements
  17. skip: false,
  18. // mover: Object
  19. // a constructor of custom Mover
  20. mover: dojo.dnd.Mover
  21. });
  22. =====*/
  23. dojo.declare("dojo.dnd.Moveable", [Evented], {
  24. // object attributes (for markup)
  25. handle: "",
  26. delay: 0,
  27. skip: false,
  28. constructor: function(node, params){
  29. // summary:
  30. // an object, which makes a node moveable
  31. // node: Node
  32. // a node (or node's id) to be moved
  33. // params: dojo.dnd.__MoveableArgs?
  34. // optional parameters
  35. this.node = dojo.byId(node);
  36. if(!params){ params = {}; }
  37. this.handle = params.handle ? dojo.byId(params.handle) : null;
  38. if(!this.handle){ this.handle = this.node; }
  39. this.delay = params.delay > 0 ? params.delay : 0;
  40. this.skip = params.skip;
  41. this.mover = params.mover ? params.mover : dojo.dnd.Mover;
  42. this.events = [
  43. dojo.connect(this.handle, touch.press, this, "onMouseDown"),
  44. // cancel text selection and text dragging
  45. dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
  46. dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
  47. ];
  48. },
  49. // markup methods
  50. markupFactory: function(params, node, ctor){
  51. return new ctor(node, params);
  52. },
  53. // methods
  54. destroy: function(){
  55. // summary:
  56. // stops watching for possible move, deletes all references, so the object can be garbage-collected
  57. dojo.forEach(this.events, dojo.disconnect);
  58. this.events = this.node = this.handle = null;
  59. },
  60. // mouse event processors
  61. onMouseDown: function(e){
  62. // summary:
  63. // event processor for onmousedown/ontouchstart, creates a Mover for the node
  64. // e: Event
  65. // mouse/touch event
  66. if(this.skip && dojo.dnd.isFormElement(e)){ return; }
  67. if(this.delay){
  68. this.events.push(
  69. dojo.connect(this.handle, touch.move, this, "onMouseMove"),
  70. dojo.connect(this.handle, touch.release, this, "onMouseUp")
  71. );
  72. this._lastX = e.pageX;
  73. this._lastY = e.pageY;
  74. }else{
  75. this.onDragDetected(e);
  76. }
  77. dojo.stopEvent(e);
  78. },
  79. onMouseMove: function(e){
  80. // summary:
  81. // event processor for onmousemove/ontouchmove, used only for delayed drags
  82. // e: Event
  83. // mouse/touch event
  84. if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
  85. this.onMouseUp(e);
  86. this.onDragDetected(e);
  87. }
  88. dojo.stopEvent(e);
  89. },
  90. onMouseUp: function(e){
  91. // summary:
  92. // event processor for onmouseup, used only for delayed drags
  93. // e: Event
  94. // mouse event
  95. for(var i = 0; i < 2; ++i){
  96. dojo.disconnect(this.events.pop());
  97. }
  98. dojo.stopEvent(e);
  99. },
  100. onSelectStart: function(e){
  101. // summary:
  102. // event processor for onselectevent and ondragevent
  103. // e: Event
  104. // mouse event
  105. if(!this.skip || !dojo.dnd.isFormElement(e)){
  106. dojo.stopEvent(e);
  107. }
  108. },
  109. // local events
  110. onDragDetected: function(/* Event */ e){
  111. // summary:
  112. // called when the drag is detected;
  113. // responsible for creation of the mover
  114. new this.mover(this.node, e, this);
  115. },
  116. onMoveStart: function(/* dojo.dnd.Mover */ mover){
  117. // summary:
  118. // called before every move operation
  119. dojo.publish("/dnd/move/start", [mover]);
  120. dojo.addClass(dojo.body(), "dojoMove");
  121. dojo.addClass(this.node, "dojoMoveItem");
  122. },
  123. onMoveStop: function(/* dojo.dnd.Mover */ mover){
  124. // summary:
  125. // called after every move operation
  126. dojo.publish("/dnd/move/stop", [mover]);
  127. dojo.removeClass(dojo.body(), "dojoMove");
  128. dojo.removeClass(this.node, "dojoMoveItem");
  129. },
  130. onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
  131. // summary:
  132. // called during the very first move notification;
  133. // can be used to initialize coordinates, can be overwritten.
  134. // default implementation does nothing
  135. },
  136. onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
  137. // summary:
  138. // called during every move notification;
  139. // should actually move the node; can be overwritten.
  140. this.onMoving(mover, leftTop);
  141. var s = mover.node.style;
  142. s.left = leftTop.l + "px";
  143. s.top = leftTop.t + "px";
  144. this.onMoved(mover, leftTop);
  145. },
  146. onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
  147. // summary:
  148. // called before every incremental move; can be overwritten.
  149. // default implementation does nothing
  150. },
  151. onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
  152. // summary:
  153. // called after every incremental move; can be overwritten.
  154. // default implementation does nothing
  155. }
  156. });
  157. return dojo.dnd.Moveable;
  158. });