[Commits] r790 - in sandbox/opengeo/geoexplorer/lib/GeoExt: data widgets

commits at geoext.org commits at geoext.org
Fri May 15 22:52:26 CEST 2009


Author: tcoulter
Date: 2009-05-15 22:52:26 +0200 (Fri, 15 May 2009)
New Revision: 790

Modified:
   sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js
   sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/LegendPanel.js
Log:
Pulling in Bart's LegendPanel and LayerStore changes from tickets #2 and #66. This replaces the old LegendPanel used by GeoExplorer.

Modified: sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js
===================================================================
--- sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js	2009-05-15 20:40:38 UTC (rev 789)
+++ sandbox/opengeo/geoexplorer/lib/GeoExt/data/LayerStore.js	2009-05-15 20:52:26 UTC (rev 790)
@@ -208,7 +208,16 @@
                     }
                 }
             }
-        }
+        } else if (evt.property === "visibility") {
+            var layerIndex = this.map.getLayerIndex(layer);
+            var recordIndex = this.findBy(function(rec, id) {
+                return rec.get("layer") === layer;
+            });
+            if (recordIndex > -1) {
+                var record = this.getAt(recordIndex);
+                this.fireEvent("update", this, record, Ext.data.Record.EDIT);
+            }
+         }
     },
    
     /**

Modified: sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/LegendPanel.js
===================================================================
--- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/LegendPanel.js	2009-05-15 20:40:38 UTC (rev 789)
+++ sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/LegendPanel.js	2009-05-15 20:52:26 UTC (rev 790)
@@ -1,378 +1,275 @@
-/*
- * Copyright (C) 2008 Camptocamp, OpenGeo
+/* Copyright (C) 2008-2009 The Open Source Geospatial Foundation
+ * Published under the BSD license.
+ * See http://geoext.org/svn/geoext/core/trunk/license.txt for the full text
+ * of the license.
  *
- * This file is part of GeoExt
- *
- * GeoExt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GeoExt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GeoExt.  If not, see <http://www.gnu.org/licenses/>.
+ * pending approval */
+
+/** api: (define)
+ *  module = GeoExt
+ *  class = LegendPanel
  */
 
 Ext.namespace('GeoExt');
 
-/**
- * Class: GeoExt.LegendPanel
- *      LegendPanel is an Ext.Panel that displays a legend for all layers in a
- *      map. Currently the following layers are supported: 
- *      - {OpenLayers.Layer.WMS}
- *      In the future other layer types can be added.
+/** api: constructor
+ *  .. class:: LegendPanel(config)
  *
- * Inherits from:
- *  - {Ext.Panel}
+ *  A panel showing legends of all layers in a layer store.
+ *  Depending on the layer type, a legend renderer will be chosen.
  */
