source: Dev/trunk/src/client/dojox/mdnd/dropMode/DefaultDropMode.js @ 483

Last change on this file since 483 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 8.9 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/declare",
4        "dojo/_base/array",
5        "dojo/dom-geometry",
6        "dojox/mdnd/AreaManager"
7],function(dojo, declare, array, geom){
8        var ddm = declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
9                // summary:
10                //              Enabled a type of calcul for Dnd.
11                //              Default class to find the nearest target.
12       
13                // _oldXPoint: Integer
14                //              used to save a X position
15                _oldXPoint: null,
16       
17                // _oldYPoint: Integer
18                //              used to save a Y position
19                _oldYPoint: null,
20       
21                // _oldBehaviour: String
22                //              see `getDragPoint`
23                _oldBehaviour: "up",
24       
25                addArea: function(/*Array*/areas, /*Object*/object){
26                        // summary:
27                        //              Add a DnD Area into an array sorting by the x position.
28                        // areas:
29                        //              array of areas
30                        // object:
31                        //              data type of a DndArea
32                        // returns:
33                        //              a sorted area
34       
35                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: addArea");
36                        var length =  areas.length;
37                        var position = geom.position(object.node, true);
38                        object.coords = {'x':position.x, 'y':position.y};
39                        if (length == 0) {
40                                areas.push(object);
41                        }else{
42                                var x =  object.coords.x;
43                                for (var i = 0; i < length; i++) {
44                                        if (x < areas[i].coords.x) {
45                                                for (var j = length-1; j >= i; j--)
46                                                        areas[j + 1] = areas[j];
47                                                areas[i] = object;
48                                                break;
49                                        }
50                                }
51                                if (i == length)
52                                        areas.push(object);
53                        }
54                        return areas;   // Array
55                },
56       
57                updateAreas: function(/*Array*/areaList){
58                        // summary:
59                        //              Refresh intervals between areas to determinate the nearest area to drop an item.
60                        //              Algorithm :
61                        //              the marker should be the vertical line passing by the
62                        //              central point between two contiguous areas.
63                        //              Note:
64                        //              If the page has only one targetArea, it's not necessary to calculate coords.
65                        // areaList:
66                        //              array of areas
67       
68                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initAreas");
69                        var length = areaList.length;
70                        if (length > 1){
71                                var currentRight, nextLeft;
72                                for (var i = 0; i < length; i++) {
73                                        var area = areaList[i];
74                                        var nextArea;
75                                        area.coords.x1 = -1;
76                                        area.coords.x2 = -1;
77                                        if (i == 0) {
78                                                nextArea = areaList[i+1];
79                                                this._updateArea(area);
80                                                this._updateArea(nextArea);
81                                                currentRight = area.coords.x + area.node.offsetWidth;
82                                                nextLeft =  nextArea.coords.x;
83                                                area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
84                                        }
85                                        else if (i == length-1) {
86                                                area.coords.x1 = areaList[i-1].coords.x2;
87                                        }else{
88                                                nextArea = areaList[i+1];
89                                                this._updateArea(nextArea);
90                                                currentRight = area.coords.x + area.node.offsetWidth;
91                                                nextLeft =  nextArea.coords.x;
92                                                area.coords.x1 = areaList[i-1].coords.x2;
93                                                area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
94                                        }
95                                }
96                        }
97                },
98       
99                _updateArea : function(/*Object*/area){
100                        // summary:
101                        //              update the DnD area object (i.e. update coordinates of its DOM node)
102                        // area:
103                        //              the DnD area
104                        // tags:
105                        //              protected
106       
107                        //console.log("dojox.mdnd.dropMode.DefaultDropMode  ::: _updateArea");
108                        var position = geom.position(area.node, true);
109                        area.coords.x = position.x;
110                        area.coords.y = position.y;
111                },
112       
113                initItems: function(/*Object*/area){
114                        // summary:
115                        //              initialize the horizontal line in order to determinate the drop zone.
116                        // area:
117                        //              the DnD area
118       
119                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initItems");
120                        array.forEach(area.items, function(obj){
121                                //get the vertical middle of the item
122                                var node = obj.item.node;
123                                var position = geom.position(node, true);
124                                var y = position.y + position.h/2;
125                                obj.y = y;
126                        });
127                        area.initItems = true;
128                },
129       
130                refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){
131                        // summary:
132                        //              take into account the drop indicator DOM element in order to compute horizontal lines
133                        // area:
134                        //              a DnD area object
135                        // indexItem:
136                        //              index of a draggable item
137                        // size:
138                        //              dropIndicator size
139                        // added:
140                        //              boolean to know if a dropIndicator has been added or deleted
141       
142                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: refreshItems");
143                        if (indexItem == -1) {
144                                return;
145                        }else if(area && size && size.h){
146                                var height = size.h;
147                                if (area.margin){
148                                        height += area.margin.t;
149                                }
150                                var length = area.items.length;
151                                for (var i=indexItem; i<length; i++){
152                                        var item = area.items[i];
153                                        if (added) {
154                                                item.y += height;
155                                        }else{
156                                                item.y -= height;
157                                        }
158                                }
159                        }
160                },
161       
162                getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
163                        // summary:
164                        //              return coordinates of the draggable item
165                        // description:
166                        //              return for:
167                        //
168                        //              - X point : the middle
169                        //              - Y point : search if the user goes up or goes down with his mouse.
170                        //              - Up : top of the draggable item
171                        //              - Down : bottom of the draggable item
172                        // coords:
173                        //              an object encapsulating X and Y position
174                        // size:
175                        //              an object encapsulating width and height values
176                        // mousePosition:
177                        //              coordinates of mouse
178                        // returns:
179                        //              an object of coordinates
180                        //              example : {'x':10,'y':10}
181       
182                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDragPoint");
183                        var y = coords.y;
184                        if (this._oldYPoint){
185                                if (y > this._oldYPoint) {
186                                        this._oldBehaviour = "down";
187                                        y += size.h;
188                                }
189                                else
190                                        if (y <= this._oldYPoint) {
191                                                this._oldBehaviour = "up";
192                                        }
193                        }
194                        this._oldYPoint = y;
195                        return {
196                                'x': coords.x + (size.w / 2),
197                                'y': y
198                                };      // Object
199                },
200       
201                getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
202                        // summary:
203                        //              get the nearest DnD area.
204                        //              Coordinates are basically provided by the ``getDragPoint`` method.
205                        // areaList:
206                        //              a list of DnD areas objects
207                        // coords:
208                        //              coordinates [x,y] of the dragItem
209                        // currentIndexArea:
210                        //              an index representing the active DnD area
211                        // returns:
212                        //              the index of the DnD area
213       
214                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getTargetArea");
215                        var index = 0;
216                        var x = coords.x;
217                        var end = areaList.length;
218                        if (end > 1) {
219                                var start = 0, direction = "right", compute = false;
220                                if (currentIndexArea == -1 || arguments.length<3) {
221                                        // first time : Need to search the nearest area in all areas.
222                                        compute = true;
223                                }
224                                else {
225                                        // check if it's always the same area
226                                        if (this._checkInterval(areaList, currentIndexArea, x)){
227                                                index = currentIndexArea;
228                                        }else{
229                                                if (this._oldXPoint < x){
230                                                        start = currentIndexArea + 1;
231                                                }else{
232                                                        start = currentIndexArea - 1;
233                                                        end = 0;
234                                                        direction = "left";
235                                                }
236                                                compute = true;
237                                        }
238                                }
239                                if (compute) {
240                                        if (direction === "right") {
241                                                for (var i = start; i < end; i++) {
242                                                        if (this._checkInterval(areaList, i, x)) {
243                                                                index = i;
244                                                                break;
245                                                        }
246                                                }
247                                        }else{
248                                                for (var i = start; i >= end; i--) {
249                                                        if (this._checkInterval(areaList, i, x)) {
250                                                                index = i;
251                                                                break;
252                                                        }
253                                                }
254                                        }
255                                }
256                        }
257                        this._oldXPoint = x;
258                        return index;   // Integer
259                },
260       
261                _checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x){
262                        // summary:
263                        //              check if the dragNode is in the interval.
264                        //              The x coordinate is basically provided by the ``getDragPoint`` method.
265                        // areaList:
266                        //              a list of DnD areas objects
267                        // index:
268                        //              index of a DnD area (to get the interval)
269                        // x:
270                        //              coordinate x, of the dragNode
271                        // returns:
272                        //              true if the dragNode is in interval
273                        // tags:
274                        //              protected
275       
276                        var coords = areaList[index].coords;
277                        if (coords.x1 == -1) {
278                                if (x <= coords.x2) {
279                                        return true;
280                                }
281                        }
282                        else
283                                if (coords.x2 == -1) {
284                                        if (x > coords.x1) {
285                                                return true;
286                                        }
287                                }
288                                else {
289                                        if (coords.x1 < x && x <= coords.x2) {
290                                                return true;
291                                        }
292                                }
293                        return false;   // Boolean
294                },
295       
296                getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
297                        // summary:
298                        //              Return the index where the drop has to be placed.
299                        // targetArea:
300                        //              a DnD area object
301                        // coords:
302                        //              coordinates [x,y] of the draggable item
303                        // returns:
304                        //              a number
305                        //              or -1 if the area has no children or the drop index represents the last position in to the area
306       
307                        //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDropIndex");
308                        var length = targetArea.items.length;
309                        var coordinates = targetArea.coords;
310                        var y = coords.y;
311                        if (length > 0) {
312                                // course all children in the target area.
313                                for (var i = 0; i < length; i++) {
314                                        // compare y value with y value of children
315                                        if (y < targetArea.items[i].y) {
316                                                return i;       // Integer
317                                        }
318                                        else {
319                                                if (i == length-1) {
320                                                        return -1;
321                                                }
322                                        }
323                                }
324                        }
325                        return -1;
326                },
327       
328                destroy: function(){
329                        //      can be overwritten.
330                }
331        });
332       
333        //------------
334        //Singleton
335        //------------
336        dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.DefaultDropMode();
337        return ddm;
338});
Note: See TracBrowser for help on using the repository browser.