/* 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.Box = OpenLayers.Class(OpenLayers.Handler, { /** * Property: dragHandler * {} */ 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 - {} * 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" });