Ticket #16: 16.2.patch

File 16.2.patch, 19.8 kB (added by tschaub, 1 year ago)

zoom slider and tips

  • tests/lib/GeoExt/widgets/ZoomSlider.html

    old new  
     1<!DOCTYPE html> 
     2<html debug="true"> 
     3  <head> 
     4    <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script> 
     5    <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script> 
     6    <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script> 
     7    <script type="text/javascript" src="../../../../lib/GeoExt.js"></script> 
     8 
     9    <script type="text/javascript"> 
     10        
     11        function test_zoomslider(t) { 
     12            t.plan(7); 
     13             
     14            var map = new OpenLayers.Map({ 
     15                div: "map", 
     16                allOverlays: true 
     17            }); 
     18            map.addLayer(new OpenLayers.Layer()); 
     19            map.setCenter(new OpenLayers.LonLat(0, 0), 2); 
     20             
     21            var slider = new GeoExt.ZoomSlider({ 
     22                map: map, 
     23                renderTo: document.body 
     24            }); 
     25             
     26            // test range of values 
     27            t.eq(slider.minValue, 0, "slider min is 0"); 
     28            t.eq(slider.maxValue, 15, "slider can go to 15"); 
     29             
     30            // test initial value 
     31            t.eq(slider.getValue(), 2, "slider has correct value after setCenter"); 
     32             
     33            // zoom in and test that value is updated 
     34            map.zoomIn(); 
     35            t.eq(slider.getValue(), 3, "slider has correct value after zoomIn"); 
     36             
     37            // test that zoomTo updates slider value 
     38            map.zoomTo(0); 
     39            t.eq(slider.getValue(), 0, "slider has correct value after zoomTo"); 
     40             
     41            // test that slider can be destroyed 
     42            try { 
     43                slider.destroy(); 
     44                t.ok(true, "slider.destroy does not cause problems"); 
     45            } catch(err) { 
     46                t.fail("slider.destroy causes problems: " + err); 
     47            } 
     48             
     49            // test that map can be zoomed without trouble after slider destroy 
     50            try { 
     51                map.zoomIn(); 
     52                t.ok(true, "map.zoomIn does not cause problems after slider.destroy"); 
     53            } catch(err) { 
     54                t.fail("map.zoomIn causes problems after slider.destroy: " + err); 
     55            } 
     56             
     57            map.destroy(); 
     58 
     59        } 
     60 
     61    </script> 
     62  <body> 
     63    <div id="map" style="width: 512px; height: 256px;"></div> 
     64  </body> 
     65</html> 
  • tests/list-tests.html

    old new  
    1818  <li>lib/GeoExt/widgets/tree/LayerNode.html</li> 
    1919  <li>lib/GeoExt/widgets/tree/LayerContainer.html</li> 
    2020  <li>lib/GeoExt/widgets/LegendPanel.html</li> 
     21  <li>lib/GeoExt/widgets/ZoomSlider.html</li> 
    2122</ul> 
  • lib/GeoExt.js

    old new  
    7575            "GeoExt/widgets/form/SearchAction.js", 
    7676            "GeoExt/widgets/form/BasicForm.js", 
    7777            "GeoExt/widgets/form/FormPanel.js", 
     78            "GeoExt/widgets/tips/SliderTip.js", 
     79            "GeoExt/widgets/tips/ZoomSliderTip.js", 
    7880            "GeoExt/widgets/tree/LayerNode.js", 
    7981            "GeoExt/widgets/tree/LayerContainer.js", 
    8082            "GeoExt/widgets/tree/BaseLayerContainer.js", 
    8183            "GeoExt/widgets/tree/OverlayLayerContainer.js", 
    8284            "GeoExt/widgets/LegendImage.js", 
    8385            "GeoExt/widgets/LegendWMS.js", 
    84             "GeoExt/widgets/LegendPanel.js" 
     86            "GeoExt/widgets/LegendPanel.js", 
     87            "GeoExt/widgets/ZoomSlider.js" 
    8588        ); 
    8689 
    8790        var agent = navigator.userAgent; 
  • lib/GeoExt/widgets/tips/ZoomSliderTip.js

    old new  
     1/** 
     2 * Copyright (c) 2008 The Open Planning Project 
     3 */ 
     4 
     5/** 
     6 * @include GeoExt/widgets/tips/SliderTip.js 
     7 */ 
     8 
     9/** api: (extends) 
     10 *  GeoExt/widgets/tips/SliderTip.js 
     11 */ 
     12 
     13/** api: (define) 
     14 *  module = GeoExt 
     15 *  class = ZoomSliderTip 
     16 *  base_link = `Ext.Tip <http://extjs.com/deploy/dev/docs/?class=Ext.Tip>`_ 
     17 */ 
     18Ext.namespace("GeoExt"); 
     19 
     20/** api: example 
     21 *  Sample code to create a slider tip to display scale and resolution: 
     22 *  
     23 *  .. code-block:: javascript 
     24 *      
     25 *      var slider = new GeoExt.ZoomSlider({ 
     26 *          renderTo: document.body, 
     27 *          width: 200, 
     28 *          map: map, 
     29 *          plugins: new GeoExt.ZoomSliderTip({ 
     30 *              template: "Scale: 1 : {scale}<br>Resolution: {resolution}" 
     31 *          }) 
     32 *      }); 
     33 */ 
     34 
     35/** api: constructor 
     36 *  .. class:: ZoomSliderTip(config) 
     37 *    
     38 *      Create a slider tip displaying :class:`GeoExt.ZoomSlider` values. 
     39 */ 
     40GeoExt.ZoomSliderTip = Ext.extend(GeoExt.SliderTip, { 
     41     
     42    /** api: config[template] 
     43     *  ``String`` 
     44     *  Template for the tip. Can be customized using the following keywords in 
     45     *  curly braces: 
     46     *   
     47     *  * ``zoom`` - the zoom level 
     48     *  * ``resolution`` - the resolution 
     49     *  * ``scale`` - the scale denominator 
     50     */ 
     51    template: '<div>Zoom Level: {zoom}</div>' + 
     52        '<div>Resolution: {resolution}</div>' + 
     53        '<div>Scale: 1 : {scale}</div>', 
     54     
     55    /** private: property[compiledTemplate] 
     56     *  ``Ext.Template`` 
     57     *  The template compiled from the ``template`` string on init. 
     58     */ 
     59    compiledTemplate: null, 
     60     
     61    /** private: method[init] 
     62     *  Called to initialize the plugin. 
     63     */ 
     64    init: function(slider) { 
     65        this.compiledTemplate = new Ext.Template(this.template); 
     66        GeoExt.ZoomSliderTip.superclass.init.call(this, slider); 
     67    }, 
     68     
     69    /** private: method[getText] 
     70     *  :param slider: ``Ext.Slider`` The slider this tip is attached to. 
     71     */ 
     72    getText : function(slider) { 
     73        var data = { 
     74            zoom: slider.getZoom(), 
     75            resolution: slider.getResolution(), 
     76            scale: Math.round(slider.getScale())  
     77        }; 
     78        return this.compiledTemplate.apply(data); 
     79    } 
     80}); 
  • lib/GeoExt/widgets/tips/SliderTip.js

    old new  
     1/** 
     2 * Copyright (c) 2008 The Open Planning Project 
     3 */ 
     4 
     5/** api: (define) 
     6 *  module = GeoExt 
     7 *  class = SliderTip 
     8 *  base_link = `Ext.Tip <http://extjs.com/deploy/dev/docs/?class=Ext.Tip>`_ 
     9 */ 
     10Ext.namespace("GeoExt"); 
     11 
     12/** api: example 
     13 *  Sample code to create a slider tip to display slider value on hover: 
     14 *  
     15 *  .. code-block:: javascript 
     16 *      
     17 *      var slider = new Ext.Slider({ 
     18 *          renderTo: document.body, 
     19 *          width: 200, 
     20 *          plugins: new GeoExt.SliderTip() 
     21 *      }); 
     22 */ 
     23 
     24/** api: constructor 
     25 *  .. class:: SliderTip(config) 
     26 *    
     27 *      Create a slider tip displaying ``Ext.Slider`` values over slider thumbs. 
     28 */ 
     29GeoExt.SliderTip = Ext.extend(Ext.Tip, { 
     30 
     31    /** api: config[hover] 
     32     *  ``Boolean`` 
     33     *  Display the tip when hovering over the thumb.  If ``false``, tip will 
     34     *  only be displayed while dragging.  Default is ``true``. 
     35     */ 
     36    hover: true, 
     37     
     38    /** api: config[minWidth] 
     39     *  ``Number`` 
     40     *  Minimum width of the tip.  Default is 10. 
     41     */ 
     42    minWidth: 10, 
     43 
     44    /** api: config[minWidth] 
     45     *  ``Number`` 
     46     *  Minimum width of the tip.  Default is 10. 
     47     */ 
     48    minWidth: 10, 
     49     
     50    /** api: config[offsets] 
     51     *  ``Array(Number)`` 
     52     *  A two item list that provides x, y offsets for the tip.  Default is 
     53     *  [0, -10]. 
     54     */ 
     55    offsets : [0, -10], 
     56     
     57    /** private: property[dragging] 
     58     *  ``Boolean`` 
     59     *  The thumb is currently being dragged. 
     60     */ 
     61    dragging: false, 
     62 
     63    /** private: method[init] 
     64     *  :param slider: ``Ext.Slider`` 
     65     *   
     66     *  Called when the plugin is initialized. 
     67     */ 
     68    init: function(slider) { 
     69        slider.on({ 
     70            dragstart: this.onSlide, 
     71            drag: this.onSlide, 
     72            dragend: this.hide, 
     73            destroy: this.destroy, 
     74            scope: this 
     75        }); 
     76        if(this.hover) { 
     77            slider.on("render", this.registerThumbListeners, this); 
     78        } 
     79        this.slider = slider; 
     80    }, 
     81 
     82    /** private: method[registerThumbListeners] 
     83     *  Set as a listener for 'render' if hover is true. 
     84     */ 
     85    registerThumbListeners: function() { 
     86        this.slider.thumb.on({ 
     87            "mouseover": function() { 
     88                this.onSlide(this.slider); 
     89                this.dragging = false; 
     90            }, 
     91            "mouseout": function() { 
     92                if(!this.dragging) { 
     93                    this.hide.apply(this, arguments); 
     94                } 
     95            }, 
     96            scope: this 
     97        }); 
     98    }, 
     99 
     100    /** private: method[onSlide] 
     101     *  :param slider: ``Ext.Slider`` 
     102     * 
     103     *  Listener for dragstart and drag. 
     104     */ 
     105    onSlide: function(slider) { 
     106        this.dragging = true; 
     107        this.show(); 
     108        this.body.update(this.getText(slider)); 
     109        this.doAutoWidth(); 
     110        this.el.alignTo(slider.thumb, 'b-t?', this.offsets); 
     111    }, 
     112 
     113    /** api: config[getText] 
     114     *  :return: ``String`` 
     115     *   
     116     *  Function that generates the value to be displayed in the tip.  By 
     117     *  default, the return from slider.getValue() is displayed. 
     118     */ 
     119    getText : function(slider) { 
     120        return slider.getValue(); 
     121    } 
     122}); 
  • lib/GeoExt/widgets/ZoomSlider.js

    old new  
     1/** 
     2 * Copyright (c) 2008 The Open Planning Project 
     3 */ 
     4 
     5/** 
     6 * @include GeoExt/widgets/tips/ZoomSliderTip.js 
     7 */ 
     8 
     9/** api: (define) 
     10 *  module = GeoExt 
     11 *  class = ZoomSlider 
     12 *  base_link = `Ext.Slider <http://extjs.com/deploy/dev/docs/?class=Ext.Slider>`_ 
     13 */ 
     14Ext.namespace("GeoExt"); 
     15 
     16/** api: example 
     17 *  Sample code to render a slider outside the map viewport: 
     18 *  
     19 *  .. code-block:: javascript 
     20 *      
     21 *      var slider = new GeoExt.ZoomSlider({ 
     22 *          renderTo: document.body, 
     23 *          width: 200, 
     24 *          map: map 
     25 *      }); 
     26 *      
     27 *  Sample code to add a slider to a map panel: 
     28 *  
     29 *  .. code-block:: javascript 
     30 *  
     31 *      var panel = new GeoExt.MapPanel({ 
     32 *          renderTo: document.body, 
     33 *          height: 300, 
     34 *          width: 400, 
     35 *          map: { 
     36 *              controls: [new OpenLayers.Control.Navigation()] 
     37 *          }, 
     38 *          layers: [new OpenLayers.Layer.WMS( 
     39 *              "Global Imagery", 
     40 *              "http://demo.opengeo.org/geoserver/wms", 
     41 *              {layers: "bluemarble"} 
     42 *          )], 
     43 *          extent: [-5, 35, 15, 55], 
     44 *          items: [{ 
     45 *              xtype: "gx_zoomslider", 
     46 *              vertical: true, 
     47 *              height: 100, 
     48 *              x: 10, 
     49 *              y: 20 
     50 *          }] 
     51 *      }); 
     52 */ 
     53 
     54/** api: constructor 
     55 *  .. class:: ZoomSlider(config) 
     56 *    
     57 *      Create a slider for controlling a map's zoom level. 
     58 */ 
     59GeoExt.ZoomSlider = Ext.extend(Ext.Slider, { 
     60     
     61    /** api: config[map] 
     62     *  ``OpenLayers.Map`` or :class:`GeoExt.MapPanel` 
     63     *  The map that the slider controls. 
     64     */ 
     65    map: null, 
     66     
     67    /** private: config[minValue] 
     68     *  ``Number`` 
     69     */ 
     70    minValue: null, 
     71     
     72    /** private: config[minValue] 
     73     *  ``Number`` 
     74     */ 
     75    maxValue: null, 
     76     
     77    /** api: config[baseCls] 
     78     *  ``String`` 
     79     *  The CSS class name for the slider elements.  Default is "gx-zoomslider". 
     80     */ 
     81    baseCls: "gx-zoomslider", 
     82     
     83    /** private: property[updating] 
     84     *  ``Boolean`` 
     85     *  The slider position is being updated by itself (based on map zoomend). 
     86     */ 
     87    updating: false, 
     88     
     89    /** private: method[initComponent] 
     90     *  Initialize the component. 
     91     */ 
     92    initComponent: function() { 
     93        GeoExt.ZoomSlider.superclass.initComponent.call(this); 
     94         
     95        if(this.map) { 
     96            if(this.map instanceof GeoExt.MapPanel) { 
     97                this.map = this.map.map; 
     98            } 
     99            this.bind(this.map); 
     100        } 
     101        this.on({ 
     102            "changecomplete": this.changeHandler, 
     103            "beforedestroy": this.unbind, 
     104            scope: this 
     105        }); 
     106         
     107    }, 
     108     
     109    /** private: method[onRender] 
     110     *  Override onRender to set base css class. 
     111     */ 
     112    onRender: function() { 
     113        GeoExt.ZoomSlider.superclass.onRender.apply(this, arguments); 
     114        this.el.addClass(this.baseCls); 
     115    }, 
     116 
     117    /** private: method[afterRender] 
     118     *  Override afterRender because the render event is fired too early 
     119     *  to call update. 
     120     */ 
     121    afterRender : function(){ 
     122        Ext.Slider.superclass.afterRender.apply(this, arguments); 
     123        this.update(); 
     124    }, 
     125     
     126    /** private: method[addToMapPanel] 
     127     *  :param panel: :class:`GeoExt.MapPanel` 
     128     *   
     129     *  Called by a MapPanel if this component is one of the items in the panel. 
     130     */ 
     131    addToMapPanel: function(panel) { 
     132        this.on({ 
     133            render: function() { 
     134                var el = this.getEl(); 
     135                el.setStyle({ 
     136                    position: "absolute", 
     137                    zIndex: panel.map.Z_INDEX_BASE.Control 
     138                }); 
     139                el.on({ 
     140                    mousedown: this.stopMouseEvents, 
     141                    click: this.stopMouseEvents 
     142                }); 
     143            }, 
     144            scope: this 
     145        }); 
     146        this.bind(panel.map); 
     147    }, 
     148     
     149    /** private: method[stopMouseEvents] 
     150     *  :param e: ``Object`` 
     151     */ 
     152    stopMouseEvents: function(e) { 
     153        e.stopEvent(); 
     154    }, 
     155     
     156    /** private: method[removeFromMap] 
     157     *  :param panel: :class:`GeoExt.MapPanel` 
     158     *   
     159     *  Called by a MapPanel if this component is one of the items in the panel. 
     160     */ 
     161    removeFromMapPanel: function(panel) { 
     162        var el = this.getEl(); 
     163        el.un("mousedown", this.stopMouseEvents, this); 
     164        el.un("click", this.stopMouseEvents, this); 
     165        this.unbind(); 
     166    }, 
     167     
     168    /** private: method[bind] 
     169     *  :param map: ``OpenLayers.Map`` 
     170     */ 
     171    bind: function(map) { 
     172        this.map = map; 
     173        this.map.events.on({ 
     174            zoomend: this.update, 
     175            changebaselayer: this.initZoomValues, 
     176            scope: this 
     177        }); 
     178        if(this.map.baseLayer) { 
     179            this.initZoomValues(); 
     180        } 
     181    }, 
     182     
     183    /** private: method[unbind] 
     184     */ 
     185    unbind: function() { 
     186        if(this.map) { 
     187            this.map.events.un({ 
     188                zoomend: this.update, 
     189                changebaselayer: this.initZoomValues, 
     190                scope: this 
     191            }); 
     192        } 
     193    }, 
     194     
     195    /** private: method[initZoomValues] 
     196     *  Set the min/max values for the slider if not set in the config. 
     197     */ 
     198    initZoomValues: function() { 
     199        var layer = this.map.baseLayer; 
     200        if(this.initialConfig.minValue === undefined) { 
     201            this.minValue = layer.minZoomLevel || 0; 
     202        } 
     203        if(this.initialConfig.maxValue === undefined) { 
     204            this.maxValue = layer.maxZoomLevel || layer.numZoomLevels - 1; 
     205        } 
     206    }, 
     207     
     208    /** api: method[getZoom] 
     209     *  :return: ``Number`` The map zoom level. 
     210     *   
     211     *  Get the zoom level for the associated map based on the slider value. 
     212     */ 
     213    getZoom: function() { 
     214        return this.getValue(); 
     215    }, 
     216     
     217    /** api: method[getScale] 
     218     *  :return: ``Number`` The map scale denominator. 
     219     *   
     220     *  Get the scale denominator for the associated map based on the slider value. 
     221     */ 
     222    getScale: function() { 
     223        return OpenLayers.Util.getScaleFromResolution( 
     224            this.map.getResolutionForZoom(this.getValue()), 
     225            this.map.getUnits() 
     226        ); 
     227    }, 
     228     
     229    /** api: method[getResolution] 
     230     *  :return: ``Number`` The map resolution. 
     231     *   
     232     *  Get the resolution for the associated map based on the slider value. 
     233     */ 
     234    getResolution: function() { 
     235        return this.map.getResolutionForZoom(this.getValue()); 
     236    }, 
     237     
     238    /** private: method[changeHandler] 
     239     *  Registered as a listener for slider changecomplete.  Zooms the map. 
     240     */ 
     241    changeHandler: function() { 
     242        if(this.map && !this.updating) { 
     243            this.map.zoomTo(this.getValue()); 
     244        } 
     245    }, 
     246     
     247    /** private: method[update] 
     248     *  Registered as a listener for map zoomend.  Updates the value of the slider. 
     249     */ 
     250    update: function() { 
     251        if(this.rendered && this.map) { 
     252            this.updating = true; 
     253            this.setValue(this.map.getZoom()); 
     254            this.updating = false; 
     255        } 
     256    } 
     257 
     258}); 
     259 
     260/** api: xtype = gx_zoomslider */ 
     261Ext.reg('gx_zoomslider', GeoExt.ZoomSlider); 
  • examples/zoomslider.html

    old new  
     1<html> 
     2    <head> 
     3        <title>GeoExt ZoomSlider</title> 
     4 
     5        <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.js"></script> 
     6        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" /> 
     7        <link rel="stylesheet" type="text/css" href="http://extjs.com/deploy/dev/examples/shared/examples.css"></link> 
     8        <script src="http://openlayers.org/api/2.8-rc2/OpenLayers.js"></script> 
     9        <script type="text/javascript" src="../lib/GeoExt.js"></script> 
     10 
     11        <script type="text/javascript" src="zoomslider.js"></script> 
     12    </head> 
     13    <body> 
     14        <h1>GeoExt.ZoomSlider</h1> 
     15        <p>The ZoomSlider allows control of the map scale using an Ext.Slider. 
     16        It is also possible to add a special tooltip plugin, ZoomSliderTip, which 
     17        will show the zoom level, scale and resolution while dragging the slider 
     18        (the content is configurable).<p> 
     19        <p>The js is not minified so it is readable. See <a href="zoomslider.js">zoomslider.js</a>.</p> 
     20        <div id="map-container"></div> 
     21    </body> 
     22</html> 
  • examples/zoomslider.js

    old new  
     1var panel, slider; 
     2 
     3Ext.onReady(function() { 
     4     
     5    // create a map panel with an embedded slider 
     6    panel = new GeoExt.MapPanel({ 
     7        title: "Map", 
     8        renderTo: "map-container", 
     9        height: 300, 
     10        width: 400, 
     11        map: { 
     12            controls: [new OpenLayers.Control.Navigation()] 
     13        }, 
     14        layers: [new OpenLayers.Layer.WMS( 
     15            "Global Imagery", 
     16            "http://demo.opengeo.org/geoserver/wms", 
     17            {layers: 'bluemarble'} 
     18        )], 
     19        extent: [-5, 35, 15, 55], 
     20        items: [{ 
     21            xtype: "gx_zoomslider", 
     22            vertical: true, 
     23            height: 100, 
     24            x: 10, 
     25            y: 20, 
     26            plugins: new GeoExt.ZoomSliderTip() 
     27        }] 
     28    }); 
     29     
     30    // create a separate slider bound to the map but displayed elsewhere 
     31    slider = new GeoExt.ZoomSlider({ 
     32        map: panel.map, 
     33        width: 200, 
     34        plugins: new GeoExt.ZoomSliderTip({ 
     35            template: "<div>Zoom Level: {zoom}</div>" 
     36        }), 
     37        renderTo: document.body 
     38    }); 
     39 
     40});