[Commits] r1461 - in sandbox/opengeo/style/geoext: examples lib/GeoExt/widgets

commits at geoext.org commits at geoext.org
Tue Nov 17 02:51:29 CET 2009


Author: tschaub
Date: 2009-11-17 02:51:29 +0100 (Tue, 17 Nov 2009)
New Revision: 1461

Added:
   sandbox/opengeo/style/geoext/examples/vector-legend.html
   sandbox/opengeo/style/geoext/examples/vector-legend.js
   sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendVector.js
Modified:
   sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendPanel.js
   sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendWMS.js
Log:
Applying patch for vector legend (#174).

Added: sandbox/opengeo/style/geoext/examples/vector-legend.html
===================================================================
--- sandbox/opengeo/style/geoext/examples/vector-legend.html	                        (rev 0)
+++ sandbox/opengeo/style/geoext/examples/vector-legend.html	2009-11-17 01:51:29 UTC (rev 1461)
@@ -0,0 +1,43 @@
+<html>
+    <head>
+        <title>GeoExt Vector Legend</title>
+
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+        <script src="../../openlayers/lib/OpenLayers.js"></script>
+        <!-- // <script src="http://openlayers.org/api/2.8/OpenLayers.js"></script> -->
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+        <script type="text/javascript" src="vector-legend.js"></script>
+        <style>
+            #wrapper {
+                position: relative;
+            }
+            #mappanel {
+                position: absolute;
+                top: 0px;
+                left: 0px;
+                width: 512px;
+                height: 256px;
+            }
+            #legend {
+                position: absolute;
+                top: 0px;
+                left: 550px;
+                height: 256px;
+                width: 150px;
+            }
+        </style>
+    </head>
+    <body>
+        <h1>GeoExt.LegendPanel with Vector Layers</h1>
+        <p>This example shows the how to create a legend for vector layers.<p>
+        <p>The js is not minified so it is readable. See <a href="vector-legend.js">vector-legend.js</a>.</p>
+        <div id="wrapper">
+            <div id="mappanel"></div>
+            <div id="legend"></div>
+        </div>
+    </body>
+</html>

Added: sandbox/opengeo/style/geoext/examples/vector-legend.js
===================================================================
--- sandbox/opengeo/style/geoext/examples/vector-legend.js	                        (rev 0)
+++ sandbox/opengeo/style/geoext/examples/vector-legend.js	2009-11-17 01:51:29 UTC (rev 1461)
@@ -0,0 +1,88 @@
+var mapPanel, legendPanel;
+
+Ext.onReady(function() {
+
+    var rules = [
+        new OpenLayers.Rule({
+            title: "> 2000m",
+            filter: new OpenLayers.Filter.Comparison({
+                type: OpenLayers.Filter.Comparison.GREATER_THAN,
+                property: "elevation",
+                value: 2000
+            }),
+            symbolizer: {
+                graphicName: "star",
+                pointRadius: 8,
+                fillColor: "#99ccff",
+                strokeColor: "#666666",
+                strokeWidth: 1
+            }
+        }),
+        new OpenLayers.Rule({
+            title: "1500 - 2000m",
+            filter: new OpenLayers.Filter.Comparison({
+                type: OpenLayers.Filter.Comparison.BETWEEN,
+                property: "elevation",
+                upperBoundary: 2000,
+                lowerBoundary: 1500
+            }),
+            symbolizer: {
+                graphicName: "star",
+                pointRadius: 6,
+                fillColor: "#6699cc",
+                strokeColor: "#666666",
+                strokeWidth: 1
+            }
+        }),
+        new OpenLayers.Rule({
+            title: "< 1500m",
+            filter: new OpenLayers.Filter.Comparison({
+                type: OpenLayers.Filter.Comparison.LESS_THAN,
+                property: "elevation",
+                value: 1500
+            }),
+            symbolizer: {
+                graphicName: "star",
+                pointRadius: 4,
+                fillColor: "#0033cc",
+                strokeColor: "#666666",
+                strokeWidth: 1
+            }
+        })
+    ];
+
+    var imagery = new OpenLayers.Layer.WMS(
+        "Imagery",
+        "http://maps.opengeo.org/geowebcache/service/wms",
+        {layers: "bluemarble"},
+        {displayInLayerSwitcher: false}
+    );
+
+    var summits = new OpenLayers.Layer.Vector("Summits", {
+        strategies: [new OpenLayers.Strategy.Fixed()],
+        protocol: new OpenLayers.Protocol.HTTP({
+            url: "data/summits.json",
+            format: new OpenLayers.Format.GeoJSON()
+        }),
+        styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({}, {rules: rules}))
+    });
+    
+    mapPanel = new GeoExt.MapPanel({
+        renderTo: "mappanel",
+        layers: [imagery, summits],
+        center: [6.3, 45.6],
+        zoom: 8
+    });
+    
+    // legendPanel = new GeoExt.LegendPanel({
+    //     renderTo: "legend",
+    //     map: mapPanel.map
+    // });
+    
+    legendPanel = new GeoExt.LegendPanel({
+        map: mapPanel.map,
+        renderTo: "legend",
+        border: false
+    });
+
+});

