source: Dev/trunk/src/client/dojox/mdnd/dropMode/VerticalDropMode.js @ 529

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