-
-/**
- * Constructor: GeoExt.LegendPanel
- * Create an instance of GeoExt.LegendPanel
- *
- * Parameters:
- * config - {Object} A config object used to set the legend
- *     panel's properties.
- *
- * Returns:
- * {<GeoExt.LegendPanel>}
- */
-
 GeoExt.LegendPanel = Ext.extend(Ext.Panel, {
-    /**
-     * APIProperty: wmsMode
-     * {Integer} should the legend component use SLD WMS GetLegendGraphic
-     *     requests or LegendURLs from the GetCapabilities reponse?
-     *     One of: GeoExt.LegendPanel.GETLEGENDGRAPHIC or 
-     *     GeoExt.LegendPanel.LEGENDURL. The LEGENDURL option requires
-     *     the OpenLayers.Format.WMSCapabilities parser. GETLEGENDGRAPHIC is
-     *     the default.
+
+    /** api: config[ascending]
+     *  ``Boolean``
+     *  If true the layers in the legend will show the bottom OpenLayers 
+     *  layer on top and the top OpenLayers layer on the bottom. 
+     *  If false, this is inverted. Default value is true.
      */
-    wmsMode: 0, // GeoExt.LegendPanel.GETLEGENDGRAPHIC,
+    ascending: true,
 
-    /**
-     * APIProperty: map
-     * {OpenLayers.Map}
+    /** api: config[autoUpdate]
+     *  ``Boolean``
+     *  If true the LegendPanel will listen to the add, remove and change 
+     *  events of the LayerStore. If false, it will load with the initial 
+     *  state of the LayerStore and not change anymore. 
      */
-    map: null,
+    autoUpdate: true,
+    
+    /** api: config[showTitle]
+     *  ``Boolean``
+     *  Whether or not to show the title of a layer. This can be a global
+     *  setting for the whole panel, or it can be overridden on the LayerStore 
+     *  record using the hideInLegend property.
+     */
+    showTitle: true,
 
-    /**
-     * APIProperty: labelCls
-     * {String} Additional css class to put on the legend labels
+    /** api: config[labelCls]
+     *  ``String``
+     *  Optional css class to use for the layer title labels.
      */
     labelCls: null,
 
-    /**
-     * APIProperty: wmsLegendFormat
-     * {String} the format to use in the GetLegendGraphic requests, defaults
-     *     to image/png. The value should be a valid mime-type.
+    /** api:config[bodyStyle]
+     *  ``String``
+     *  Optional style to apply to the body of the legend panels.
      */
-    wmsLegendFormat: "image/png",
+    bodyStyle: '',
 
-    /**
-     * APIProperty: ascending
-     * {Boolean} if true the layers in the tree will show the
-     *     bottom OpenLayer layer on top and the top OpenLayer layer on the
-     *     bottom. If false, this is inverted.
+    /** api: config[layerStore]
+     *  ``GeoExt.data.LayerStore``
+     *  The layer store containing layers to be displayed in the legend 
+     *  container. If not provided it will be taken from the MapPanel.
      */
-    ascending: true,
+    layerStore: null,
 
-    /**
-     * APIProperty: static
-     * {Boolean} if true the LegendPanel will not listen to the addlayer,
-     *     changelayer and removelayer events. So it will load with the initial
-     *     state of the map object and not change anymore.
+    /** private: method[initComponent]
+     *  Initializes the legend panel.
      */
-    static: false,
-
-    /**
-     * Property: idPrefix
-     * {String} the prefix to use for the id attribute value of the sub panels
-     *    (gxt for GeoExt and lp for LegendPanel)
-    */
-    idPrefix: 'gxt-lp-',
-
-    /**
-     * Method: initComponent
-     *      Initialize this component. We register for the events here.
-     */
     initComponent: function() {
-        if (!this.static) {
-            this.map.events.register("addlayer", this, this.addLayer);
-            this.map.events.register("changelayer", this, this.changeLayer);
-            this.map.events.register("removelayer", this, this.removeLayer);
-        }
         GeoExt.LegendPanel.superclass.initComponent.call(this);
     },
-
-    /**
-     * Method: onRender
-     *      This function is called when the component renders.
+    
+    /** private: method[onRender]
+     *  Private method called when the legend panel is being rendered.
      */
-    onRender: function(ct, position) {
-        GeoExt.LegendPanel.superclass.onRender.call(this, ct, position);
-        var layers = this.map.layers.slice();
-        if (!this.ascending) {
-            layers.reverse();
+    onRender: function() {
+        GeoExt.LegendPanel.superclass.onRender.apply(this, arguments);
+        if(!this.layerStore) {
+            this.layerStore = GeoExt.MapPanel.guess().layers;
         }
-        for (var i=0, len=layers.length; i<len; i++) {
-            var layer = layers[i];
-            this.createLegend(layer);
+        this.layerStore.each(this.addLegend, this);
+        if (this.autoUpdate) {
+            this.layerStore.on({
+                "add": this.onStoreAdd,
+                "move": this.onStoreMove,
+                "remove": this.onStoreRemove,
+                "update": this.onStoreUpdate,
+                scope: this
+            });
         }
+        this.doLayout();
     },
 
-    /**
-     * Method: onDestroy
-     *      This function is called when the component destroys. We deregister
-     *      the events here.
+    /** private: method[onStoreUpdate]
+     *  Update a layer within the legend panel. Gets called when the store
+     *  fires the update event. This usually means the visibility of the layer
+     *  has changed.
+     *
+     *  :param store: ``Ext.data.Store`` The store in which the record was
+     *      changed.
+     *  :param record: ``Ext.data.Record`` The record object corresponding
+     *      to the updated layer.
+     *  :param operation: ``String`` The type of operation.
      */
-    onDestroy: function() {
-        if (!this.static) {
-            this.map.events.unregister("addlayer", this, this.addLayer);
-            this.map.events.unregister("changelayer", this, this.changeLayer);
-            this.map.events.unregister("removelayer", this, this.removeLayer);
+    onStoreUpdate: function(store, record, operation) {
+        var layer = record.get('layer');
+        var legend = this.getComponent(layer.id);
+        if (legend) {
+            legend.setVisible(layer.getVisibility() && !record.get('hideInLegend'));
         }
-        GeoExt.LegendPanel.superclass.onDestroy.call(this);
     },
 
-    /**
-     * Method: addLayer
-     *      Internal function called on the addlayer event
+    /** private: method[onStoreMove]
+     *  Relocate a layer within the legend panel. Gets called when the store
+     *  fires the move event.
      *
-     * Parameters:
-     * evt - {Object} The event object sent by OpenLayers
+     *  :param store: ``Ext.data.Store`` The store in which the record was
+     *      moved.
+     *  :param record: ``Ext.data.Record`` The record object corresponding
+     *      to the moved layer.
+     *  :param from: ``Integer`` The previous index of the moved record.
+     *  :param to: ``Integer`` The new index of the moved record.
      */
-    addLayer: function(evt) {
-        this.createLegend(evt.layer);
+    onStoreMove: function(store, record, from, to) {
+        this.moveLegend(record, to);
     },
 
-    /**
-     * Method: removeLayer
-     *      Internal function called on the removelayer event
+    /** private: method[moveLegend]
+     *  Relocate a layer within the legend panel. Removes the existing panel
+     *  and then inserts it at the right index.
      *
-     * Parameters:
-     * evt - {Object} The event object sent by OpenLayers
+     *  :param record: ``Ext.data.Record`` The record object(s) corresponding
+     *      to the moved layer.
+     *  :param index: ``Integer`` The new index of the moved record.
      */
-    removeLayer: function(evt) {
-        if (evt.layer && evt.layer instanceof OpenLayers.Layer.WMS) {
-            this.remove(this.generatePanelId(evt.layer));
-        } 
+    moveLegend: function(record, index) {
+        var legend = this.getComponent(record.get('layer').id);
+        this.remove(legend);
+        var newLegend = this.createLegendSubpanel(record);
+        if (this.ascending) {
+            this.insert(index, newLegend); 
+        } else {
+            this.insert((this.items.length-index), newLegend);
+        }
+        this.doLayout(); 
     },
 
-    /**
-     * Method: changeLayer
-     *      Internal function called on the changelayer event
+    /** private: method[onStoreAdd]
+     *  Private method called when a layer is added to the store.
      *
-     * Parameters:
-     * evt - {Object} The event object sent by OpenLayers
+     *  :param store: ``Ext.data.Store`` The store to which the record(s) was 
+     *      added.
+     *  :param record: ``Ext.data.Record`` The record object(s) corresponding
+     *      to the added layers.
+     *  :param index: ``Integer`` The index of the inserted record.
      */
-    changeLayer: function(evt) {
-        // TODO deal with property order if we want to reflect the order
-        // in the legend
-        if (evt && evt.layer && evt.property) {
-            var panel = Ext.getCmp(this.generatePanelId(evt.layer));
-            if (!panel) {
-                panel = this.createLegend(evt.layer);
-            }
-            if (evt.property == 'visibility') {
-                if (panel) {
-                    panel.setVisible(evt.layer.getVisibility());
-                }
-            }
-            // it is possible for an application to hide layers from the legend
-            // by setting the hideInLegend property on the layer
-            // when the hideInLegend property changes, the application is
-            // responsible for triggering a changelayer event with a property
-            // named legendvisibility.
-            else if (evt.property == 'legendvisibility') {
-                if (panel) {
-                    panel.setVisible(!evt.layer.hideInLegend);
-                }
-            }else if(evt.property == 'order') {
-                var newPosition;
-                if(this.ascending){
-                    newPosition = this.map.getLayerIndex(evt.layer);
-                } else {
-                    newPosition = this.map.layers.length - 1
-                        - this.map.getLayerIndex(evt.layer);
-                }
-
-                this.moveLegend(panel, evt.layer, newPosition);
-            }
+    onStoreAdd: function(store, records, index) {
+        for (var i=0, len=records.length; i<len; i++) {
+            this.addLegend(records[i]);
         }
-    },
-
-    moveLegend: function(panel, layer, position){
-        this.remove(panel);
-        var newPanel = this.createLegendPanel(
-            this.generatePanelId(layer),
-            layer.name, 
-            this.generateImageGroup(layer)
-        );
-        this.insert(position, panel);
         this.doLayout();
     },
 
-    /**
-     * Method: generatePanelId
-     *     Generate an id attribute value for the panel.
-     *     It is assumed that the combination of layer.params.LAYER and
-     *     layer.mame is unique.
+    /** private: method[onStoreRemove]
+     *  Private method called when a layer is removed from the store.
      *
-     * Parameters:
-     * layer - {<OpenLayers.Layer.WMS>} the layer object
-     *
-     * Returns: 
-     * {String}
+     *  :param store: ``Ext.data.Store`` The store from which the record(s) was
+     *      removed.
+     *  :param record: ``Ext.data.Record`` The record object(s) corresponding
+     *      to the removed layers.
+     *  :param index: ``Integer`` The index of the removed record.
      */
-    generatePanelId: function(layer) {
-        return this.idPrefix + layer.params.LAYERS + layer.id;
+    onStoreRemove: function(store, record, index) {
+        this.removeLegend(record);
     },
 
-    /**
-     * Method: onImageLoadError
-     *     When the image fails loading (e.g. when the server returns an XML
-     *     exception) we need to set the src to a blank image otherwise IE
-     *     will show the infamous red cross.
+    /** private: method[removeLegend]
+     *  Remove the legend of a layer.
+     *  :param record: ``Ext.data.Record`` The record object from the layer 
+     *      store to remove.
      */
-    onImageLoadError: function() {
-        this.src = Ext.BLANK_IMAGE_URL;
+    removeLegend: function(record) {
+        var legend = this.getComponent(record.get('layer').id);
+        if (legend) {
+            legend.hide();
+            this.doLayout();
+        }
     },
 
-    /**
-     * Method: createLegendPanel
-     *     Create a panel for every layer, it will contain a Label with the
-     *     layer's name and for every possible sub layer an image
+    /** private: method[createLegendSubpanel]
+     *  Create a legend sub panel for the layer.
      *
-     * Parameters:
-     * id - {String} the unique id to use for the panel
-     * title - {String} the title of the layer
-     * legImg - {Object} the legend image object
+     *  :param record: ``Ext.data.Record`` The record object from the layer
+     *      store.
+     */
+    createLegendSubpanel: function(record) {
+        var layer = record.get('layer');
+        var mainPanel = this.createMainPanel(record);
+        // the default legend can be overridden by specifying a
+        // legendURL property
+        if (record.get('legendURL')) {
+            var legend = new GeoExt.legend.Image({url:
+                record.get('legendURL')});
+            mainPanel.add(legend);
+        } else {
+            var legendGenerator = GeoExt.legend[layer.CLASS_NAME.replace(
+                'OpenLayers.Layer.', '')];
+            if (legendGenerator) {
+                var legend = new legendGenerator({layer: layer});
+                mainPanel.add(legend);
+            }
+        }
+        return mainPanel;
+    },
+
+    /** private: method[addLegend]
+     *  Add a legend for the layer.
      *
-     * Returns:
-     * {<Ext.Panel>}
+     *  :param record: ``Ext.data.Record`` The record object from the layer 
+     *      store.
      */
-    createLegendPanel: function(id, title, legImg) {
-        // TODO: we probably need the ability to change the css class
-        // of the label
+    addLegend: function(record) {
+        var layer = record.get('layer');
+        // a layer can be excluded from the legend by setting the hideInLegend
+        // property to true
+        var hideInLegend = record.get('hideInLegend');
+        var legendSubpanel = this.createLegendSubpanel(record);
+        legendSubpanel.setVisible((layer && layer.getVisibility() && !hideInLegend));
+        if (this.ascending) {
+            this.add(legendSubpanel);
+        } else {
+            this.insert(0, legendSubpanel);
+        }
+    },
+
+    /** private: method[createMainPanel]
+     *  Creates the main panel with a title for the layer.
+     *
+     *  :param record: ``Ext.data.Record`` The record object from the layer
+     *      store.
+     */
+    createMainPanel: function(record) {
+        var layer = record.get('layer');
         var panelConfig = {
-            id: id,
+            id: layer.id,
+            border: false,
+            bodyBorder: false,
             bodyStyle: this.bodyStyle,
             items: [
                 new Ext.form.Label({
-                    text: title,
-                    cls: 'x-form-item x-form-item-label' + 
+                    text: (this.showTitle && !record.get('hideTitle')) ? 
+                        layer.name : '',
+                    cls: 'x-form-item x-form-item-label' +
                         (this.labelCls ? ' ' + this.labelCls : '')
                 })
             ]
         };
-
-        panelConfig = Ext.applyIf(panelConfig, this.childDefaults);
-
         var panel = new Ext.Panel(panelConfig);
-        for (var i=0, len=legImg.length; i<len; i++) {
-            panel.add(new Ext.BoxComponent({el: legImg[i]}));
-        }
         return panel;
     },
 
-    /**
-     * Method: getLegendUrl
-     *     Get the URL from which the legend image can be retrieved
-     *
-     * Parameters:
-     * layer - {<OpenLayers.Layer.WMS>} the WMS layer
-     * layerName - {String} one of the layers from the LAYERS parameter
-     *
-     * Returns:
-     * {String}
+    /** private: method[onDestroy]
+     *  Private method called during the destroy sequence.
      */
-    getLegendUrl: function(layer, layerName) {
-        if (this.wmsMode == GeoExt.LegendPanel.GETLEGENDGRAPHIC) {
-           return layer.getFullRequestString({
-                REQUEST: "GetLegendGraphic",
-                WIDTH: null,
-                HEIGHT: null,
-                EXCEPTIONS: "application/vnd.ogc.se_xml",
-                LAYER: layerName,
-                LAYERS: null,
-                SRS: null,
-                FORMAT: this.wmsLegendFormat
-            });
+    onDestroy: function() {
+        if(this.layerStore) {
+            this.layerStore.un("add", this.onStoreAdd, this);
+            this.layerStore.un("remove", this.onStoreRemove, this);
         }
-    },
-
-    /**
-     * Method: createImage
-     *     Create an image object for the legend image
-     *
-     * Parameters:
-     * src - {String} the source of the image (url)
-     * id - {String} the id (prefix) for the image object
-     *
-     * Returns:
-     * {DOMElement}
-     */
-    createImage: function(src, id) {
-        var legendImage = document.createElement("img");
-        Ext.EventManager.addListener(legendImage, 'error', 
-            this.onImageLoadError, legendImage);
-        legendImage.src = src;
-        legendImage.id = id+'_img';
-        return legendImage;
-    },
-
-    /**
-     * Method: createLegend
-     *     Create the legend panel for a layer
-     *
-     * Parameters:
-     * layer - {<OpenLayers.Layer>} the layer object
-     */
-    createLegend: function(layer) {
-        // currently only OpenLayers.Layer.WMS is supported and
-        // only for visible layers a legend is created.
-        // If an application does not want a layer in the legend
-        // they can set hideInLegend to true on the layer.
-        var panel;
-        if (layer instanceof OpenLayers.Layer.WMS && 
-            layer.getVisibility() && !layer.hideInLegend) {
-                panel = this.createLegendPanel(
-                    this.generatePanelId(layer),
-                    layer.name, 
-                    this.generateImageGroup(layer)
-                );
-
-                if (this.ascending) {
-                    this.add(panel);
-                } else {
-                    var idx = (this.map.layers.length-1)-this.map.getLayerIndex(layer);
-                    this.insert(idx, panel);
-                }
-                this.doLayout();
-        }
-        return panel;
-    },
-
-    generateImageGroup: function(layer) {
-        var layers = layer.params.LAYERS.split(",");
-        var legImg = [];
-        for (var i = 0, len = layers.length; i < len; i++){
-            var layerName = layers[i];
-            legImg.push(this.createImage(
-                this.getLegendUrl(layer, layerName),
-                this.generatePanelId(layer)+i
-            )); 
-        }
-        return legImg;
+        GeoExt.LegendPanel.superclass.onDestroy.apply(this, arguments);
     }
+    
 });
 
-GeoExt.LegendPanel.LEGENDURL = 1;
-GeoExt.LegendPanel.GETLEGENDGRAPHIC = 0;
-
-Ext.reg('gx_legend', GeoExt.LegendPanel);
+Ext.reg('gx_legend', GeoExt.LegendPanel);
\ No newline at end of file



More information about the Commits mailing list