|
/* 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/Control/PanZoom.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Control.PanZoomBar |
|
* The PanZoomBar is a visible control composed of a |
|
* <OpenLayers.Control.PanPanel> and a <OpenLayers.Control.ZoomBar>. |
|
* By default it is displayed in the upper left corner of the map as 4 |
|
* directional arrows above a vertical slider. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Control.PanZoom> |
|
*/ |
|
OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, { |
|
|
|
/** |
|
* APIProperty: zoomStopWidth |
|
*/ |
|
zoomStopWidth: 18, |
|
|
|
/** |
|
* APIProperty: zoomStopHeight |
|
*/ |
|
zoomStopHeight: 11, |
|
|
|
/** |
|
* Property: slider |
|
*/ |
|
slider: null, |
|
|
|
/** |
|
* Property: sliderEvents |
|
* {<OpenLayers.Events>} |
|
*/ |
|
sliderEvents: null, |
|
|
|
/** |
|
* Property: zoombarDiv |
|
* {DOMElement} |
|
*/ |
|
zoombarDiv: null, |
|
|
|
/** |
|
* Property: divEvents |
|
* {<OpenLayers.Events>} |
|
*/ |
|
divEvents: null, |
|
|
|
/** |
|
* APIProperty: zoomWorldIcon |
|
* {Boolean} |
|
*/ |
|
zoomWorldIcon: false, |
|
|
|
/** |
|
* APIProperty: forceFixedZoomLevel |
|
* {Boolean} Force a fixed zoom level even though the map has |
|
* fractionalZoom |
|
*/ |
|
forceFixedZoomLevel: false, |
|
|
|
/** |
|
* Property: mouseDragStart |
|
* {<OpenLayers.Pixel>} |
|
*/ |
|
mouseDragStart: null, |
|
|
|
/** |
|
* Property: zoomStart |
|
* {<OpenLayers.Pixel>} |
|
*/ |
|
zoomStart: null, |
|
|
|
/** |
|
* Constructor: OpenLayers.Control.PanZoomBar |
|
*/ |
|
initialize: function() { |
|
OpenLayers.Control.PanZoom.prototype.initialize.apply(this, arguments); |
|
}, |
|
|
|
/** |
|
* APIMethod: destroy |
|
*/ |
|
destroy: function() { |
|
|
|
this._removeZoomBar(); |
|
|
|
this.map.events.un({ |
|
"changebaselayer": this.redraw, |
|
scope: this |
|
}); |
|
|
|
OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments); |
|
|
|
delete this.mouseDragStart; |
|
delete this.zoomStart; |
|
}, |
|
|
|
/** |
|
* Method: setMap |
|
* |
|
* Parameters: |
|
* map - {<OpenLayers.Map>} |
|
*/ |
|
setMap: function(map) { |
|
OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments); |
|
this.map.events.register("changebaselayer", this, this.redraw); |
|
}, |
|
|
|
/** |
|
* Method: redraw |
|
* clear the div and start over. |
|
*/ |
|
redraw: function() { |
|
if (this.div != null) { |
|
this.removeButtons(); |
|
this._removeZoomBar(); |
|
} |
|
this.draw(); |
|
}, |
|
|
|
/** |
|
* Method: draw |
|
* |
|
* Parameters: |
|
* px - {<OpenLayers.Pixel>} |
|
*/ |
|
draw: function(px) { |
|
// initialize our internal div |
|
OpenLayers.Control.prototype.draw.apply(this, arguments); |
|
px = this.position.clone(); |
|
|
|
// place the controls |
|
this.buttons = []; |
|
|
|
var sz = new OpenLayers.Size(18,18); |
|
var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y); |
|
var wposition = sz.w; |
|
|
|
if (this.zoomWorldIcon) { |
|
centered = new OpenLayers.Pixel(px.x+sz.w, px.y); |
|
} |
|
|
|
this._addButton("panup", "north-mini.png", centered, sz); |
|
px.y = centered.y+sz.h; |
|
this._addButton("panleft", "west-mini.png", px, sz); |
|
if (this.zoomWorldIcon) { |
|
this._addButton("zoomworld", "zoom-world-mini.png", px.add(sz.w, 0), sz); |
|
|
|
wposition *= 2; |
|
} |
|
this._addButton("panright", "east-mini.png", px.add(wposition, 0), sz); |
|
this._addButton("pandown", "south-mini.png", centered.add(0, sz.h*2), sz); |
|
this._addButton("zoomin", "zoom-plus-mini.png", centered.add(0, sz.h*3+5), sz); |
|
centered = this._addZoomBar(centered.add(0, sz.h*4 + 5)); |
|
this._addButton("zoomout", "zoom-minus-mini.png", centered, sz); |
|
return this.div; |
|
}, |
|
|
|
/** |
|
* Method: _addZoomBar |
|
* |
|
* Parameters: |
|
* location - {<OpenLayers.Pixel>} where zoombar drawing is to start. |
|
*/ |
|
_addZoomBar:function(centered) { |
|
var imgLocation = OpenLayers.Util.getImagesLocation(); |
|
|
|
var id = this.id + "_" + this.map.id; |
|
var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom(); |
|
var slider = OpenLayers.Util.createAlphaImageDiv(id, |
|
centered.add(-1, zoomsToEnd * this.zoomStopHeight), |
|
new OpenLayers.Size(20,9), |
|
imgLocation+"slider.png", |
|
"absolute"); |
|
this.slider = slider; |
|
|
|
this.sliderEvents = new OpenLayers.Events(this, slider, null, true, |
|
{includeXY: true}); |
|
this.sliderEvents.on({ |
|
"mousedown": this.zoomBarDown, |
|
"mousemove": this.zoomBarDrag, |
|
"mouseup": this.zoomBarUp, |
|
"dblclick": this.doubleClick, |
|
"click": this.doubleClick |
|
}); |
|
|
|
var sz = new OpenLayers.Size(); |
|
sz.h = this.zoomStopHeight * this.map.getNumZoomLevels(); |
|
sz.w = this.zoomStopWidth; |
|
var div = null; |
|
|
|
if (OpenLayers.Util.alphaHack()) { |
|
var id = this.id + "_" + this.map.id; |
|
div = OpenLayers.Util.createAlphaImageDiv(id, centered, |
|
new OpenLayers.Size(sz.w, |
|
this.zoomStopHeight), |
|
imgLocation + "zoombar.png", |
|
"absolute", null, "crop"); |
|
div.style.height = sz.h + "px"; |
|
} else { |
|
div = OpenLayers.Util.createDiv( |
|
'OpenLayers_Control_PanZoomBar_Zoombar' + this.map.id, |
|
centered, |
|
sz, |
|
imgLocation+"zoombar.png"); |
|
} |
|
|
|
this.zoombarDiv = div; |
|
|
|
this.divEvents = new OpenLayers.Events(this, div, null, true, |
|
{includeXY: true}); |
|
this.divEvents.on({ |
|
"mousedown": this.divClick, |
|
"mousemove": this.passEventToSlider, |
|
"dblclick": this.doubleClick, |
|
"click": this.doubleClick |
|
}); |
|
|
|
this.div.appendChild(div); |
|
|
|
this.startTop = parseInt(div.style.top); |
|
this.div.appendChild(slider); |
|
|
|
this.map.events.register("zoomend", this, this.moveZoomBar); |
|
|
|
centered = centered.add(0, |
|
this.zoomStopHeight * this.map.getNumZoomLevels()); |
|
return centered; |
|
}, |
|
|
|
/** |
|
* Method: _removeZoomBar |
|
*/ |
|
_removeZoomBar: function() { |
|
this.sliderEvents.un({ |
|
"mousedown": this.zoomBarDown, |
|
"mousemove": this.zoomBarDrag, |
|
"mouseup": this.zoomBarUp, |
|
"dblclick": this.doubleClick, |
|
"click": this.doubleClick |
|
}); |
|
this.sliderEvents.destroy(); |
|
|
|
this.divEvents.un({ |
|
"mousedown": this.divClick, |
|
"mousemove": this.passEventToSlider, |
|
"dblclick": this.doubleClick, |
|
"click": this.doubleClick |
|
}); |
|
this.divEvents.destroy(); |
|
|
|
this.div.removeChild(this.zoombarDiv); |
|
this.zoombarDiv = null; |
|
this.div.removeChild(this.slider); |
|
this.slider = null; |
|
|
|
this.map.events.unregister("zoomend", this, this.moveZoomBar); |
|
}, |
|
|
|
/** |
|
* Method: passEventToSlider |
|
* This function is used to pass events that happen on the div, or the map, |
|
* through to the slider, which then does its moving thing. |
|
* |
|
* Parameters: |
|
* evt - {<OpenLayers.Event>} |
|
*/ |
|
passEventToSlider:function(evt) { |
|
this.sliderEvents.handleBrowserEvent(evt); |
|
}, |
|
|
|
/** |
|
* Method: divClick |
|
* Picks up on clicks directly on the zoombar div |
|
* and sets the zoom level appropriately. |
|
*/ |
|
divClick: function (evt) { |
|
if (!OpenLayers.Event.isLeftClick(evt)) { |
|
return; |
|
} |
|
var y = evt.xy.y; |
|
var top = OpenLayers.Util.pagePosition(evt.object)[1]; |
|
var levels = (y - top)/this.zoomStopHeight; |
|
if(this.forceFixedZoomLevel || !this.map.fractionalZoom) { |
|
levels = Math.floor(levels); |
|
} |
|
var zoom = (this.map.getNumZoomLevels() - 1) - levels; |
|
zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1); |
|
this.map.zoomTo(zoom); |
|
OpenLayers.Event.stop(evt); |
|
}, |
|
|
|
/* |
|
* Method: zoomBarDown |
|
* event listener for clicks on the slider |
|
* |
|
* Parameters: |
|
* evt - {<OpenLayers.Event>} |
|
*/ |
|
zoomBarDown:function(evt) { |
|
if (!OpenLayers.Event.isLeftClick(evt)) { |
|
return; |
|
} |
|
this.map.events.on({ |
|
"mousemove": this.passEventToSlider, |
|
"mouseup": this.passEventToSlider, |
|
scope: this |
|
}); |
|
this.mouseDragStart = evt.xy.clone(); |
|
this.zoomStart = evt.xy.clone(); |
|
this.div.style.cursor = "move"; |
|
// reset the div offsets just in case the div moved |
|
this.zoombarDiv.offsets = null; |
|
OpenLayers.Event.stop(evt); |
|
}, |
|
|
|
/* |
|
* Method: zoomBarDrag |
|
* This is what happens when a click has occurred, and the client is |
|
* dragging. Here we must ensure that the slider doesn't go beyond the |
|
* bottom/top of the zoombar div, as well as moving the slider to its new |
|
* visual location |
|
* |
|
* Parameters: |
|
* evt - {<OpenLayers.Event>} |
|
*/ |
|
zoomBarDrag:function(evt) { |
|
if (this.mouseDragStart != null) { |
|
var deltaY = this.mouseDragStart.y - evt.xy.y; |
|
var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv); |
|
if ((evt.clientY - offsets[1]) > 0 && |
|
(evt.clientY - offsets[1]) < parseInt(this.zoombarDiv.style.height) - 2) { |
|
var newTop = parseInt(this.slider.style.top) - deltaY; |
|
this.slider.style.top = newTop+"px"; |
|
this.mouseDragStart = evt.xy.clone(); |
|
} |
|
OpenLayers.Event.stop(evt); |
|
} |
|
}, |
|
|
|
/* |
|
* Method: zoomBarUp |
|
* Perform cleanup when a mouseup event is received -- discover new zoom |
|
* level and switch to it. |
|
* |
|
* Parameters: |
|
* evt - {<OpenLayers.Event>} |
|
*/ |
|
zoomBarUp:function(evt) { |
|
if (!OpenLayers.Event.isLeftClick(evt)) { |
|
return; |
|
} |
|
if (this.mouseDragStart) { |
|
this.div.style.cursor=""; |
|
this.map.events.un({ |
|
"mouseup": this.passEventToSlider, |
|
"mousemove": this.passEventToSlider, |
|
scope: this |
|
}); |
|
var deltaY = this.zoomStart.y - evt.xy.y; |
|
var zoomLevel = this.map.zoom; |
|
if (!this.forceFixedZoomLevel && this.map.fractionalZoom) { |
|
zoomLevel += deltaY/this.zoomStopHeight; |
|
zoomLevel = Math.min(Math.max(zoomLevel, 0), |
|
this.map.getNumZoomLevels() - 1); |
|
} else { |
|
zoomLevel += Math.round(deltaY/this.zoomStopHeight); |
|
} |
|
this.map.zoomTo(zoomLevel); |
|
this.mouseDragStart = null; |
|
this.zoomStart = null; |