Modified: sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendPanel.js
===================================================================
--- sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendPanel.js	2009-11-17 01:48:14 UTC (rev 1460)
+++ sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendPanel.js	2009-11-17 01:51:29 UTC (rev 1461)
@@ -78,6 +78,13 @@
     filter: function(record) {
         return true;
     },
+    
+    /** private: property[legendTypes]
+     *  ``Array``
+     *  List of supported legend types.  These should be OpenLayers layer type
+     *  names.
+     */
+    legendTypes: ["WMS", "Vector"],
 
     /** private: method[initComponent]
      *  Initializes the legend panel.
@@ -123,10 +130,8 @@
         var legendCount = this.items ? this.items.length : 0;
         for(var i=count-1; i>=0; --i) {
             var layer = store.getAt(i).get("layer");
-            var legendGenerator = GeoExt[
-                "Legend" + layer.CLASS_NAME.split(".").pop()
-            ];
-            if(layer.displayInLayerSwitcher && legendGenerator &&
+            var LegendType = this.getLegendType(layer);
+            if(layer.displayInLayerSwitcher && LegendType &&
                 (store.getAt(i).get("hideInLegend") !== true)) {
                     ++panelIndex;
                     if(index === i || panelIndex > legendCount-1) {
@@ -229,11 +234,9 @@
                 legend = new GeoExt.LegendImage({url: record.get('legendURL')});
                 mainPanel.add(legend);
             } else {
-                var legendGenerator = GeoExt[
-                    "Legend" + layer.CLASS_NAME.split(".").pop()
-                ];
-                if (legendGenerator) {
-                    legend = new legendGenerator(Ext.applyIf({
+                var LegendType = this.getLegendType(layer);
+                if (LegendType) {
+                    legend = new LegendType(Ext.applyIf({
                         layer: layer,
                         record: record
                     }, this.legendOptions));
@@ -243,6 +246,25 @@
         }
         return mainPanel;
     },
+    
+    /** private: method[getLegendType]
+     *  :arg layer: ``OpenLayers.Layer``
+     *  :returns:  ``Function`` GeoExt legend constructor.
+     *
+     *  Find the first matching legend constructor for a layer.
+     */
+    getLegendType: function(layer) {
+        var type, LayerType, LegendType;
+        for (var i=0, ii=this.legendTypes.length; i<ii; ++i) {
+            type = this.legendTypes[i];
+            LayerType = OpenLayers.Layer[type];
+            if (LayerType && layer instanceof LayerType) {
+                LegendType = GeoExt["Legend" + type];
+                break;
+            }
+        }
+        return LegendType;
+    },
 
     /** private: method[addLegend]
      *  Add a legend for the layer.
@@ -274,11 +296,8 @@
     createMainPanel: function(record) {
         var layer = record.get('layer');
         var panel = null;
-        var legendGenerator = GeoExt[
-            "Legend" + layer.CLASS_NAME.split(".").pop()
-        ];
-        if (layer.displayInLayerSwitcher && !record.get('hideInLegend') &&
-            legendGenerator) {
+        var LegendType = this.getLegendType(layer);
+        if (LegendType && layer.displayInLayerSwitcher && !record.get('hideInLegend')) {
             var panelConfig = {
                 id: layer.id,
                 border: false,

Added: sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendVector.js
===================================================================
--- sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendVector.js	                        (rev 0)
+++ sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendVector.js	2009-11-17 01:51:29 UTC (rev 1461)
@@ -0,0 +1,551 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+/** api: (define)
+ *  module = GeoExt
+ *  class = LegendVector
+ *  base_link = `Ext.Panel <http://extjs.com/deploy/dev/docs/?class=Ext.Panel>`_
+ */
+
+Ext.namespace('GeoExt');
+
+/** api: constructor
+ *  .. class:: LegendVector(config)
+ *
+ *      Create a vector legend.
+ */
+GeoExt.LegendVector = Ext.extend(Ext.Panel, {
+
+    /** api: config[layer]
+     *  ``OpenLayers.Layer.Vector``
+     *  The vector layer to create the legend for.  One of ``layer``, ``record``,
+     *  or ``rules`` must be specified in the config.
+     */
+    layer: null,
+    
+    /** api: config[record]
+     *  ``Ext.data.Record``
+     *  Optional record containing the layer.  One of ``record``, ``layer``, 
+     *  or ``rules`` must be specified in the config.
+     */
+    record: null,
+
+    /** api: config[rules]
+     * ``Array(OpenLayers.Rule)``
+     *  List of rules.  One of ``rules``, ``layer``, or ``record`` must be
+     *  specified in the config.
+     */
+    rules: null,
+    
+    /** api: config[symbolType]
+     *  ``String``
+     *  The symbol type for legend swatches.  Must be one of ``"Point"``, 
+     *  ``"Line"``, or ``"Polygon"``.  If not provided, the ``layer``
+     *  or ``record`` config property must be specified, and the geometry type
+     *  of the first feature found on the layer will be used.
+     */
+    symbolType: null,
+
+    /** api: config[untitledPrefix]
+     *  ``String``
+     *  The prefix to use as a title for rules with no title or
+     *  name.  Default is ``"Untitled "``.  Prefix will be appended with a
+     *  number.
+     */
+    untitledPrefix: "Untitled ",
+    
+    /** api: config[clickableSymbol]
+     *  ``Boolean``
+     *  Set cursor style to "pointer" for symbolizers.  Register for
+     *  the ``symbolclick`` event to handle clicks.  Note that click events
+     *  are fired regardless of this value.  If ``false``, no cursor style will
+     *  be set.  Default is ``false``.
+     */
+    clickableSymbol: false,
+    
+    /** api: config[clickableTitle]
+     *  ``Boolean``
+     *  Set cursor style to "pointer" for rule titles.  Register for
+     *  the ``titleclick`` event to handle clicks.  Note that click events
+     *  are fired regardless of this value.  If ``false``, no cursor style will
+     *  be set.  Default is ``false``.
+     */
+    clickableTitle: false,
+    
+    /** api: config[selectOnClick]
+     *  ``Boolean``
+     *  Set to true if a rule should be selected by clicking on the
+     *  symbol or title. Selection will trigger the ruleselected event, and
+     *  a click on a selected rule will unselect it and trigger the
+     *  ``ruleunselected`` event. Default is ``false``.
+     */
+    selectOnClick: false,
+    
+    /** api: config[enableDD]
+     *  ``Boolean``
+     *  Allow drag and drop of rules. Default is ``false``.
+     */
+    enableDD: false,
+    
+    /** api: config[bodyBorder]
+     *  ``Boolean``
+     *  Show a border around the legend panel. Default is ``false``.
+     */
+    bodyBorder: false,
+
+    /** private: property[feature]
+     *  ``OpenLayers.Feature.Vector``
+     *  Cached feature for rendering.
+     */
+    feature: null,
+    
+    /** private: property[selectedRule]
+     *  ``OpenLayers.Rule``
+     *  The rule that is currently selected.
+     */
+    selectedRule: null,
+
+    /** private: property[currentScaleDenominator]
+     *  ``Number`` 
+     *  The current scale denominator of any map associated with this
+     *  legend.  Use :meth`setCurrentScaleDenominator` to change this.  If not
+     *  set an entry for each rule will be rendered.  If set, only rules that
+     *  apply for the given scale will be rendered.
+     */
+    currentScaleDenominator: null,
+    
+    /** private: property[untitledCount]
+     *  ``Number``
+     *  Last number used for untitled rule.
+     */
+    untitledCount: 0,
+    
+    /** private: method[initComponent]
+     *  Initializes the Vector legend.
+     */
+    initComponent: function() {
+        GeoExt.LegendVector.superclass.initComponent.call(this);
+        if (this.record) {
+            this.layer = this.record.get("layer");
+        }
+        
+        // determine symbol type
+        if (!this.symbolType) {
+            if (this.feature) {
+                this.symbolType = this.symbolTypeFromFeature(this.feature);
+            } else if (this.layer) {
+                if (this.layer.features.length > 0) {
+                    var feature = this.layer.features[0].clone();
+                    feature.attributes = {};
+                    this.feature = feature;
+                    this.symbolType = this.symbolTypeFromFeature(this.feature);
+                } else {
+                    this.layer.events.on({
+                        featuresadded: this.onFeaturesAdded,
+                        scope: this
+                    });
+                }
+            }
+        }
+        
+        // set rules if not provided
+        if (this.layer && this.feature && !this.rules) {
+            this.setRules();
+        }
+
+        this.rulesContainer = new Ext.Panel({
+            border: false
+        });
+        
+        this.items = [this.rulesContainer];
+        
+        this.addEvents(
+            /** api: event[titleclick]
+             *  Fires when a rule title is clicked.
+             *
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule whose title was clicked.
+             */
+            "titleclick", 
+
+            /** api: event[symbolclick]
+             *  Fires when a rule symbolizer is clicked.
+             *
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule whose symbol was clicked.
+             */
+            "symbolclick",
+
+            /** api: event[ruleclick]
+             *  Fires when a rule entry is clicked (fired with symbolizer or
+             *  title click).
+             *
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule that was clicked.
+             */
+            "ruleclick",
+            
+            /** api: event[ruleselected]
+             *  Fires when a rule is clicked and ``selectOnClick`` is set to 
+             *  ``true``.
+             * 
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule that was selected.
+             */
+            "ruleselected",
+            
+            /** api: event[ruleunselected]
+             *  Fires when the selected rule is clicked and ``selectOnClick`` 
+             *  is set to ``true``, or when a rule is unselected by selecting a
+             *  different one.
+             * 
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule that was unselected.
+             */
+            "ruleunselected",
+            
+            /** api: event[rulemoved]
+             *  Fires when a rule is moved.
+             * 
+             *  Listener arguments:
+             *  * comp - :class:`GeoExt.LegendVector`` This component.
+             *  * rule - ``OpenLayers.Rule`` The rule that was moved.
+             */
+            "rulemoved"
+        ); 
+        
+        GeoExt.LegendVector.superclass.initComponent.apply(this, arguments);
+        this.update();
+    },
+    
+    /** private: method[symbolTypeFromFeature]
+     *  :arg feature:  ``OpenLayers.Feature.Vector``
+     *
+     *  Determine the symbol type given a feature.
+     */
+    symbolTypeFromFeature: function(feature) {
+        var match = feature.geometry.CLASS_NAME.match(/Point|Line|Polygon/);
+        return (match && match[0]) || "Point";
+    },
+    
+    /** private: method[onFeaturesAdded]
+     *  Set as a one time listener for the ``featuresadded`` event on the layer
+     *  if it was provided with no features originally.
+     */
+    onFeaturesAdded: function() {
+        this.layer.events.un({
+            featuresadded: this.onFeaturesAdded,
+            scope: this
+        });
+        var feature = this.layer.features[0].clone();
+        feature.attributes = {};
+        this.feature = feature;
+        this.symbolType = this.symbolTypeFromFeature(this.feature);
+        if (!this.rules) {
+            this.setRules();
+        }
+        this.update();
+    },
+    
+    /** private: method[setRules]
+     *  Sets the ``rules`` property for this.  This is called when the component
+     *  is constructed without rules.  Rules will be derived from the layer's 
+     *  style map if it has one.
+     */
+    setRules: function() {
+        var style = this.layer.styleMap && this.layer.styleMap.styles["default"];
+        if (!style) {
+            style = new OpenLayers.Style();
+        }
+        if (style.rules.length === 0) {
+            this.rules = [
+                new OpenLayers.Rule({
+                    symbolizer: style.createSymbolizer(this.feature)
+                })
+            ];
+        } else {
+            this.rules = style.rules;                
+        }
+    },
+    
+    /** api: method[setCurrentScaleDenominator]
+     *  :arg scale: ``Number`` The scale denominator.
+     *
+     *  Set the current scale denominator.  This will hide entries for any
+     *  rules that don't apply at the current scale.
+     */
+    setCurrentScaleDenominator: function(scale) {
+        if (scale !== this.currentScaleDenominator) {
+            this.currentScaleDenominator = scale;
+            this.update();
+        }
+    },
+
+    /** private: method[getRuleEntry]
+     *  :arg rule: ``OpenLayers.Rule``
+     *  :returns: ``Ext.Container``
+     *
+     *  Get the item corresponding to the rule.
+     */
+    getRuleEntry: function(rule) {
+        return this.rulesContainer.items.get(this.rules.indexOf(rule));
+    },
+
+    /** private: method[addRuleEntry]
+     *  :arg rule: ``OpenLayers.Rule``
+     *  :arg noDoLayout: ``Boolean``  Don't call doLayout after adding rule.
+     *      Default is ``false``.
+     *
+     *  Add a new rule entry in the rules container. This
+     *  method does not add the rule to the rules array.
+     */
+    addRuleEntry: function(rule, noDoLayout) {
+        this.rulesContainer.add(this.createRuleEntry(rule));
+        if (!noDoLayout) {
+            this.doLayout();
+        }
+    },
+
+    /** private: method[removeRuleEntry]
+     *  :arg rule: ``OpenLayers.Rule``
+     *  :arg noDoLayout: ``Boolean``  Don't call doLayout after removing rule.
+     *      Default is ``false``.
+     *
+     *  Remove a rule entry from the rules container, this
+     *  method assumes the rule is in the rules array, and
+     *  it does not remove the rule from the rules array.
+     */
+    removeRuleEntry: function(rule, noDoLayout) {
+        var ruleEntry = this.getRuleEntry(rule);
+        if (ruleEntry) {
+            this.rulesContainer.remove(ruleEntry);
+            if (!noDoLayout) {
+                this.doLayout();
+            }
+        }
+    },
+    
+    /** private: method[selectRuleEntry]
+     */
+    selectRuleEntry: function(rule) {
+        var newSelection = rule != this.selectedRule;
+        if (this.selectedRule) {
+            this.unselect();
+        }
+        if (newSelection) {
+            var ruleEntry = this.getRuleEntry(rule);
+            ruleEntry.body.addClass("x-grid3-row-selected");
+            this.selectedRule = rule;
+            this.fireEvent("ruleselected", this, rule);
+        }
+    },
+    
+    /** private: method[unselect]
+     */
+    unselect: function() {
+        this.rulesContainer.items.each(function(item, i) {
+            if (this.rules[i] == this.selectedRule) {
+                item.body.removeClass("x-grid3-row-selected");
+                this.selectedRule = null;
+                this.fireEvent("ruleunselected", this, this.rules[i]);
+            }
+        }, this);
+    },
+
+    /** private: method[createRuleEntry]
+     */
+    createRuleEntry: function(rule) {
+        var applies = true;
+        if (this.currentScaleDenominator != null) {
+            if (rule.minScaleDenominator) {
+                applies = applies && (this.currentScaleDenominator >= rule.minScaleDenominator);
+            }
+            if (rule.maxScaleDenominator) {
+                applies = applies && (this.currentScaleDenominator < rule.maxScaleDenominator);
+            }
+        }
+        return {
+            xtype: "panel",
+            layout: "column",
+            border: false,
+            bodyStyle: this.selectOnClick ? {cursor: "pointer"} : undefined,
+            defaults: {
+                border: false
+            },
+            hidden: !applies, 
+            items: [
+                this.createRuleRenderer(rule),
+                this.createRuleTitle(rule)
+            ],
+            listeners: {
+                render: function(comp){
+                    this.selectOnClick && comp.getEl().on({
+                        click: function(comp){
+                            this.selectRuleEntry(rule);
+                        },
+                        scope: this
+                    });
+                    if (this.enableDD == true) {
+                        this.addDD(comp);
+                    }
+                },
+                scope: this
+            }
+        }
+    },
+
+    /** private: method[createRuleRenderer]
+     *  :arg rule: ``OpenLayers.Rule``
+     *  :returns: ``GeoExt.FeatureRenderer``
+     *
+     *  Create a renderer for the rule.
+     */
+    createRuleRenderer: function(rule) {
+        var symbolizer = rule.symbolizer;
+        if (symbolizer[this.symbolType]) {
+            symbolizer = symbolizer[this.symbolType];
+        }
+        return {
+            xtype: "gx_renderer",
+            symbolType: this.symbolType,
+            symbolizers: [symbolizer],
+            style: this.clickableSymbol ? {cursor: "pointer"} : undefined,
+            listeners: {
+                click: function() {
+                    if (this.clickableSymbol) {
+                        this.fireEvent("symbolclick", this, rule);
+                        this.fireEvent("ruleclick", this, rule);
+                    }
+                },
+                scope: this
+            }
+        };
+    },
+
+    /** private: method[createRuleTitle]
+     *  :arg rule: ``OpenLayers.Rule``
+     *  :returns: ``Ext.Component``
+     *
+     *  Create a title component for the rule.
+     */
+    createRuleTitle: function(rule) {
+        return {
+            cls: "x-form-item",
+            style: "padding: 0.2em 0.5em 0;", // TODO: css
+            bodyStyle: Ext.applyIf({background: "transparent"}, 
+                this.clickableTitle ? {cursor: "pointer"} : undefined),
+            html: this.getRuleTitle(rule),
+            listeners: {
+                render: function(comp) {
+                    this.clickableTitle && comp.getEl().on({
+                        click: function() {
+                            this.fireEvent("titleclick", this, rule);
+                            this.fireEvent("ruleclick", this, rule);
+                        },
+                        scope: this
+                    });
+                },
+                scope: this
+            }
+        };
+    },
+    
+    /** private: method[addDD]
+     *  :arg component: ``Ext.Component``
+     *
+     *  Adds drag & drop functionality to a rule entry.
+     */
+    addDD: function(component) {
+        var cursor = component.body.getStyle("cursor");
+        var dd = new Ext.Panel.DD(component);
+        // restore previous curser (if set). because Panel.DD always
+        // sets a move cursor
+        component.body.setStyle("cursor", cursor || "move");
+        var panel = this;
+        var dropZone = new Ext.dd.DropTarget(component.getEl(), {
+            notifyDrop: function(ddSource) {
+                var source = Ext.getCmp(ddSource.getEl().id);
+                var target = Ext.getCmp(this.getEl().id);
+                // sometimes, for whatever reason, Ext forgets who the source
+                // was, so we make sure that we have one before moving on
+                if (source && target && source != target) {
+                    var sourceCt = source.ownerCt;
+                    var targetCt = target.ownerCt;
+                    // only move rules around inside the same container
+                    if (sourceCt == targetCt) {
+                        panel.moveRule(
+                            sourceCt.items.indexOf(source),
+                            targetCt.items.indexOf(target)
+                        );
+                    }
+                }
+            }
+        });
+    },
+    
+    /** api: method[update]
+     *  Update rule titles and symbolizers.
+     */
+    update: function() {
+        if (this.symbolType && this.rules) {
+            if (this.rulesContainer.items) {
+                var comp;
+                for (var i=this.rulesContainer.items.length-1; i>=0; --i) {
+                    comp = this.rulesContainer.getComponent(i);
+                    this.rulesContainer.remove(comp, true);
+                }
+            }
+            for (var i=0, ii=this.rules.length; i<ii; ++i) {
+                this.addRuleEntry(this.rules[i], true);
+            }
+            this.doLayout();
+        }
+    },
+
+    /** private: method[updateRuleEntry]
+     *  :arg rule: ``OpenLayers.Rule``
+     *
+     *  Update the renderer and the title of a rule.
+     */
+    updateRuleEntry: function(rule) {
+        var ruleEntry = this.getRuleEntry(rule);
+        if (ruleEntry) {
+            ruleEntry.removeAll();
+            ruleEntry.add(this.createRuleRenderer(rule));
+            ruleEntry.add(this.createRuleTitle(rule));
+            ruleEntry.doLayout();
+        }
+    },
+    
+    /** private: method[moveRule]
+     */
+    moveRule: function(sourcePos, targetPos) {
+        var srcRule = this.rules[sourcePos];
+        this.rules.splice(sourcePos, 1);
+        this.rules.splice(targetPos, 0, srcRule);
+        this.update();
+        this.fireEvent("rulemoved", this, srcRule);
+    },
+    
+    /** private: method[getRuleTitle]
+     *  :returns: ``String``
+     *
+     *  Get a rule title given a rule.
+     */
+    getRuleTitle: function(rule) {
+        return rule.title || rule.name || (this.untitledPrefix + (++this.untitledCount));
+    }
+        
+});
+
+Ext.reg("gx_vectorlegend", GeoExt.LegendVector); 

Modified: sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendWMS.js
===================================================================
--- sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendWMS.js	2009-11-17 01:48:14 UTC (rev 1460)
+++ sandbox/opengeo/style/geoext/lib/GeoExt/widgets/LegendWMS.js	2009-11-17 01:51:29 UTC (rev 1461)
@@ -78,7 +78,7 @@
         }
         this.updateLegend();
     },
-
+    
     /** private: method[getLegendUrl]
      *  :param layerName: ``String`` A sublayer.
      *  :param layerNames: ``Array(String)`` The array of sublayers,



More information about the Commits mailing list