]>
Commit | Line | Data |
---|---|---|
1354d172 AD |
1 | define("dojo/dnd/Manager", ["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) { |
2 | // module: | |
3 | // dojo/dnd/Manager | |
4 | // summary: | |
5 | // TODOC | |
6 | ||
7 | ||
8 | var Manager = dojo.declare("dojo.dnd.Manager", [Evented], { | |
9 | // summary: | |
10 | // the manager of DnD operations (usually a singleton) | |
11 | constructor: function(){ | |
12 | this.avatar = null; | |
13 | this.source = null; | |
14 | this.nodes = []; | |
15 | this.copy = true; | |
16 | this.target = null; | |
17 | this.canDropFlag = false; | |
18 | this.events = []; | |
19 | }, | |
20 | ||
21 | // avatar's offset from the mouse | |
22 | OFFSET_X: 16, | |
23 | OFFSET_Y: 16, | |
24 | ||
25 | // methods | |
26 | overSource: function(source){ | |
27 | // summary: | |
28 | // called when a source detected a mouse-over condition | |
29 | // source: Object | |
30 | // the reporter | |
31 | if(this.avatar){ | |
32 | this.target = (source && source.targetState != "Disabled") ? source : null; | |
33 | this.canDropFlag = Boolean(this.target); | |
34 | this.avatar.update(); | |
35 | } | |
36 | dojo.publish("/dnd/source/over", [source]); | |
37 | }, | |
38 | outSource: function(source){ | |
39 | // summary: | |
40 | // called when a source detected a mouse-out condition | |
41 | // source: Object | |
42 | // the reporter | |
43 | if(this.avatar){ | |
44 | if(this.target == source){ | |
45 | this.target = null; | |
46 | this.canDropFlag = false; | |
47 | this.avatar.update(); | |
48 | dojo.publish("/dnd/source/over", [null]); | |
49 | } | |
50 | }else{ | |
51 | dojo.publish("/dnd/source/over", [null]); | |
52 | } | |
53 | }, | |
54 | startDrag: function(source, nodes, copy){ | |
55 | // summary: | |
56 | // called to initiate the DnD operation | |
57 | // source: Object | |
58 | // the source which provides items | |
59 | // nodes: Array | |
60 | // the list of transferred items | |
61 | // copy: Boolean | |
62 | // copy items, if true, move items otherwise | |
63 | this.source = source; | |
64 | this.nodes = nodes; | |
65 | this.copy = Boolean(copy); // normalizing to true boolean | |
66 | this.avatar = this.makeAvatar(); | |
67 | dojo.body().appendChild(this.avatar.node); | |
68 | dojo.publish("/dnd/start", [source, nodes, this.copy]); | |
69 | this.events = [ | |
70 | dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"), | |
71 | dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"), | |
72 | dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"), | |
73 | dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp"), | |
74 | // cancel text selection and text dragging | |
75 | dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent), | |
76 | dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent) | |
77 | ]; | |
78 | var c = "dojoDnd" + (copy ? "Copy" : "Move"); | |
79 | dojo.addClass(dojo.body(), c); | |
80 | }, | |
81 | canDrop: function(flag){ | |
82 | // summary: | |
83 | // called to notify if the current target can accept items | |
84 | var canDropFlag = Boolean(this.target && flag); | |
85 | if(this.canDropFlag != canDropFlag){ | |
86 | this.canDropFlag = canDropFlag; | |
87 | this.avatar.update(); | |
88 | } | |
89 | }, | |
90 | stopDrag: function(){ | |
91 | // summary: | |
92 | // stop the DnD in progress | |
93 | dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]); | |
94 | dojo.forEach(this.events, dojo.disconnect); | |
95 | this.events = []; | |
96 | this.avatar.destroy(); | |
97 | this.avatar = null; | |
98 | this.source = this.target = null; | |
99 | this.nodes = []; | |
100 | }, | |
101 | makeAvatar: function(){ | |
102 | // summary: | |
103 | // makes the avatar; it is separate to be overwritten dynamically, if needed | |
104 | return new dojo.dnd.Avatar(this); | |
105 | }, | |
106 | updateAvatar: function(){ | |
107 | // summary: | |
108 | // updates the avatar; it is separate to be overwritten dynamically, if needed | |
109 | this.avatar.update(); | |
110 | }, | |
111 | ||
112 | // mouse event processors | |
113 | onMouseMove: function(e){ | |
114 | // summary: | |
115 | // event processor for onmousemove | |
116 | // e: Event | |
117 | // mouse event | |
118 | var a = this.avatar; | |
119 | if(a){ | |
120 | dojo.dnd.autoScrollNodes(e); | |
121 | //dojo.dnd.autoScroll(e); | |
122 | var s = a.node.style; | |
123 | s.left = (e.pageX + this.OFFSET_X) + "px"; | |
124 | s.top = (e.pageY + this.OFFSET_Y) + "px"; | |
125 | var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))); | |
126 | if(this.copy != copy){ | |
127 | this._setCopyStatus(copy); | |
128 | } | |
129 | } | |
130 | }, | |
131 | onMouseUp: function(e){ | |
132 | // summary: | |
133 | // event processor for onmouseup | |
134 | // e: Event | |
135 | // mouse event | |
136 | if(this.avatar){ | |
137 | if(this.target && this.canDropFlag){ | |
138 | var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))), | |
139 | params = [this.source, this.nodes, copy, this.target, e]; | |
140 | dojo.publish("/dnd/drop/before", params); | |
141 | dojo.publish("/dnd/drop", params); | |
142 | }else{ | |
143 | dojo.publish("/dnd/cancel"); | |
144 | } | |
145 | this.stopDrag(); | |
146 | } | |
147 | }, | |
148 | ||
149 | // keyboard event processors | |
150 | onKeyDown: function(e){ | |
151 | // summary: | |
152 | // event processor for onkeydown: | |
153 | // watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag | |
154 | // e: Event | |
155 | // keyboard event | |
156 | if(this.avatar){ | |
157 | switch(e.keyCode){ | |
158 | case dojo.keys.CTRL: | |
159 | var copy = Boolean(this.source.copyState(true)); | |
160 | if(this.copy != copy){ | |
161 | this._setCopyStatus(copy); | |
162 | } | |
163 | break; | |
164 | case dojo.keys.ESCAPE: | |
165 | dojo.publish("/dnd/cancel"); | |
166 | this.stopDrag(); | |
167 | break; | |
168 | } | |
169 | } | |
170 | }, | |
171 | onKeyUp: function(e){ | |
172 | // summary: | |
173 | // event processor for onkeyup, watching for CTRL for copy/move status | |
174 | // e: Event | |
175 | // keyboard event | |
176 | if(this.avatar && e.keyCode == dojo.keys.CTRL){ | |
177 | var copy = Boolean(this.source.copyState(false)); | |
178 | if(this.copy != copy){ | |
179 | this._setCopyStatus(copy); | |
180 | } | |
181 | } | |
182 | }, | |
183 | ||
184 | // utilities | |
185 | _setCopyStatus: function(copy){ | |
186 | // summary: | |
187 | // changes the copy status | |
188 | // copy: Boolean | |
189 | // the copy status | |
190 | this.copy = copy; | |
191 | this.source._markDndStatus(this.copy); | |
192 | this.updateAvatar(); | |
193 | dojo.replaceClass(dojo.body(), | |
194 | "dojoDnd" + (this.copy ? "Copy" : "Move"), | |
195 | "dojoDnd" + (this.copy ? "Move" : "Copy")); | |
196 | } | |
197 | }); | |
198 | ||
199 | // dojo.dnd._manager: | |
200 | // The manager singleton variable. Can be overwritten if needed. | |
201 | dojo.dnd._manager = null; | |
202 | ||
203 | Manager.manager = dojo.dnd.manager = function(){ | |
204 | // summary: | |
205 | // Returns the current DnD manager. Creates one if it is not created yet. | |
206 | if(!dojo.dnd._manager){ | |
207 | dojo.dnd._manager = new dojo.dnd.Manager(); | |
208 | } | |
209 | return dojo.dnd._manager; // Object | |
210 | }; | |
211 | ||
212 | return Manager; | |
213 | }); |