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