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