1 /* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
2 * full list of contributors). Published under the 2-clause BSD license.
3 * See license.txt in the OpenLayers distribution or repository for the
4 * full text of the license. */
8 * @requires OpenLayers/Control/PanZoom.js
12 * Class: OpenLayers.Control.PanZoomBar
13 * The PanZoomBar is a visible control composed of a
14 * <OpenLayers.Control.PanPanel> and a <OpenLayers.Control.ZoomBar>.
15 * By default it is displayed in the upper left corner of the map as 4
16 * directional arrows above a vertical slider.
19 * - <OpenLayers.Control.PanZoom>
21 OpenLayers.Control.SimplePanZoom = OpenLayers.Class(OpenLayers.Control.PanZoom, {
24 * APIProperty: zoomStopWidth
29 * APIProperty: zoomStopHeight
39 * Property: sliderEvents
40 * {<OpenLayers.Events>}
45 * Property: zoombarDiv
51 * APIProperty: zoomWorldIcon
57 * APIProperty: panIcons
58 * {Boolean} Set this property to false not to display the pan icons. If
59 * false the zoom world icon is placed under the zoom bar. Defaults to
65 * APIProperty: forceFixedZoomLevel
66 * {Boolean} Force a fixed zoom level even though the map has
69 forceFixedZoomLevel: false,
72 * Property: mouseDragStart
73 * {<OpenLayers.Pixel>}
79 * {Number} The cumulative vertical pixel offset during a zoom bar drag.
85 * {<OpenLayers.Pixel>}
90 * Constructor: OpenLayers.Control.PanZoomBar
99 this._removeZoomBar();
102 "changebaselayer": this.redraw,
103 "updatesize": this.redraw,
107 OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments);
109 delete this.mouseDragStart;
110 delete this.zoomStart;
117 * map - {<OpenLayers.Map>}
119 setMap: function(map) {
120 OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments);
122 "changebaselayer": this.redraw,
123 "updatesize": this.redraw,
130 * clear the div and start over.
133 if (this.div !== null) {
134 this.removeButtons();
135 this._removeZoomBar();
145 * px - {<OpenLayers.Pixel>}
148 // initialize our internal div
149 OpenLayers.Control.prototype.draw.apply(this, arguments);
150 px = this.position.clone();
152 // place the controls
154 var ids = ['panup', 'panleft', 'panright', 'pandown', 'zoomout', 'zoomin'];
156 for (var i = 0; i < ids.length; i++) {
157 var b = document.createElement('div');
160 b.className = 'button olButton';
161 this.div.appendChild(b);
162 this.buttons.push(b);
170 * Method: _addZoomBar
173 * centered - {<OpenLayers.Pixel>} where zoombar drawing is to start.
175 _addZoomBar:function() {
176 var id = this.id + "_" + this.map.id;
177 var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();
178 var slider = document.createElement('div');
179 slider.id = 'slider';
180 slider.className = 'button';
181 slider.style.cursor = 'move';
182 this.slider = slider;
184 this.sliderEvents = new OpenLayers.Events(this, slider, null, true,
185 { includeXY: true });
186 this.sliderEvents.on({
187 "touchstart": this.zoomBarDown,
188 "touchmove": this.zoomBarDrag,
189 "touchend": this.zoomBarUp,
190 "mousedown": this.zoomBarDown,
191 "mousemove": this.zoomBarDrag,
192 "mouseup": this.zoomBarUp
195 var height = this.zoomStopHeight * (this.map.getNumZoomLevels());
197 // this is the background image
198 var div = document.createElement('div');
199 div.className = 'button olButton';
201 this.zoombarDiv = div;
203 this.div.appendChild(div);
205 this.div.appendChild(slider);
207 this.map.events.register("zoomend", this, this.moveZoomBar);
211 * Method: _removeZoomBar
213 _removeZoomBar: function() {
214 this.sliderEvents.un({
215 "touchstart": this.zoomBarDown,
216 "touchmove": this.zoomBarDrag,
217 "touchend": this.zoomBarUp,
218 "mousedown": this.zoomBarDown,
219 "mousemove": this.zoomBarDrag,
220 "mouseup": this.zoomBarUp
222 this.sliderEvents.destroy();
224 this.div.removeChild(this.zoombarDiv);
225 this.zoombarDiv = null;
226 this.div.removeChild(this.slider);
229 this.map.events.unregister("zoomend", this, this.moveZoomBar);
233 * Method: onButtonClick
238 onButtonClick: function(evt) {
239 OpenLayers.Control.PanZoom.prototype.onButtonClick.apply(this, arguments);
240 if (evt.buttonElement === this.zoombarDiv) {
241 var levels = evt.buttonXY.y / this.zoomStopHeight;
242 if (this.forceFixedZoomLevel || !this.map.fractionalZoom) {
243 levels = Math.floor(levels);
245 var zoom = (this.map.getNumZoomLevels() - 1) - levels;
246 zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1);
247 this.map.zoomTo(zoom);
252 * Method: passEventToSlider
253 * This function is used to pass events that happen on the div, or the map,
254 * through to the slider, which then does its moving thing.
257 * evt - {<OpenLayers.Event>}
259 passEventToSlider:function(evt) {
260 this.sliderEvents.handleBrowserEvent(evt);
264 * Method: zoomBarDown
265 * event listener for clicks on the slider
268 * evt - {<OpenLayers.Event>}
270 zoomBarDown:function(evt) {
271 if (!OpenLayers.Event.isLeftClick(evt) && !OpenLayers.Event.isSingleTouch(evt)) {
275 "touchmove": this.passEventToSlider,
276 "mousemove": this.passEventToSlider,
277 "mouseup": this.passEventToSlider,
280 this.mouseDragStart = evt.xy.clone();
281 this.zoomStart = evt.xy.clone();
282 this.div.style.cursor = "move";
283 // reset the div offsets just in case the div moved
284 this.zoombarDiv.offsets = null;
285 OpenLayers.Event.stop(evt);
289 * Method: zoomBarDrag
290 * This is what happens when a click has occurred, and the client is
291 * dragging. Here we must ensure that the slider doesn't go beyond the
292 * bottom/top of the zoombar div, as well as moving the slider to its new
296 * evt - {<OpenLayers.Event>}
298 zoomBarDrag: function(evt) {
299 if (this.mouseDragStart !== null) {
300 var deltaY = this.mouseDragStart.y - evt.xy.y;
301 var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv);
302 if ((evt.clientY - offsets[1]) > 0 &&
303 (evt.clientY - offsets[1]) < 140) {
304 var newTop = parseInt(this.slider.style.top, 10) - deltaY;
305 this.slider.style.top = newTop + "px";
306 this.mouseDragStart = evt.xy.clone();
308 // set cumulative displacement
309 this.deltaY = this.zoomStart.y - evt.xy.y;
310 OpenLayers.Event.stop(evt);
316 * Perform cleanup when a mouseup event is received -- discover new zoom
317 * level and switch to it.
320 * evt - {<OpenLayers.Event>}
322 zoomBarUp: function(evt) {
323 if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== "touchend") {
326 if (this.mouseDragStart) {
327 this.div.style.cursor = "";
329 "touchmove": this.passEventToSlider,
330 "mouseup": this.passEventToSlider,
331 "mousemove": this.passEventToSlider,
334 var zoomLevel = this.map.zoom;
335 zoomLevel += this.deltaY/this.zoomStopHeight;
336 zoomLevel = Math.max(Math.round(zoomLevel), 0);
337 this.map.zoomTo(zoomLevel);
338 this.mouseDragStart = null;
339 this.zoomStart = null;
341 OpenLayers.Event.stop(evt);
346 * Method: moveZoomBar
347 * Change the location of the slider to match the current zoom level.
349 moveZoomBar:function() {
351 ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) *
352 this.zoomStopHeight + this.startTop;
353 this.slider.style.top = newTop + "px";
355 CLASS_NAME: "OpenLayers.Control.SimplePanZoom"