source: Dev/branches/rest-dojo-ui/client/dojox/mdnd/dropMode/VerticalDropMode.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: 8.8 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/declare",
4        "dojo/_base/html",
5        "dojo/_base/array",
6        "dojox/mdnd/AreaManager"
7],function(dojo){
8        var vdm = dojo.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 = dojo.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 = dojo.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                        dojo.forEach(area.items, function(obj){
127                                //get the vertical middle of the item
128                                var node = obj.item.node;
129                                var position = dojo.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                        //                      - X point : the middle
176                        //                      - Y point : search if the user goes up or goes down with his mouse.
177                        //                      - Up : top of the draggable item
178                        //                      - Down : bottom of the draggable item
179                        // coords:
180                        //              an object encapsulating X and Y position
181                        // size:
182                        //              an object encapsulating width and height values
183                        // mousePosition:
184                        //              coordinates of mouse
185                        // returns:
186                        //              an object of coordinates
187                        //              example : {'x':10,'y':10}
188       
189                        //console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDragPoint");
190                        var y = coords.y;
191                        if(this._oldYPoint){
192                                if(y > this._oldYPoint){
193                                        this._oldBehaviour = "down";
194                                        y += size.h;
195                                }
196                                else
197                                        if(y <= this._oldYPoint){
198                                                this._oldBehaviour = "up";
199                                        }
200                        }
201                        this._oldYPoint = y;
202                        return {
203                                'x': coords.x + (size.w / 2),
204                                'y': y
205                                };      // Object
206                },
207       
208                getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
209                        // summary:
210                        //              get the nearest DnD area.
211                        //              Coordinates are basically provided by the <getDragPoint> method.
212                        // areaList:
213                        //              a list of DnD areas objects
214                        // coords:
215                        //              coordinates [x,y] of the dragItem
216                        // currentIndexArea:
217                        //              an index representing the active DnD area
218                        // returns:
219                        //              the index of the DnD area
220       
221                        //console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getTargetArea");
222                        var index = 0;
223                        var x = coords.x;
224                        var end = areaList.length;
225                        if(end > 1){
226                                var start = 0, direction = "right", compute = false;
227                                if(currentIndexArea == -1 || arguments.length < 3){
228                                        // first time : Need to search the nearest area in all areas.
229                                        compute = true;
230                                }
231                                else{
232                                        // check if it's always the same area
233                                        if(this._checkInterval(areaList, currentIndexArea, x)){
234                                                index = currentIndexArea;
235                                        }
236                                        else{
237                                                if(this._oldXPoint < x){
238                                                        start = currentIndexArea + 1;
239                                                }
240                                                else{
241                                                        start = currentIndexArea - 1;
242                                                        end = 0;
243                                                        direction = "left";
244                                                }
245                                                compute = true;
246                                        }
247                                }
248                                if(compute){
249                                        if(direction === "right"){
250                                                for(var i = start; i < end; i++){
251                                                        if(this._checkInterval(areaList, i, x)){
252                                                                index = i;
253                                                                break;
254                                                        }
255                                                }
256                                        }
257                                        else{
258                                                for(var i = start; i >= end; i--){
259                                                        if(this._checkInterval(areaList, i, x)){
260                                                                index = i;
261                                                                break;
262                                                        }
263                                                }
264                                        }
265                                }
266                        }
267                        this._oldXPoint = x;
268                        return index;   // Integer
269                },
270       
271                _checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x){
272                        // summary:
273                        //              check if the dragNode is in the interval.
274                        //              The x coordinate is basically provided by the <getDragPoint> method.
275                        // areaList:
276                        //              a list of DnD areas objects
277                        // index:
278                        //              index of a DnD area (to get the interval)
279                        // x:
280                        //              coordinate x, of the dragNode
281                        // returns:
282                        //              true if the dragNode is in intervall
283                        // tags:
284                        //              protected
285                        var coords = areaList[index].coords;
286                        if(coords.x1 == -1){
287                                if(x <= coords.x2){
288                                        return true;
289                                }
290                        }
291                        else
292                                if(coords.x2 == -1){
293                                        if(x > coords.x1){
294                                                return true;
295                                        }
296                                }
297                                else{
298                                        if(coords.x1 < x && x <= coords.x2){
299                                                return true;
300                                        }
301                                }
302                        return false;   // Boolean
303                },
304       
305                getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){
306                        // summary:
307                        //              Return the index where the drop has to be placed.
308                        // targetArea:
309                        //              a DnD area object
310                        // coords:
311                        //              coordinates [x,y] of the draggable item
312                        // returns:
313                        //              a number
314                        //              or -1 if the area has no children or the drop index represents the last position in to the area
315       
316                        //console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDropIndex");
317                        var length = targetArea.items.length;
318                        var coordinates = targetArea.coords;
319                        var y = coords.y;
320                        if(length > 0){
321                                // course all children in the target area.
322                                for(var i = 0; i < length; i++){
323                                        // compare y value with y value of children
324                                        if(y < targetArea.items[i].y){
325                                                return i;       // Integer
326                                        }
327                                        else{
328                                                if(i == length-1){
329                                                        return -1;
330                                                }
331                                        }
332                                }
333                        }
334                        return -1;
335                },
336       
337                destroy: function(){
338                        //      can be overwritten.
339                }
340        });
341       
342        //------------
343        //Singleton
344        //------------
345        dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.VerticalDropMode();
346        return vdm;
347});
Note: See TracBrowser for help on using the repository browser.