diff options
Diffstat (limited to 'js/dojo/dojox/mdnd/dropMode/DefaultDropMode.js')
| -rw-r--r-- | js/dojo/dojox/mdnd/dropMode/DefaultDropMode.js | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/js/dojo/dojox/mdnd/dropMode/DefaultDropMode.js b/js/dojo/dojox/mdnd/dropMode/DefaultDropMode.js new file mode 100644 index 0000000..05d08db --- /dev/null +++ b/js/dojo/dojox/mdnd/dropMode/DefaultDropMode.js @@ -0,0 +1,338 @@ +//>>built +define("dojox/mdnd/dropMode/DefaultDropMode", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/html", + "dojox/mdnd/AreaManager" +],function(dojo){ + var ddm = dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, { + // summary: + // Enabled a type of calcul for Dnd. + // Default class to find the nearest target. + + // _oldXPoint: Integer + // used to save a X position + _oldXPoint: null, + + // _oldYPoint: Integer + // used to save a Y position + _oldYPoint: null, + + // _oldBehaviour: String + // see <getDragPoint> + _oldBehaviour: "up", + + addArea: function(/*Array*/areas, /*Object*/object){ + // summary: + // Add a DnD Area into an array sorting by the x position. + // areas: + // array of areas + // object: + // data type of a DndArea + // returns: + // a sorted area + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: addArea"); + var length = areas.length; + var position = dojo.position(object.node, true); + object.coords = {'x':position.x, 'y':position.y}; + if (length == 0) { + areas.push(object); + }else{ + var x = object.coords.x; + for (var i = 0; i < length; i++) { + if (x < areas[i].coords.x) { + for (var j = length-1; j >= i; j--) + areas[j + 1] = areas[j]; + areas[i] = object; + break; + } + } + if (i == length) + areas.push(object); + } + return areas; // Array + }, + + updateAreas: function(/*Array*/areaList){ + // summary: + // Refresh intervals between areas to determinate the nearest area to drop an item. + // Algorithm : + // the marker should be the vertical line passing by the + // central point between two contiguous areas. + // Note: + // If the page has only one targetArea, it's not necessary to calculate coords. + // areaList: + // array of areas + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initAreas"); + var length = areaList.length; + if (length > 1){ + var currentRight, nextLeft; + for (var i = 0; i < length; i++) { + var area = areaList[i]; + var nextArea; + area.coords.x1 = -1; + area.coords.x2 = -1; + if (i == 0) { + nextArea = areaList[i+1]; + this._updateArea(area); + this._updateArea(nextArea); + currentRight = area.coords.x + area.node.offsetWidth; + nextLeft = nextArea.coords.x; + area.coords.x2 = currentRight + (nextLeft-currentRight)/2; + } + else if (i == length-1) { + area.coords.x1 = areaList[i-1].coords.x2; + }else{ + nextArea = areaList[i+1]; + this._updateArea(nextArea); + currentRight = area.coords.x + area.node.offsetWidth; + nextLeft = nextArea.coords.x; + area.coords.x1 = areaList[i-1].coords.x2; + area.coords.x2 = currentRight + (nextLeft-currentRight)/2; + } + } + } + }, + + _updateArea : function(/*Object*/area){ + // summary: + // update the DnD area object (i.e. update coordinates of its DOM node) + // area: + // the DnD area + // tags: + // protected + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: _updateArea"); + var position = dojo.position(area.node, true); + area.coords.x = position.x; + area.coords.y = position.y; + }, + + initItems: function(/*Object*/area){ + // summary: + // initialize the horizontal line in order to determinate the drop zone. + // area: + // the DnD area + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initItems"); + dojo.forEach(area.items, function(obj){ + //get the vertical middle of the item + var node = obj.item.node; + var position = dojo.position(node, true); + var y = position.y + position.h/2; + obj.y = y; + }); + area.initItems = true; + }, + + refreshItems: function(/*Object*/area, /*Integer*/indexItem, /*Object*/size, /*Boolean*/added){ + // summary: + // take into account the drop indicator DOM element in order to compute horizontal lines + // area: + // a DnD area object + // indexItem: + // index of a draggable item + // size: + // dropIndicator size + // added: + // boolean to know if a dropIndicator has been added or deleted + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: refreshItems"); + if (indexItem == -1) { + return; + }else if(area && size && size.h){ + var height = size.h; + if (area.margin){ + height += area.margin.t; + } + var length = area.items.length; + for (var i=indexItem; i<length; i++){ + var item = area.items[i]; + if (added) { + item.y += height; + }else{ + item.y -= height; + } + } + } + }, + + getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){ + // summary: + // return coordinates of the draggable item + // description: + // return for: + // - X point : the middle + // - Y point : search if the user goes up or goes down with his mouse. + // - Up : top of the draggable item + // - Down : bottom of the draggable item + // coords: + // an object encapsulating X and Y position + // size: + // an object encapsulating width and height values + // mousePosition: + // coordinates of mouse + // returns: + // an object of coordinates + // example : {'x':10,'y':10} + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDragPoint"); + var y = coords.y; + if (this._oldYPoint){ + if (y > this._oldYPoint) { + this._oldBehaviour = "down"; + y += size.h; + } + else + if (y <= this._oldYPoint) { + this._oldBehaviour = "up"; + } + } + this._oldYPoint = y; + return { + 'x': coords.x + (size.w / 2), + 'y': y + }; // Object + }, + + getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){ + // summary: + // get the nearest DnD area. + // Coordinates are basically provided by the <getDragPoint> method. + // areaList: + // a list of DnD areas objects + // coords: + // coordinates [x,y] of the dragItem + // currentIndexArea: + // an index representing the active DnD area + // returns: + // the index of the DnD area + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getTargetArea"); + var index = 0; + var x = coords.x; + var end = areaList.length; + if (end > 1) { + var start = 0, direction = "right", compute = false; + if (currentIndexArea == -1 || arguments.length<3) { + // first time : Need to search the nearest area in all areas. + compute = true; + } + else { + // check if it's always the same area + if (this._checkInterval(areaList, currentIndexArea, x)){ + index = currentIndexArea; + }else{ + if (this._oldXPoint < x){ + start = currentIndexArea + 1; + }else{ + start = currentIndexArea - 1; + end = 0; + direction = "left"; + } + compute = true; + } + } + if (compute) { + if (direction === "right") { + for (var i = start; i < end; i++) { + if (this._checkInterval(areaList, i, x)) { + index = i; + break; + } + } + }else{ + for (var i = start; i >= end; i--) { + if (this._checkInterval(areaList, i, x)) { + index = i; + break; + } + } + } + } + } + this._oldXPoint = x; + return index; // Integer + }, + + _checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x){ + // summary: + // check if the dragNode is in the interval. + // The x coordinate is basically provided by the <getDragPoint> method. + // areaList: + // a list of DnD areas objects + // index: + // index of a DnD area (to get the interval) + // x: + // coordinate x, of the dragNode + // returns: + // true if the dragNode is in intervall + // tags: + // protected + + var coords = areaList[index].coords; + if (coords.x1 == -1) { + if (x <= coords.x2) { + return true; + } + } + else + if (coords.x2 == -1) { + if (x > coords.x1) { + return true; + } + } + else { + if (coords.x1 < x && x <= coords.x2) { + return true; + } + } + return false; // Boolean + }, + + getDropIndex: function(/*Object*/ targetArea, /*Object*/ coords){ + // summary: + // Return the index where the drop has to be placed. + // targetArea: + // a DnD area object + // coords: + // coordinates [x,y] of the draggable item + // returns: + // a number + // or -1 if the area has no children or the drop index represents the last position in to the area + + //console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDropIndex"); + var length = targetArea.items.length; + var coordinates = targetArea.coords; + var y = coords.y; + if (length > 0) { + // course all children in the target area. + for (var i = 0; i < length; i++) { + // compare y value with y value of children + if (y < targetArea.items[i].y) { + return i; // Integer + } + else { + if (i == length-1) { + return -1; + } + } + } + } + return -1; + }, + + destroy: function(){ + // can be overwritten. + } + }); + + //------------ + //Singleton + //------------ + dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.DefaultDropMode(); + return ddm; +}); |
