2 Copyright (c) 2004-2011, 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
8 if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9 dojo._hasResource["dojo.dnd.Moveable"] = true;
10 dojo.provide("dojo.dnd.Moveable");
11 dojo.require("dojo.dnd.Mover");
15 dojo.declare("dojo.dnd.__MoveableArgs", [], {
16 // handle: Node||String
17 // A node (or node's id), which is used as a mouse handle.
18 // If omitted, the node itself is used as a handle.
22 // delay move by this number of pixels
26 // skip move of form elements
30 // a constructor of custom Mover
35 dojo.declare("dojo.dnd.Moveable", null, {
36 // object attributes (for markup)
41 constructor: function(node, params){
43 // an object, which makes a node moveable
45 // a node (or node's id) to be moved
46 // params: dojo.dnd.__MoveableArgs?
47 // optional parameters
48 this.node = dojo.byId(node);
49 if(!params){ params = {}; }
50 this.handle = params.handle ? dojo.byId(params.handle) : null;
51 if(!this.handle){ this.handle = this.node; }
52 this.delay = params.delay > 0 ? params.delay : 0;
53 this.skip = params.skip;
54 this.mover = params.mover ? params.mover : dojo.dnd.Mover;
56 dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
57 dojo.connect(this.handle, "ontouchstart", this, "onMouseDown"),
58 // cancel text selection and text dragging
59 dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
60 dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
65 markupFactory: function(params, node){
66 return new dojo.dnd.Moveable(node, params);
72 // stops watching for possible move, deletes all references, so the object can be garbage-collected
73 dojo.forEach(this.events, dojo.disconnect);
74 this.events = this.node = this.handle = null;
77 // mouse event processors
78 onMouseDown: function(e){
80 // event processor for onmousedown/ontouchstart, creates a Mover for the node
83 if(this.skip && dojo.dnd.isFormElement(e)){ return; }
86 dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
87 dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
88 dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
89 dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
91 var pos = e.touches ? e.touches[0] : e;
92 this._lastX = pos.pageX;
93 this._lastY = pos.pageY;
95 this.onDragDetected(e);
99 onMouseMove: function(e){
101 // event processor for onmousemove/ontouchmove, used only for delayed drags
104 var pos = e.touches ? e.touches[0] : e;
105 if(Math.abs(pos.pageX - this._lastX) > this.delay || Math.abs(pos.pageY - this._lastY) > this.delay){
107 this.onDragDetected(e);
111 onMouseUp: function(e){
113 // event processor for onmouseup, used only for delayed drags
116 for(var i = 0; i < 2; ++i){
117 dojo.disconnect(this.events.pop());
121 onSelectStart: function(e){
123 // event processor for onselectevent and ondragevent
126 if(!this.skip || !dojo.dnd.isFormElement(e)){
132 onDragDetected: function(/* Event */ e){
134 // called when the drag is detected;
135 // responsible for creation of the mover
136 new this.mover(this.node, e, this);
138 onMoveStart: function(/* dojo.dnd.Mover */ mover){
140 // called before every move operation
141 dojo.publish("/dnd/move/start", [mover]);
142 dojo.addClass(dojo.body(), "dojoMove");
143 dojo.addClass(this.node, "dojoMoveItem");
145 onMoveStop: function(/* dojo.dnd.Mover */ mover){
147 // called after every move operation
148 dojo.publish("/dnd/move/stop", [mover]);
149 dojo.removeClass(dojo.body(), "dojoMove");
150 dojo.removeClass(this.node, "dojoMoveItem");
152 onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
154 // called during the very first move notification;
155 // can be used to initialize coordinates, can be overwritten.
157 // default implementation does nothing
159 onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
161 // called during every move notification;
162 // should actually move the node; can be overwritten.
163 this.onMoving(mover, leftTop);
164 var s = mover.node.style;
165 s.left = leftTop.l + "px";
166 s.top = leftTop.t + "px";
167 this.onMoved(mover, leftTop);
169 onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
171 // called before every incremental move; can be overwritten.
173 // default implementation does nothing
175 onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
177 // called after every incremental move; can be overwritten.
179 // default implementation does nothing