diff --git a/examples/overviewmap.html b/examples/overviewmap.html
index ddab54510a..f4fd8c916d 100644
--- a/examples/overviewmap.html
+++ b/examples/overviewmap.html
@@ -86,7 +86,7 @@
map2.addLayers([bos]);
map2.addControl(new OpenLayers.Control.LayerSwitcher());
- // create an overview map control with the default options
+ // create an overview map control with non-default options
var controlOptions = {
mapOptions: mapOptions
}
diff --git a/lib/OpenLayers/Control/OverviewMap.js b/lib/OpenLayers/Control/OverviewMap.js
index e55bd2abc5..3a2a58dc27 100644
--- a/lib/OpenLayers/Control/OverviewMap.js
+++ b/lib/OpenLayers/Control/OverviewMap.js
@@ -19,12 +19,6 @@
*/
OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
- /**
- * Property: id
- * {String} For div.id
- */
- id: "OverviewMap",
-
/**
* Property: element
* {DOMElement} The DOM element that contains the overview map
@@ -36,7 +30,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
* {} A reference to the overvew map itself.
*/
ovmap: null,
-
+
/**
* APIProperty: size
* {} The overvew map size in pixels. Note that this is
@@ -52,6 +46,34 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
* If none are sent at construction, the base layer for the main map is used.
*/
layers: null,
+
+ /**
+ * APIProperty: minRectSize
+ * {Integer} The minimum width or height (in pixels) of the extent
+ * rectangle on the overview map. When the extent rectangle reaches
+ * this size, it will be replaced depending on the value of the
+ * property. Default is 15 pixels.
+ */
+ minRectSize: 15,
+
+ /**
+ * APIProperty: minRectDisplayClass
+ * {String} Replacement style class name for the extent rectangle when
+ * is reached. This string will be suffixed on to the
+ * displayClass. Default is "RectReplacement".
+ *
+ * Example CSS declaration:
+ * (code)
+ * .olControlOverviewMapRectReplacement {
+ * overflow: hidden;
+ * cursor: move;
+ * background-image: url("img/overview_replacement.gif");
+ * background-repeat: no-repeat;
+ * background-position: center;
+ * }
+ * (end)
+ */
+ minRectDisplayClass: "RectReplacement",
/**
* APIProperty: minRatio
@@ -74,6 +96,12 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
* options that the main map was constructed with.
*/
mapOptions: null,
+
+ /**
+ * Property: dragHandler
+ * {} A handler for dragging the extent rectangle.
+ */
+ dragHandler: null,
/**
* Constructor: OpenLayers.Control.OverviewMap
@@ -97,6 +125,9 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
if (!this.mapDiv) { // we've already been destroyed
return;
}
+ this.dragHandler.destroy();
+ this.clickHandler.destroy();
+
this.mapDiv.removeChild(this.extentRectangle);
this.extentRectangle = null;
this.rectEvents.destroy();
@@ -107,13 +138,9 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
this.element.removeChild(this.mapDiv);
this.mapDiv = null;
- this.mapDivEvents.destroy();
- this.mapDivEvents = null;
this.div.removeChild(this.element);
this.element = null;
- this.elementEvents.destroy();
- this.elementEvents = null;
if (this.maximizeDiv) {
OpenLayers.Event.stopObservingElement(this.maximizeDiv);
@@ -165,45 +192,14 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
this.extentRectangle = document.createElement('div');
this.extentRectangle.style.position = 'absolute';
this.extentRectangle.style.zIndex = 1000; //HACK
- this.extentRectangle.style.overflow = 'hidden';
- this.extentRectangle.style.backgroundImage = 'url(' +
- OpenLayers.Util.getImagesLocation() +
- 'blank.gif)';
this.extentRectangle.className = this.displayClass+'ExtentRectangle';
this.mapDiv.appendChild(this.extentRectangle);
-
+
this.element.appendChild(this.mapDiv);
this.div.appendChild(this.element);
this.map.events.register('moveend', this, this.update);
-
- // Set up events. The image div recenters the map on click.
- // The extent rectangle can be dragged to recenter the map.
- // If the mousedown happened elsewhere, then mousemove and mouseup
- // should slip through.
- this.elementEvents = new OpenLayers.Events(this, this.element);
- this.elementEvents.register('mousedown', this, function(e) {
- OpenLayers.Event.stop(e);
- });
- this.elementEvents.register('click', this, function(e) {
- OpenLayers.Event.stop(e);
- });
- this.elementEvents.register('dblclick', this, function(e) {
- OpenLayers.Event.stop(e);
- });
- this.rectEvents = new OpenLayers.Events(this, this.extentRectangle,
- null, true);
- this.rectEvents.register('mouseout', this, this.rectMouseOut);
- this.rectEvents.register('mousedown', this, this.rectMouseDown);
- this.rectEvents.register('mousemove', this, this.rectMouseMove);
- this.rectEvents.register('mouseup', this, this.rectMouseUp);
- this.rectEvents.register('click', this, function(e) {
- OpenLayers.Event.stop(e);
- });
- this.rectEvents.register('dblclick', this, this.rectDblClick );
- this.mapDivEvents = new OpenLayers.Events(this, this.mapDiv);
- this.mapDivEvents.register('click', this, this.mapDivClick);
// Optionally add min/max buttons if the control will go in the
// map viewport.
@@ -276,64 +272,20 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
},
/**
- * Method: rectMouseOut
- * Handle browser events
+ * Method: rectDrag
+ * Handle extent rectangle drag
*
* Parameters:
- * evt - {} evt
+ * px - {} The pixel location of the drag.
*/
- rectMouseOut: function (evt) {
- if(this.rectDragStart != null) {
- if(this.performedRectDrag) {
- this.rectMouseMove(evt);
- var rectPxBounds = this.getRectPxBounds();
- // if we're off of the overview map, update the main map
- // otherwise, keep moving the rect
- if((rectPxBounds.top <= 0) || (rectPxBounds.left <= 0) ||
- (rectPxBounds.bottom >= this.size.h - this.hComp) ||
- (rectPxBounds.right >= this.size.w - this.wComp)) {
- this.updateMapToRect();
- } else {
- return;
- }
- }
- document.onselectstart = null;
- this.rectDragStart = null;
- }
- },
-
- /**
- * Method: rectMouseDown
- * Handle browser events
- *
- * Parameters:
- * evt - {} evt
- */
- rectMouseDown: function (evt) {
- if(!OpenLayers.Event.isLeftClick(evt)) {
- return;
- }
- this.rectDragStart = evt.xy.clone();
- this.performedRectDrag = false;
- OpenLayers.Event.stop(evt);
- },
-
- /**
- * Method: rectMouseMove
- * Handle browser events
- *
- * Parameters:
- * evt - {} evt
- */
- rectMouseMove: function(evt) {
- if(this.rectDragStart != null) {
- var deltaX = this.rectDragStart.x - evt.xy.x;
- var deltaY = this.rectDragStart.y - evt.xy.y;
- var rectPxBounds = this.getRectPxBounds();
- var rectTop = rectPxBounds.top;
- var rectLeft = rectPxBounds.left;
- var rectHeight = Math.abs(rectPxBounds.getHeight());
- var rectWidth = rectPxBounds.getWidth();
+ rectDrag: function(px) {
+ var deltaX = this.dragHandler.last.x - px.x;
+ var deltaY = this.dragHandler.last.y - px.y;
+ if(deltaX != 0 || deltaY != 0) {
+ var rectTop = this.rectPxBounds.top;
+ var rectLeft = this.rectPxBounds.left;
+ var rectHeight = Math.abs(this.rectPxBounds.getHeight());
+ var rectWidth = this.rectPxBounds.getWidth();
// don't allow dragging off of parent element
var newTop = Math.max(0, (rectTop - deltaY));
newTop = Math.min(newTop,
@@ -345,44 +297,9 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
newTop + rectHeight,
newLeft + rectWidth,
newTop));
- this.rectDragStart = evt.xy.clone();
- this.performedRectDrag = true;
- OpenLayers.Event.stop(evt);
}
},
-
- /**
- * Method: rectMouseUp
- * Handle browser events
- *
- * Parameters:
- * evt - {} evt
- */
- rectMouseUp: function(evt) {
- if(!OpenLayers.Event.isLeftClick(evt)) {
- return;
- }
- if(this.performedRectDrag) {
- this.updateMapToRect();
- OpenLayers.Event.stop(evt);
- }
- document.onselectstart = null;
- this.rectDragStart = null;
- },
- /**
- * Method: rectDblClick
- * Handle browser events
- *
- * Parameters:
- * evt - {} evt
- */
- rectDblClick: function(evt) {
- this.performedRectDrag = false;
- OpenLayers.Event.stop(evt);
- this.updateOverview();
- },
-
/**
* Method: mapDivClick
* Handle browser events
@@ -391,14 +308,13 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
* evt - {} evt
*/
mapDivClick: function(evt) {
- var pxBounds = this.getRectPxBounds();
- var pxCenter = pxBounds.getCenterPixel();
+ var pxCenter = this.rectPxBounds.getCenterPixel();
var deltaX = evt.xy.x - pxCenter.x;
var deltaY = evt.xy.y - pxCenter.y;
- var top = pxBounds.top;
- var left = pxBounds.left;
- var height = Math.abs(pxBounds.getHeight());
- var width = pxBounds.getWidth();
+ var top = this.rectPxBounds.top;
+ var left = this.rectPxBounds.left;
+ var height = Math.abs(this.rectPxBounds.getHeight());
+ var width = this.rectPxBounds.getWidth();
var newTop = Math.max(0, (top + deltaY));
newTop = Math.min(newTop, this.ovmap.size.h - height);
var newLeft = Math.max(0, (left + deltaX));
@@ -532,6 +448,40 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
'border-bottom-width'));
this.hComp = (this.hComp) ? this.hComp : 2;
+
+ this.dragHandler = new OpenLayers.Handler.Drag(
+ this, {move: this.rectDrag, done: this.updateMapToRect},
+ {map: this.ovmap}
+ );
+ this.clickHandler = new OpenLayers.Handler.Click(
+ this, {
+ "click": this.mapDivClick
+ },{
+ "single": true, "double": false,
+ "stopSingle": true, "stopDouble": true,
+ "pixelTolerance": 1,
+ map: this.ovmap
+ }
+ );
+ this.clickHandler.activate();
+
+ this.rectEvents = new OpenLayers.Events(this, this.extentRectangle,
+ null, true);
+ this.rectEvents.register("mouseover", this, function(e) {
+ if(!this.dragHandler.active && !this.map.dragging) {
+ // this click handler de/activation can be removed when
+ // ticket #1247 is addressed
+ this.clickHandler.deactivate();
+ this.dragHandler.activate();
+ this.clickHandler.activate();
+ }
+ });
+ this.rectEvents.register("mouseout", this, function(e) {
+ if(!this.dragHandler.dragging) {
+ this.dragHandler.deactivate();
+ }
+ });
+
},
/**
@@ -548,7 +498,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
}
var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent());
if (pxBounds) {
- this.setRectPxBounds(pxBounds);
+ this.setRectPxBounds(pxBounds);
}
},
@@ -557,26 +507,9 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
* Updates the map extent to match the extent rectangle position and size
*/
updateMapToRect: function() {
- var pxBounds = this.getRectPxBounds();
- var lonLatBounds = this.getMapBoundsFromRectBounds(pxBounds);
+ var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds);
this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom);
},
-
- /**
- * Method: getRectPxBounds
- * Get extent rectangle pixel bounds
- *
- * Returns:
- * {} A bounds which is the extent rectangle's pixel
- * bounds (relative to the parent element)
- */
- getRectPxBounds: function() {
- var top = parseInt(this.extentRectangle.style.top);
- var left = parseInt(this.extentRectangle.style.left);
- var height = parseInt(this.extentRectangle.style.height);
- var width = parseInt(this.extentRectangle.style.width);
- return new OpenLayers.Bounds(left, top + height, left + width, top);
- },
/**
* Method: setRectPxBounds
@@ -592,10 +525,29 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
this.ovmap.size.h - this.hComp);
var right = Math.min(pxBounds.left + pxBounds.getWidth(),
this.ovmap.size.w - this.wComp);
- this.extentRectangle.style.top = parseInt(top) + 'px';
- this.extentRectangle.style.left = parseInt(left) + 'px';
- this.extentRectangle.style.height = parseInt(Math.max(bottom - top, 0))+ 'px';
- this.extentRectangle.style.width = parseInt(Math.max(right - left, 0)) + 'px';
+ var width = Math.max(right - left, 0);
+ var height = Math.max(bottom - top, 0);
+ if(width < this.minRectSize || height < this.minRectSize) {
+ this.extentRectangle.className = this.displayClass +
+ this.minRectDisplayClass;
+ var rLeft = left + (width / 2) - (this.minRectSize / 2);
+ var rTop = top + (height / 2) - (this.minRectSize / 2);
+ this.extentRectangle.style.top = Math.round(rTop) + 'px';
+ this.extentRectangle.style.left = Math.round(rLeft) + 'px';
+ this.extentRectangle.style.height = this.minRectSize + 'px';
+ this.extentRectangle.style.width = this.minRectSize + 'px';
+ } else {
+ this.extentRectangle.className = this.displayClass +
+ 'ExtentRectangle';
+ this.extentRectangle.style.top = Math.round(top) + 'px';
+ this.extentRectangle.style.left = Math.round(left) + 'px';
+ this.extentRectangle.style.height = Math.round(height) + 'px';
+ this.extentRectangle.style.width = Math.round(width) + 'px';
+ }
+ this.rectPxBounds = new OpenLayers.Bounds(
+ Math.round(left), Math.round(bottom),
+ Math.round(right), Math.round(top)
+ );
},
/**
diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js
index c5721b24f8..61d4bdb632 100644
--- a/lib/OpenLayers/Map.js
+++ b/lib/OpenLayers/Map.js
@@ -53,6 +53,12 @@ OpenLayers.Map = OpenLayers.Class({
* {DOMElement} The element that contains the map
*/
div: null,
+
+ /**
+ * Property: dragging
+ * {Boolean} The map is currently being dragged.
+ */
+ dragging: false,
/**
* Property: size
@@ -1221,7 +1227,8 @@ OpenLayers.Map = OpenLayers.Class({
* TBD: reconsider forceZoomChange in 3.0
*/
setCenter: function (lonlat, zoom, dragging, forceZoomChange) {
-
+ this.dragging = !!dragging;
+
if (!this.center && !this.isValidLonLat(lonlat)) {
lonlat = this.maxExtent.getCenterLonLat();
}
diff --git a/tests/Control/test_OverviewMap.html b/tests/Control/test_OverviewMap.html
index 92cd01bb94..920f83f8df 100644
--- a/tests/Control/test_OverviewMap.html
+++ b/tests/Control/test_OverviewMap.html
@@ -51,9 +51,12 @@
t.eq(cent.lon, -71.3515625, "Clicking on the Overview Map has the correct effect on map lon");
t.eq(cent.lat, 42.17578125, "Clicking on the Overview Map has the correct effect on map lat");
- control.rectMouseDown({'xy':new OpenLayers.Pixel(5,5), 'which':1});
- control.rectMouseMove({'xy':new OpenLayers.Pixel(15,15), 'which':1});
- control.rectMouseUp({'xy':new OpenLayers.Pixel(15,15), 'which':1});
+ control.dragHandler = {
+ last: new OpenLayers.Pixel(5,5),
+ destroy: function() {}
+ };
+ control.rectDrag(new OpenLayers.Pixel(15, 15));
+ control.updateMapToRect();
var cent = map.getCenter();
t.eq(cent.lon, -71.2734375, "Dragging on the Overview Map has the correct effect on map lon");
diff --git a/theme/default/img/blank.gif b/theme/default/img/blank.gif
new file mode 100644
index 0000000000..4bcc753a12
Binary files /dev/null and b/theme/default/img/blank.gif differ
diff --git a/theme/default/img/overview_replacement.gif b/theme/default/img/overview_replacement.gif
new file mode 100644
index 0000000000..a82cf5fc54
Binary files /dev/null and b/theme/default/img/overview_replacement.gif differ
diff --git a/theme/default/style.css b/theme/default/style.css
index 242e5d3589..77029ace5e 100644
--- a/theme/default/style.css
+++ b/theme/default/style.css
@@ -64,9 +64,19 @@ div.olControlMousePosition {
}
.olControlOverviewMapExtentRectangle {
- cursor: move;
+ overflow: hidden;
+ background-image: url("img/blank.gif");
+ cursor: move;
border: 2px dotted red;
}
+.olControlOverviewMapRectReplacement {
+ overflow: hidden;
+ cursor: move;
+ background-image: url("img/overview_replacement.gif");
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
.olLayerGeoRSSDescription {
float:left;
width:100%;