/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Handler.js
* @requires OpenLayers/Handler/Drag.js
*/
/**
* Class: OpenLayers.Handler.Box
* Handler for dragging a rectangle across the map. Box is displayed
* on mouse down, moves on mouse move, and is finished on mouse up.
*
* Inherits from:
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {
/**
* Property: dragHandler
* {<OpenLayers.Handler.Drag>}
*/
dragHandler: null,
/**
* APIProperty: boxDivClassName
* {String} The CSS class to use for drawing the box. Default is
* olHandlerBoxZoomBox
*/
boxDivClassName: 'olHandlerBoxZoomBox',
/**
* Property: boxCharacteristics
* {Object} Caches some box characteristics from css. This is used
* by the getBoxCharacteristics method.
*/
boxCharacteristics: null,
/**
* Constructor: OpenLayers.Handler.Box
*
* Parameters:
* control - {<OpenLayers.Control>}
* callbacks - {Object} An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
* options - {Object}
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
var callbacks = {
"down": this.startBox,
"move": this.moveBox,
"out": this.removeBox,
"up": this.endBox
};
this.dragHandler = new OpenLayers.Handler.Drag(
this, callbacks, {keyMask: this.keyMask});
},
/**
* Method: destroy
*/
destroy: function() {
if (this.dragHandler) {
this.dragHandler.destroy();
this.dragHandler = null;
}
OpenLayers.Handler.prototype.destroy.apply(this, arguments);
},
/**
* Method: setMap
*/
setMap: function (map) {
OpenLayers.Handler.prototype.setMap.apply(this, arguments);
if (this.dragHandler) {
this.dragHandler.setMap(map);
}
},
/**
* Method: startBox
*
* Parameters:
* evt - {Event}
*/
startBox: function (xy) {
this.zoomBox = OpenLayers.Util.createDiv('zoomBox',
this.dragHandler.start);
this.zoomBox.className = this.boxDivClassName;
this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
this.map.viewPortDiv.appendChild(this.zoomBox);
OpenLayers.Element.addClass(
this.map.viewPortDiv, "olDrawBox"
);
},
/**
* Method: moveBox
*/
moveBox: function (xy) {
var startX = this.dragHandler.start.x;
var startY = this.dragHandler.start.y;
var deltaX = Math.abs(startX - xy.x);
var deltaY = Math.abs(startY - xy.y);
this.zoomBox.style.width = Math.max(1, deltaX) + "px";
this.zoomBox.style.height = Math.max(1, deltaY) + "px";
this.zoomBox.style.left = xy.x < startX ? xy.x+"px" : startX+"px";
this.zoomBox.style.top = xy.y < startY ? xy.y+"px" : startY+"px";
// depending on the box model, modify width and height to take borders
// of the box into account
var box = this.getBoxCharacteristics();
if (box.newBoxModel) {
if (xy.x > startX) {
this.zoomBox.style.width =
Math.max(1, deltaX - box.xOffset) + "px";
}
if (xy.y > startY) {
this.zoomBox.style.height =
Math.max(1, deltaY - box.yOffset) + "px";
}
}
},
/**
* Method: endBox
*/
endBox: function(end) {
var result;
if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||
Math.abs(this.dragHandler.start.y - end.y) > 5) {
var start = this.dragHandler.start;
var top = Math.min(start.y, end.y);
var bottom = Math.max(start.y, end.y);
var left = Math.min(start.x, end.x);
var right = Math.max(start.x, end.x);
result = new OpenLayers.Bounds(left, bottom, right, top);
} else {
result = this.dragHandler.start.clone(); // i.e. OL.Pixel
}
this.removeBox();
this.callback("done", [result]);
},
/**
* Method: removeBox
* Remove the zoombox from the screen and nullify our reference to it.
*/
removeBox: function() {
this.map.viewPortDiv.removeChild(this.zoomBox);
this.zoomBox = null;
this.boxCharacteristics = null;
OpenLayers.Element.removeClass(
this.map.viewPortDiv, "olDrawBox"
);
},
/**
* Method: activate
*/
activate: function () {
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.dragHandler.activate();
return true;
} else {
return false;
}
},
/**
* Method: deactivate
*/
deactivate: function () {
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
this.dragHandler.deactivate();
return true;
} else {
return false;
}
},
/**
* Method: getCharacteristics
* Determines offset and box model for a box.
*
* Returns:
* {Object} a hash with the following properties:
* - xOffset - Corner offset in x-direction
* - yOffset - Corner offset in y-direction
* - newBoxModel - true for all browsers except IE in quirks mode
*/
getBoxCharacteristics: function() {
if (!this.boxCharacteristics) {
var xOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
"border-left-width")) + parseInt(OpenLayers.Element.getStyle(
this.zoomBox, "border-right-width")) + 1;
var yOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
"border-top-width")) + parseInt(OpenLayers.Element.getStyle(
this.zoomBox, "border-bottom-width")) + 1;
// all browsers use the new box model, except IE in quirks mode
var newBoxModel = OpenLayers.Util.getBrowserName() == "msie" ?
document.compatMode != "BackCompat" : true;
this.boxCharacteristics = {
xOffset: xOffset,
yOffset: yOffset,
newBoxModel: newBoxModel
};
}
return this.boxCharacteristics;
},
CLASS_NAME: "OpenLayers.Handler.Box"
});