]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Control/PanZoomBar.js
fixes notices
[syp.git] / openlayers / lib / OpenLayers / Control / PanZoomBar.js
1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2  * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3  * full text of the license. */
4
5
6 /**
7  * @requires OpenLayers/Control/PanZoom.js
8  */
9
10 /**
11  * Class: OpenLayers.Control.PanZoomBar
12  * The PanZoomBar is a visible control composed of a
13  * <OpenLayers.Control.PanPanel> and a <OpenLayers.Control.ZoomBar>. 
14  * By default it is displayed in the upper left corner of the map as 4
15  * directional arrows above a vertical slider.
16  *
17  * Inherits from:
18  *  - <OpenLayers.Control.PanZoom>
19  */
20 OpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {
21
22     /** 
23      * APIProperty: zoomStopWidth
24      */
25     zoomStopWidth: 18,
26
27     /** 
28      * APIProperty: zoomStopHeight
29      */
30     zoomStopHeight: 11,
31
32     /** 
33      * Property: slider
34      */
35     slider: null,
36
37     /** 
38      * Property: sliderEvents
39      * {<OpenLayers.Events>}
40      */
41     sliderEvents: null,
42
43     /** 
44      * Property: zoomBarDiv
45      * {DOMElement}
46      */
47     zoomBarDiv: null,
48
49     /** 
50      * Property: divEvents
51      * {<OpenLayers.Events>}
52      */
53     divEvents: null,
54
55     /** 
56      * APIProperty: zoomWorldIcon
57      * {Boolean}
58      */
59     zoomWorldIcon: false,
60
61     /**
62      * Constructor: OpenLayers.Control.PanZoomBar
63      */ 
64     initialize: function() {
65         OpenLayers.Control.PanZoom.prototype.initialize.apply(this, arguments);
66     },
67
68     /**
69      * APIMethod: destroy
70      */
71     destroy: function() {
72
73         this._removeZoomBar();
74
75         this.map.events.un({
76             "changebaselayer": this.redraw,
77             scope: this
78         });
79
80         OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments);
81     },
82     
83     /**
84      * Method: setMap
85      * 
86      * Parameters:
87      * map - {<OpenLayers.Map>} 
88      */
89     setMap: function(map) {
90         OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments);
91         this.map.events.register("changebaselayer", this, this.redraw);
92     },
93
94     /** 
95      * Method: redraw
96      * clear the div and start over.
97      */
98     redraw: function() {
99         if (this.div != null) {
100             this.removeButtons();
101             this._removeZoomBar();
102         }  
103         this.draw();
104     },
105     
106     /**
107     * Method: draw 
108     *
109     * Parameters:
110     * px - {<OpenLayers.Pixel>} 
111     */
112     draw: function(px) {
113         // initialize our internal div
114         OpenLayers.Control.prototype.draw.apply(this, arguments);
115         px = this.position.clone();
116
117         // place the controls
118         this.buttons = [];
119
120         var sz = new OpenLayers.Size(18,18);
121         var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);
122         var wposition = sz.w;
123
124         if (this.zoomWorldIcon) {
125             centered = new OpenLayers.Pixel(px.x+sz.w, px.y);
126         }
127
128         this._addButton("panup", "north-mini.png", centered, sz);
129         px.y = centered.y+sz.h;
130         this._addButton("panleft", "west-mini.png", px, sz);
131         if (this.zoomWorldIcon) {
132             this._addButton("zoomworld", "zoom-world-mini.png", px.add(sz.w, 0), sz);
133             
134             wposition *= 2;
135         }
136         this._addButton("panright", "east-mini.png", px.add(wposition, 0), sz);
137         this._addButton("pandown", "south-mini.png", centered.add(0, sz.h*2), sz);
138         this._addButton("zoomin", "zoom-plus-mini.png", centered.add(0, sz.h*3+5), sz);
139         centered = this._addZoomBar(centered.add(0, sz.h*4 + 5));
140         this._addButton("zoomout", "zoom-minus-mini.png", centered, sz);
141         return this.div;
142     },
143
144     /** 
145     * Method: _addZoomBar
146     * 
147     * Parameters:
148     * location - {<OpenLayers.Pixel>} where zoombar drawing is to start.
149     */
150     _addZoomBar:function(centered) {
151         var imgLocation = OpenLayers.Util.getImagesLocation();
152         
153         var id = this.id + "_" + this.map.id;
154         var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();
155         var slider = OpenLayers.Util.createAlphaImageDiv(id,
156                        centered.add(-1, zoomsToEnd * this.zoomStopHeight), 
157                        new OpenLayers.Size(20,9), 
158                        imgLocation+"slider.png",
159                        "absolute");
160         this.slider = slider;
161         
162         this.sliderEvents = new OpenLayers.Events(this, slider, null, true,
163                                             {includeXY: true});
164         this.sliderEvents.on({
165             "mousedown": this.zoomBarDown,
166             "mousemove": this.zoomBarDrag,
167             "mouseup": this.zoomBarUp,
168             "dblclick": this.doubleClick,
169             "click": this.doubleClick
170         });
171         
172         var sz = new OpenLayers.Size();
173         sz.h = this.zoomStopHeight * this.map.getNumZoomLevels();
174         sz.w = this.zoomStopWidth;
175         var div = null;
176         
177         if (OpenLayers.Util.alphaHack()) {
178             var id = this.id + "_" + this.map.id;
179             div = OpenLayers.Util.createAlphaImageDiv(id, centered,
180                                       new OpenLayers.Size(sz.w, 
181                                               this.zoomStopHeight),
182                                       imgLocation + "zoombar.png", 
183                                       "absolute", null, "crop");
184             div.style.height = sz.h + "px";
185         } else {
186             div = OpenLayers.Util.createDiv(
187                         'OpenLayers_Control_PanZoomBar_Zoombar' + this.map.id,
188                         centered,
189                         sz,
190                         imgLocation+"zoombar.png");
191         }
192         
193         this.zoombarDiv = div;
194         
195         this.divEvents = new OpenLayers.Events(this, div, null, true, 
196                                                 {includeXY: true});
197         this.divEvents.on({
198             "mousedown": this.divClick,
199             "mousemove": this.passEventToSlider,
200             "dblclick": this.doubleClick,
201             "click": this.doubleClick
202         });
203         
204         this.div.appendChild(div);
205
206         this.startTop = parseInt(div.style.top);
207         this.div.appendChild(slider);
208
209         this.map.events.register("zoomend", this, this.moveZoomBar);
210
211         centered = centered.add(0, 
212             this.zoomStopHeight * this.map.getNumZoomLevels());
213         return centered; 
214     },
215     
216     /**
217      * Method: _removeZoomBar
218      */
219     _removeZoomBar: function() {
220         this.sliderEvents.un({
221             "mousedown": this.zoomBarDown,
222             "mousemove": this.zoomBarDrag,
223             "mouseup": this.zoomBarUp,
224             "dblclick": this.doubleClick,
225             "click": this.doubleClick
226         });
227         this.sliderEvents.destroy();
228
229         this.divEvents.un({
230             "mousedown": this.divClick,
231             "mousemove": this.passEventToSlider,
232             "dblclick": this.doubleClick,
233             "click": this.doubleClick
234         });
235         this.divEvents.destroy();
236         
237         this.div.removeChild(this.zoombarDiv);
238         this.zoombarDiv = null;
239         this.div.removeChild(this.slider);
240         this.slider = null;
241         
242         this.map.events.unregister("zoomend", this, this.moveZoomBar);
243     },
244     
245     /**
246      * Method: passEventToSlider
247      * This function is used to pass events that happen on the div, or the map,
248      * through to the slider, which then does its moving thing.
249      *
250      * Parameters:
251      * evt - {<OpenLayers.Event>} 
252      */
253     passEventToSlider:function(evt) {
254         this.sliderEvents.handleBrowserEvent(evt);
255     },
256     
257     /**
258      * Method: divClick
259      * Picks up on clicks directly on the zoombar div
260      *           and sets the zoom level appropriately.
261      */
262     divClick: function (evt) {
263         if (!OpenLayers.Event.isLeftClick(evt)) {
264             return;
265         }
266         var y = evt.xy.y;
267         var top = OpenLayers.Util.pagePosition(evt.object)[1];
268         var levels = (y - top)/this.zoomStopHeight;
269         if(!this.map.fractionalZoom) {
270             levels = Math.floor(levels);
271         }    
272         var zoom = (this.map.getNumZoomLevels() - 1) - levels; 
273         zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1);
274         this.map.zoomTo(zoom);
275         OpenLayers.Event.stop(evt);
276     },
277     
278     /*
279      * Method: zoomBarDown
280      * event listener for clicks on the slider
281      *
282      * Parameters:
283      * evt - {<OpenLayers.Event>} 
284      */
285     zoomBarDown:function(evt) {
286         if (!OpenLayers.Event.isLeftClick(evt)) {
287             return;
288         }
289         this.map.events.on({
290             "mousemove": this.passEventToSlider,
291             "mouseup": this.passEventToSlider,
292             scope: this
293         });
294         this.mouseDragStart = evt.xy.clone();
295         this.zoomStart = evt.xy.clone();
296         this.div.style.cursor = "move";
297         // reset the div offsets just in case the div moved
298         this.zoombarDiv.offsets = null; 
299         OpenLayers.Event.stop(evt);
300     },
301     
302     /*
303      * Method: zoomBarDrag
304      * This is what happens when a click has occurred, and the client is
305      * dragging.  Here we must ensure that the slider doesn't go beyond the
306      * bottom/top of the zoombar div, as well as moving the slider to its new
307      * visual location
308      *
309      * Parameters:
310      * evt - {<OpenLayers.Event>} 
311      */
312     zoomBarDrag:function(evt) {
313         if (this.mouseDragStart != null) {
314             var deltaY = this.mouseDragStart.y - evt.xy.y;
315             var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv);
316             if ((evt.clientY - offsets[1]) > 0 && 
317                 (evt.clientY - offsets[1]) < parseInt(this.zoombarDiv.style.height) - 2) {
318                 var newTop = parseInt(this.slider.style.top) - deltaY;
319                 this.slider.style.top = newTop+"px";
320                 this.mouseDragStart = evt.xy.clone();
321             }
322             OpenLayers.Event.stop(evt);
323         }
324     },
325     
326     /*
327      * Method: zoomBarUp
328      * Perform cleanup when a mouseup event is received -- discover new zoom
329      * level and switch to it.
330      *
331      * Parameters:
332      * evt - {<OpenLayers.Event>} 
333      */
334     zoomBarUp:function(evt) {
335         if (!OpenLayers.Event.isLeftClick(evt)) {
336             return;
337         }
338         if (this.zoomStart) {
339             this.div.style.cursor="";
340             this.map.events.un({
341                 "mouseup": this.passEventToSlider,
342                 "mousemove": this.passEventToSlider,
343                 scope: this
344             });
345             var deltaY = this.zoomStart.y - evt.xy.y;
346             var zoomLevel = this.map.zoom;
347             if (this.map.fractionalZoom) {
348                 zoomLevel += deltaY/this.zoomStopHeight;
349                 zoomLevel = Math.min(Math.max(zoomLevel, 0), 
350                                      this.map.getNumZoomLevels() - 1);
351             } else {
352                 zoomLevel += Math.round(deltaY/this.zoomStopHeight);
353             }
354             this.map.zoomTo(zoomLevel);
355             this.moveZoomBar();
356             this.mouseDragStart = null;
357             OpenLayers.Event.stop(evt);
358         }
359     },
360     
361     /*
362     * Method: moveZoomBar
363     * Change the location of the slider to match the current zoom level.
364     */
365     moveZoomBar:function() {
366         var newTop = 
367             ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) * 
368             this.zoomStopHeight + this.startTop + 1;
369         this.slider.style.top = newTop + "px";
370     },    
371     
372     CLASS_NAME: "OpenLayers.Control.PanZoomBar"
373 });