245 lines
7.5 KiB
JavaScript
245 lines
7.5 KiB
JavaScript
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
|
|
* full list of contributors). Published under the 2-clause BSD license.
|
|
* See license.txt in the OpenLayers distribution or repository 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: boxOffsets
|
|
* {Object} Caches box offsets from css. This is used by the getBoxOffsets
|
|
* method.
|
|
*/
|
|
boxOffsets: null,
|
|
|
|
/**
|
|
* Constructor: OpenLayers.Handler.Box
|
|
*
|
|
* Parameters:
|
|
* control - {<OpenLayers.Control>}
|
|
* callbacks - {Object} An object with a properties whose values are
|
|
* functions. Various callbacks described below.
|
|
* options - {Object}
|
|
*
|
|
* Named callbacks:
|
|
* start - Called when the box drag operation starts.
|
|
* done - Called when the box drag operation is finished.
|
|
* The callback should expect to receive a single argument, the box
|
|
* bounds or a pixel. If the box dragging didn't span more than a 5
|
|
* pixel distance, a pixel will be returned instead of a bounds object.
|
|
*/
|
|
initialize: function(control, callbacks, options) {
|
|
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
|
|
this.dragHandler = new OpenLayers.Handler.Drag(
|
|
this,
|
|
{
|
|
down: this.startBox,
|
|
move: this.moveBox,
|
|
out: this.removeBox,
|
|
up: this.endBox
|
|
},
|
|
{keyMask: this.keyMask}
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Method: destroy
|
|
*/
|
|
destroy: function() {
|
|
OpenLayers.Handler.prototype.destroy.apply(this, arguments);
|
|
if (this.dragHandler) {
|
|
this.dragHandler.destroy();
|
|
this.dragHandler = null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Method: setMap
|
|
*/
|
|
setMap: function (map) {
|
|
OpenLayers.Handler.prototype.setMap.apply(this, arguments);
|
|
if (this.dragHandler) {
|
|
this.dragHandler.setMap(map);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Method: startBox
|
|
*
|
|
* Parameters:
|
|
* xy - {<OpenLayers.Pixel>}
|
|
*/
|
|
startBox: function (xy) {
|
|
this.callback("start", []);
|
|
this.zoomBox = OpenLayers.Util.createDiv('zoomBox', {
|
|
x: -9999, y: -9999
|
|
});
|
|
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);
|
|
|
|
var offset = this.getBoxOffsets();
|
|
this.zoomBox.style.width = (deltaX + offset.width + 1) + "px";
|
|
this.zoomBox.style.height = (deltaY + offset.height + 1) + "px";
|
|
this.zoomBox.style.left = (xy.x < startX ?
|
|
startX - deltaX - offset.left : startX - offset.left) + "px";
|
|
this.zoomBox.style.top = (xy.y < startY ?
|
|
startY - deltaY - offset.top : startY - offset.top) + "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.boxOffsets = 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)) {
|
|
if (this.dragHandler.deactivate()) {
|
|
if (this.zoomBox) {
|
|
this.removeBox();
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Method: getBoxOffsets
|
|
* Determines border offsets for a box, according to the box model.
|
|
*
|
|
* Returns:
|
|
* {Object} an object with the following offsets:
|
|
* - left
|
|
* - right
|
|
* - top
|
|
* - bottom
|
|
* - width
|
|
* - height
|
|
*/
|
|
getBoxOffsets: function() {
|
|
if (!this.boxOffsets) {
|
|
// Determine the box model. If the testDiv's clientWidth is 3, then
|
|
// the borders are outside and we are dealing with the w3c box
|
|
// model. Otherwise, the browser uses the traditional box model and
|
|
// the borders are inside the box bounds, leaving us with a
|
|
// clientWidth of 1.
|
|
var testDiv = document.createElement("div");
|
|
//testDiv.style.visibility = "hidden";
|
|
testDiv.style.position = "absolute";
|
|
testDiv.style.border = "1px solid black";
|
|
testDiv.style.width = "3px";
|
|
document.body.appendChild(testDiv);
|
|
var w3cBoxModel = testDiv.clientWidth == 3;
|
|
document.body.removeChild(testDiv);
|
|
|
|
var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
|
|
"border-left-width"));
|
|
var right = parseInt(OpenLayers.Element.getStyle(
|
|
this.zoomBox, "border-right-width"));
|
|
var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
|
|
"border-top-width"));
|
|
var bottom = parseInt(OpenLayers.Element.getStyle(
|
|
this.zoomBox, "border-bottom-width"));
|
|
this.boxOffsets = {
|
|
left: left,
|
|
right: right,
|
|
top: top,
|
|
bottom: bottom,
|
|
width: w3cBoxModel === false ? left + right : 0,
|
|
height: w3cBoxModel === false ? top + bottom : 0
|
|
};
|
|
}
|
|
return this.boxOffsets;
|
|
},
|
|
|
|
CLASS_NAME: "OpenLayers.Handler.Box"
|
|
});
|