source: Dev/branches/rest-dojo-ui/client/dojox/mdnd/adapter/DndFromDojo.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 12.3 KB
Line 
1define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/array",
2        "dojo/_base/html","dojo/_base/window","dojox/mdnd/AreaManager","dojo/dnd/Manager"],function(dojo){
3        var dfd = dojo.declare(
4                "dojox.mdnd.adapter.DndFromDojo",
5                null,
6        {
7                // summary
8                //              Allow communication between Dojo dnd items and DojoX D&D areas
9       
10                // dropIndicatorSize: Object
11                //              size by default of dropIndicator (display only into a D&D Area)
12                dropIndicatorSize : {'w':0,'h':50},
13       
14                // dropIndicatorSize: Object
15                //              size by default of dropIndicator (display only into a D&D Area)
16                dropIndicatorSize: {'w':0,'h':50},
17       
18                // _areaManager: Object
19                //              Reference to the current DojoX Dnd Manager
20                _areaManager: null,
21       
22                // _dojoManager
23                //              Reference to the current Dojo Manager
24                _dojoManager: null,
25       
26                // _currentArea: Object
27                //              The current Area on mouse over
28                _currentArea: null,
29       
30                // _oldArea: Object
31                //              The old area the mouse has passed over
32                _oldArea: null,
33       
34                // _moveHandler: Object
35                //              The handler of mouse connection
36                _moveHandler: null,
37       
38                // _subscribeHandler: Array
39                //              The list of dojo dnd topics
40                _subscribeHandler: null,
41       
42                constructor: function(){
43                        this._areaManager = dojox.mdnd.areaManager();
44                        this._dojoManager = dojo.dnd.manager();
45                        this._currentArea = null;
46                        this._moveHandler = null;
47                        this.subscribeDnd();
48                },
49       
50                subscribeDnd: function(){
51                        // summary:
52                        //              Subscribe to somes topics of dojo drag and drop.
53       
54                        //console.log(("dojox.mdnd.adapter.DndFromDojo ::: subscribeDnd");
55                        this._subscribeHandler = [
56                                dojo.subscribe("/dnd/start",this,"onDragStart"),
57                                dojo.subscribe("/dnd/drop/before", this, "onDrop"),
58                                dojo.subscribe("/dnd/cancel",this,"onDropCancel"),
59                                dojo.subscribe("/dnd/source/over",this,"onDndSource")
60                        ]
61                },
62       
63                unsubscribeDnd: function(){
64                        // summary:
65                        //              Unsubscribe to some topics of dojo drag and drop.
66       
67                        //console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd");
68                        dojo.forEach(this._subscribeHandler, dojo.unsubscribe);
69                },
70       
71                _getHoverArea: function(/*Object*/ coords){
72                        // summary:
73                        //              Get a D&D dojoX area as a DOM node positioned under a specific point.
74                        // coords:
75                        //              Object containing the coordinates x and y (mouse position)
76                        // tags:
77                        //              protected
78       
79                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea");
80                        var x = coords.x;
81                        var y = coords.y;
82                        this._oldArea = this._currentArea;
83                        this._currentArea = null;
84                        var areas = this._areaManager._areaList;
85                        for(var i = 0; i < areas.length; i++){
86                                var area = areas[i];
87                                var startX = area.coords.x;
88                                var endX = startX + area.node.offsetWidth;
89                                var startY = area.coords.y;
90                                var endY = startY + area.node.offsetHeight;
91                                // check if the coordinates mouse is in a D&D Area
92                                if(startX <= x && x <= endX && startY <= y && y <= endY){
93                                        this._areaManager._oldIndexArea = this._areaManager._currentIndexArea;
94                                        this._areaManager._currentIndexArea = i;
95                                        this._currentArea = area.node;
96                                        break;
97                                }
98                        }
99                        if(this._currentArea != this._oldArea){
100                                if(this._currentArea == null){
101                                        // case when the dragNode was in a D&D area but it's out now.
102                                        this.onDragExit();
103                                }
104                                else if(this._oldArea == null){
105                                        // case when the dragNode was out a D&D area but it's in now.
106                                        this.onDragEnter();
107                                }
108                                else{
109                                        // case when the dragNode was in a D&D area and enter in an other D&D area directly.
110                                        this.onDragExit();
111                                        this.onDragEnter();
112                                }
113                        }
114       
115                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: _getHoverArea",this._dojoManager.avatar.node,this._currentArea,this._oldArea);
116                },
117       
118                onDragStart: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
119                        // summary:
120                        //              Occurs when the "/dnd/start" topic is published.
121                        // source:
122                        //              the source which provides items
123                        // nodes:
124                        //              the list of transferred items
125                        // copy:
126                        //              copy items, if true, move items otherwise
127                        // tags:
128                        //              callback
129       
130                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragStart");
131                        // catch the dragNode to get the type when it's necessary.
132                        this._dragNode = nodes[0];
133                        this._copy = copy; this._source = source;
134                        // Connect the onMouseMove :
135                        // It's usefull to activate the detection of a D&D area and the dropIndicator place only if
136                        // the dragNode is out of a the source dojo. The classic behaviour of the dojo source is kept.
137                        this._outSourceHandler = dojo.connect(this._dojoManager, "outSource", this, function(){
138                                //dojo.disconnect(this._outSourceHandler);
139                                if(this._moveHandler == null){
140                                        this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
141                                }
142                        });
143                },
144       
145                onMouseMove: function(/*DOMEvent*/e){
146                        // summary:
147                        //              Occurs when the user moves the mouse.
148                        // e:
149                        //              the DOM event
150                        // tags:
151                        //              callback
152       
153                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onMouseMove");
154                        // calculate the coordonates of the mouse.
155                        var coords = {
156                                'x': e.pageX,
157                                'y': e.pageY
158                        };
159                        this._getHoverArea(coords);
160                        // if a D&D area has been found and if it's accepted to drop this type of dragged node
161                        if(this._currentArea && this._areaManager._accept){
162                                // specific case : a dropIndicator can be hidden (see onDndSource method)
163                                if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
164                                        this._areaManager._dropIndicator.node.style.visibility = "";
165                                        dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
166                                }
167                                // place the dropIndicator in D&D Area with a default size.
168                                this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize);
169                        }
170                },
171       
172                onDragEnter: function(){
173                        // summary:
174                        //              Occurs when the user drages an DOJO dnd item inside a D&D dojoX area.
175                        // tags:
176                        //              callback
177       
178                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragEnter");
179                        // Check if the type of dragged node is accepted in the selected D&D dojoX Area.
180                        var _dndType = this._dragNode.getAttribute("dndType");
181                        // need to have an array as type
182                        var type = (_dndType) ? _dndType.split(/\s*,\s*/) : ["text"];
183                        this._areaManager._isAccepted(type, this._areaManager._areaList[this._areaManager._currentIndexArea].accept);
184                        // if the D&D dojoX Area accepts the drop, change the color of Avatar.
185                        if(this._dojoManager.avatar){
186                                if(this._areaManager._accept){
187                                        dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
188                                }
189                                else{
190                                        dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
191                                }
192                        }
193                },
194       
195                onDragExit: function(){
196                        // summary:
197                        //              Occurs when the user leaves a D&D dojoX area after dragging an DOJO dnd item over it.
198       
199                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDragExit");
200                        // if the dragged node exits of a D&D dojoX Area :
201                        this._areaManager._accept = false;
202                        // change color of avatar
203                        if(this._dojoManager.avatar){
204                                dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
205                        }
206                        // reset all variables and remove the dropIndicator.
207                        if(this._currentArea == null){
208                                this._areaManager._dropMode.refreshItems(this._areaManager._areaList[this._areaManager._oldIndexArea], this._areaManager._oldDropIndex, this.dropIndicatorSize, false);
209                                this._areaManager._resetAfterDrop();
210                        }
211                        else{
212                                this._areaManager._dropIndicator.remove();
213                        }
214                },
215       
216                isAccepted: function(/*Node*/node, /*Object*/accept){
217                        // summary:
218                        //              Check if a dragNode is accepted into a dojo target.
219                        // node:
220                        //              The dragged node.
221                        // accept:
222                        //              Object containing the type accepted for a target dojo.
223                        // returns:
224                        //              true if the dragged node is accepted in the target dojo.
225       
226                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: isAccepted");
227                        var type = (node.getAttribute("dndType")) ? node.getAttribute("dndType") : "text";
228                        if(type && type in accept)
229                                return true;    // Boolean
230                        else
231                                return false;   // Boolean
232                },
233       
234                onDndSource: function(/*Object*/ source){
235                        // summary:
236                        //              Called when the mouse enters or exits of a source dojo.
237                        // source:
238                        //              the dojo source/target
239                        // tags:
240                        //              callback
241       
242                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDndSource",source);
243                        // Only the case : "source dojo into a D&D dojoX Area" is treated.
244                        if(this._currentArea == null){
245                                return;
246                        }
247                        if(source){
248                                // Enter in a source/target dojo.
249                                // test if the type of draggedNode is accepted :
250                                var accept = false;
251                                if(this._dojoManager.target == source){
252                                        accept = true;
253                                }
254                                else{
255                                        accept = this.isAccepted(this._dragNode, source.accept);
256                                }
257                                if(accept){
258                                        // disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area.
259                                        dojo.disconnect(this._moveHandler);
260                                        this._currentArea = this._moveHandler = null;
261                                        // hidden the visibility of dojoX dropIndicator to prevent an offset when the dropIndicator disappears.
262                                        // test if drop indicator is visible before applaying hidden style.
263                                        var dropIndicator = this._areaManager._dropIndicator.node;
264                                        if(dropIndicator && dropIndicator.parentNode !== null && dropIndicator.parentNode.nodeType == 1)
265                                                dropIndicator.style.visibility = "hidden";
266                                }
267                                else{
268                                        // if the type of dragged node is not accepted in the target dojo, the color of avatar
269                                        // have to be the same that the color of D&D dojoX Area acceptance.
270                                        this._resetAvatar();
271                                }
272                        }
273                        else{
274                                // Exit of a source/target dojo.
275                                // reconnect the onMouseMove to enabled the search of a drop zone in the D&D dojox Area.
276                                if(!this._moveHandler)
277                                        this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
278       
279                                this._resetAvatar();
280                        }
281                },
282       
283                _resetAvatar: function(){
284                        // summary:
285                        //              Function executed in onDndSource function to set the avatar
286                        //              acceptance according to the dojox DnD AreaManager Acceptance.
287                        //              It is used when The mouse exit a source/target dojo or if the
288                        //              dragged node is not accepted in dojo source / target.
289                        // tags:
290                        //              protected
291       
292                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar");
293                        if(this._dojoManager.avatar){
294                                if(this._areaManager._accept){
295                                        dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
296                                }
297                                else{
298                                        dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
299                                }
300                        }
301                },
302       
303                onDropCancel: function(){
304                        // summary:
305                        //              Occurs when the "/dnd/cancel" topic is published.
306                        // tags:
307                        //              callback
308       
309                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDropCancel");
310                        if(this._currentArea == null){
311                                // the dragged node is not in the D&D dojox Area => Cancel
312                                this._areaManager._resetAfterDrop();
313                                dojo.disconnect(this._moveHandler);
314                                dojo.disconnect(this._outSourceHandler);
315                                this._currentArea = this._moveHandler = this._outSourceHandler = null;
316                        }
317                        else{
318                                // the dragged node is in the D&D dojox Area
319                                //              (catch when dragged node exits of a source/target dojo and stays in the same D&D dojox Area)
320                                // dojo cancel the drop but it's authorized in the D&D Area
321                                if(this._areaManager._accept){
322                                        this.onDrop(this._source, [this._dragNode], this._copy, this._currentArea);
323                                }
324                                else{
325                                        this._currentArea = null;
326                                        dojo.disconnect(this._outSourceHandler);
327                                        dojo.disconnect(this._moveHandler);
328                                        this._moveHandler = this._outSourceHandler = null;
329                                }
330                        }
331                },
332       
333                onDrop: function(/*Object*/source, /*Array*/nodes, /*Boolean*/copy){
334                        // summary:
335                        //              Occurs when the user leaves a D&D dojox area after dragging an DOJO dnd item over it.
336                        // source:
337                        //              the source which provides items
338                        // nodes:
339                        //              the list of transferred items
340                        // copy:
341                        //              copy items, if true, move items otherwise
342                        // tags:
343                        //              callback
344       
345                        //console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea);
346                        dojo.disconnect(this._moveHandler);
347                        dojo.disconnect(this._outSourceHandler);
348                        this._moveHandler = this._outSourceHandler = null;
349                        if(this._currentArea){
350                                var dropIndex = this._areaManager._currentDropIndex;
351                                dojo.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]);
352                                this._currentArea = null;
353                        }
354                        if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
355                                this._areaManager._dropIndicator.node.style.visibility = "";
356                        }
357                        this._areaManager._resetAfterDrop();
358                }
359        });
360       
361        dojox.mdnd.adapter._dndFromDojo = null;
362        dojox.mdnd.adapter._dndFromDojo = new dojox.mdnd.adapter.DndFromDojo();
363        return dfd;
364});
Note: See TracBrowser for help on using the repository browser.