[Commits] r831 - in sandbox/elemoine/playground/geoext: examples lib lib/GeoExt/data lib/GeoExt/widgets lib/GeoExt/widgets/tree resources/css tests tests/lib/GeoExt/data tests/lib/GeoExt/widgets tests/lib/GeoExt/widgets/tree

commits at geoext.org commits at geoext.org
Wed May 20 08:33:05 CEST 2009


Author: elemoine
Date: 2009-05-20 08:33:05 +0200 (Wed, 20 May 2009)
New Revision: 831

Added:
   sandbox/elemoine/playground/geoext/examples/layercontainer.html
   sandbox/elemoine/playground/geoext/examples/layercontainer.js
   sandbox/elemoine/playground/geoext/examples/tree.html
   sandbox/elemoine/playground/geoext/examples/tree.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js
   sandbox/elemoine/playground/geoext/resources/css/gxtheme-gray.css
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html
Removed:
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html
Modified:
   sandbox/elemoine/playground/geoext/lib/GeoExt.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/data/FeatureRecord.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerRecord.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerStore.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/MapPanel.js
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/Popup.js
   sandbox/elemoine/playground/geoext/resources/css/popup.css
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/FeatureRecord.html
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerRecord.html
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerStore.html
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/MapPanel.html
   sandbox/elemoine/playground/geoext/tests/list-tests.html
Log:
svn merge -r742:HEAD http://svn.geoext.org/core/trunk/geoext .


Copied: sandbox/elemoine/playground/geoext/examples/layercontainer.html (from rev 830, core/trunk/geoext/examples/layercontainer.html)
===================================================================
--- sandbox/elemoine/playground/geoext/examples/layercontainer.html	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/layercontainer.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,30 @@
+<html>
+    <head>
+        <title>GeoExt Layer Tree</title>
+
+        <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.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.com/deploy/dev/examples/shared/examples.css"></link>
+        <script src="http://openlayers.org/api/2.8-rc2/OpenLayers.js"></script>
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+        <script type="text/javascript" src="layercontainer.js"></script>
+
+    </head>
+    <body>
+        <h1>Layer Tree Example</h1>
+        <p>This is example that shows how create a TreePanel with layers
+        from a map.  GeoExt does not provide a LayerTree component.  Instead,
+        to create a tree with nodes that represent layers, create a tree with
+        a LayerContainer at the root, or add LayerNodes directly.</p>
+
+        <p>Note that the js is not minified so it is readable.
+        See <a href="layercontainer.js">layercontainer.js</a>.</p>
+
+        <div style="position: relative;">
+            <div id="capgrid"></div>
+            <div id="tree"></div>
+            <div id="mappanel"></div>
+        </div>
+    </body>
+</html>

Copied: sandbox/elemoine/playground/geoext/examples/layercontainer.js (from rev 830, core/trunk/geoext/examples/layercontainer.js)
===================================================================
--- sandbox/elemoine/playground/geoext/examples/layercontainer.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/layercontainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,74 @@
+var store, tree, panel;
+Ext.onReady(function() {
+    
+    // create a new WMS capabilities store
+    store = new GeoExt.data.WMSCapabilitiesStore({
+        url: "data/wmscap.xml"
+    });
+    // load the store with records derived from the doc at the above url
+    store.load();
+
+    // create a grid to display records from the store
+    var grid = new Ext.grid.GridPanel({
+        title: "WMS Capabilities",
+        store: store,
+        cm: new Ext.grid.ColumnModel([
+            {header: "Name", dataIndex: "name", sortable: true},
+            {id: "title", header: "Title", dataIndex: "title", sortable: true}
+        ]),
+        sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
+        autoExpandColumn: "title",
+        renderTo: "capgrid",
+        height: 300,
+        width: 350,
+        floating: true,
+        x: 10,
+        y: 0,
+        bbar: ["->", {
+            text: "Add Layer",
+            handler: function() {
+                var record = grid.getSelectionModel().getSelected();
+                if(record) {
+                    var copy = record.copy();
+                    copy.set("layer", record.get("layer"));
+                    copy.get("layer").mergeNewParams({
+                        format: "image/png",
+                        transparent: "true"
+                    });
+                    panel.layers.add(copy);
+                    panel.map.zoomToExtent(
+                        OpenLayers.Bounds.fromArray(copy.get("llbbox"))
+                    );
+                }
+            }
+        }]
+    });
+    
+    // create a map panel
+    panel = new GeoExt.MapPanel({
+        renderTo: "mappanel",
+        width: 350,
+        height: 300,
+        floating: true,
+        x: 570,
+        y: 0
+    });
+    
+    tree = new Ext.tree.TreePanel({
+        renderTo: "tree",
+        root: new GeoExt.tree.LayerContainer({
+            text: 'Map Layers',
+            layerStore: panel.layers,
+            leaf: false,
+            expanded: true
+        }),
+        enableDD: true,
+        width: 170,
+        height: 300,
+        floating: true,
+        x: 380,
+        y: 0
+    });
+    
+
+});

Copied: sandbox/elemoine/playground/geoext/examples/tree.html (from rev 830, core/trunk/geoext/examples/tree.html)
===================================================================
--- sandbox/elemoine/playground/geoext/examples/tree.html	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/tree.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,27 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>GeoExt Tree Components</title>
+        
+        <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.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.com/deploy/dev/examples/shared/examples.css"></link>
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+        <script src="http://openlayers.org/api/2.8-rc2/OpenLayers.js"></script>
+
+        <script type="text/javascript" src="tree.js"></script>
+
+    </head>
+    <body>
+        <div id="desc">
+            <h1>GeoExt.tree Components</h1>
+            <p>This example shows how to work with layer tree.  The basic
+            component for building layer trees is the LayerNode, and there are
+            differnt types of containers for automatically adding a map's
+            layers to the tree. The tree configuration of this example is pure
+            JSON and can be edited live by clicking on the "Show/Edit Tree Config"
+            button below the layers panel.<p>
+            <p>The js is not minified so it is readable. See
+            <a href="tree.js">tree.js</a>.</p>
+        </div>
+    </body>
+</html>
\ No newline at end of file

Copied: sandbox/elemoine/playground/geoext/examples/tree.js (from rev 830, core/trunk/geoext/examples/tree.js)
===================================================================
--- sandbox/elemoine/playground/geoext/examples/tree.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/tree.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,175 @@
+var mapPanel;
+Ext.onReady(function() {
+    // using OpenLayers.Format.JSON to create a nice formatted string of the
+    // configuration for editing it in the UI
+    var treeConfig = new OpenLayers.Format.JSON().write([{
+        nodeType: "gx_baselayercontainer"
+    }, {
+        nodeType: "gx_overlaylayercontainer",
+        // render the nodes inside this container with a radio button,
+        // and assign them the group "foo"
+        defaults: {
+            radioGroup: "foo"
+        }
+    }, {
+        nodeType: "gx_layer",
+        layer: "Tasmania Roads"
+    }], true);
+
+    mapPanel = new GeoExt.MapPanel({
+        border: true,
+        region: "center",
+        // we do not want all overlays, to try the OverlayLayerContainer
+        map: new OpenLayers.Map({allOverlays: false}),
+        center: [146.1569825, -41.6109735],
+        zoom: 6,
+        layers: [
+            new OpenLayers.Layer.WMS("Blue Marble",
+                "http://sigma.openplans.org/geoserver/wms", {
+                    layers: "bluemarble"
+                }, {
+                    buffer: 0,
+                    visibility: false
+                }),
+            new OpenLayers.Layer.WMS("Tasmania State Boundaries",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_state_boundaries"
+                }, {
+                    buffer: 0
+               }),
+            new OpenLayers.Layer.WMS("Water",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_water_bodies",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    isBaseLayer: false,
+                    buffer: 0
+                }),
+            new OpenLayers.Layer.WMS("Cities",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_cities",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    isBaseLayer: false,
+                    buffer: 0
+                }),
+            new OpenLayers.Layer.WMS("Tasmania Roads",
+                "http://demo.opengeo.org/geoserver/wms", {
+                    layers: "topp:tasmania_roads",
+                    transparent: true,
+                    format: "image/gif"
+                }, {
+                    isBaseLayer: false,
+                    buffer: 0,
+                    // exclude this layer from layer container nodes
+                    displayInLayerSwitcher: false
+                })
+        ]
+    });
+    
+    // dialog for editing the tree configuration
+    var treeConfigWin = new Ext.Window({
+        layout: "fit",
+        hideBorders: true,
+        closeAction: "hide",
+        width: 300,
+        height: 400,
+        title: "Tree Configuration",
+        items: [{
+            xtype: "form",
+            layout: "fit",
+            items: [{
+                id: "treeconfig",
+                xtype: "textarea"
+            }],
+            buttons: [{
+                text: "Save",
+                handler: function() {
+                    var value = Ext.getCmp("treeconfig").getValue()
+                    try {
+                        var root = tree.getRootNode();
+                        root.attributes.children = Ext.decode(value);
+                        tree.getLoader().load(root);
+                    } catch(e) {
+                        alert("Invalid JSON");
+                        return;
+                    }
+                    treeConfig = value;
+                    treeConfigWin.hide();
+                }
+            }, {
+                text: "Cancel",
+                handler: function() {
+                    treeConfigWin.hide();
+                }
+            }]
+        }]
+    });
+    
+    var toolbar = new Ext.Toolbar({
+        items: [{
+            text: "Show/Edit Tree Config",
+            handler: function() {
+                treeConfigWin.show();
+                Ext.getCmp("treeconfig").setValue(treeConfig);
+            }
+        }]
+    });
+    
+    var tree = new Ext.tree.TreePanel({
+        border: true,
+        region: "west",
+        title: "Layers",
+        width: 200,
+        split: true,
+        collapsible: true,
+        collapseMode: "mini",
+        autoScroll: true,
+        loader: new Ext.tree.TreeLoader({
+            clearOnLoad: true
+        }),
+        root: {
+            nodeType: "async",
+            children: Ext.decode(treeConfig)
+        },
+        rootVisible: false,
+        lines: false,
+        bbar: toolbar
+    });
+    
+    // the layer node's radio button with its radiochange event can be used
+    // to set an active layer.
+    var registerRadio = function(node){
+        if(!node.hasListener("radiochange")) {
+            node.on("radiochange", function(node){
+                alert(node.layer.name + " is now the the active layer.");
+            });
+        }
+    }
+    tree.on({
+        "insert": registerRadio,
+        "append": registerRadio,
+        scope: this
+    });
+    
+    new Ext.Viewport({
+        layout: "fit",
+        hideBorders: true,
+        items: {
+            layout: "border",
+            deferredRender: false,
+            items: [mapPanel, tree, {
+                contentEl: "desc",
+                region: "east",
+                bodyStyle: {"padding": "5px"},
+                collapsible: true,
+                collapseMode: "mini",
+                split: true,
+                width: 200,
+                title: "Description"
+            }]
+        }
+    });
+});

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/data/FeatureRecord.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/data/FeatureRecord.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/data/FeatureRecord.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -28,24 +28,6 @@
 ]);
 
 /**
- * APIMethod: copy
- * Creates a copy of this Record.
- * 
- * Paremters:
- * id - {String} (optional) A new Record id.
- *
- * Returns:
- * {GeoExt.data.LayerRecord} A new layer record.
- */
-GeoExt.data.FeatureRecord.prototype.copy = function(id) {
-    var feature = this.get("feature") && this.get("feature").clone();
-    return new this.constructor(
-        Ext.applyIf({feature: feature}, this.data),
-        id || this.id
-    );
-};
-
-/**
  * APIFunction: GeoExt.data.FeatureRecord.create
  * Creates a constructor for a FeatureRecord, optionally with additional
  * fields.

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerRecord.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerRecord.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerRecord.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -30,24 +30,6 @@
 ]);
 
 /**
- * APIMethod: copy
- * Creates a copy of this Record.
- * 
- * Paremters:
- * id - {String} (optional) A new Record id.
- *
- * Returns:
- * {GeoExt.data.LayerRecord} A new layer record.
- */
-GeoExt.data.LayerRecord.prototype.copy = function(id) {
-    var layer = this.get("layer") && this.get("layer").clone();
-    return new this.constructor(
-        Ext.applyIf({layer: layer}, this.data),
-        id || this.id
-    );
-};
-
-/**
  * APIFunction: GeoExt.data.LayerRecord.create
  * Creates a constructor for a LayerRecord, optionally with additional
  * fields.

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerStore.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerStore.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/data/LayerStore.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -151,6 +151,10 @@
             "remove": this.onRemove,
             scope: this
         });
+        this.data.on({
+            "replace" : this.onReplace,
+            scope: this
+        });
     },
 
     /**
@@ -170,6 +174,8 @@
             this.un("add", this.onAdd, this);
             this.un("remove", this.onRemove, this);
 
+            this.data.un("replace", this.onReplace, this);
+
             this.map = null;
         }
     },
@@ -324,10 +330,34 @@
             var layer = record.get("layer");
             if (this.map.getLayer(layer.id) != null) {
                 this._removing = true;
-                this.map.removeLayer(record.get("layer"));
+                this.removeMapLayer(record);
                 delete this._removing;
             }
         }
+    },
+
+    /**
+     * Method: removeMapLayers
+     * Removes a record's layer from the bound map.
+     * 
+     * Parameters:
+     * record - {<Ext.data.Record>}
+     */
+    removeMapLayer: function(record){
+        this.map.removeLayer(record.get("layer"));
+    },
+
+    /**
+     * Method: onReplace
+     * Handler for a store's data collections' replace event
+     * 
+     * Parameters:
+     * key - {String}
+     * oldRecord - {Object} In this case, a record that has been replaced.
+     * newRecord - {Object} In this case, a record that is replacing oldRecord.
+     */
+    onReplace: function(key, oldRecord, newRecord){
+        this.removeMapLayer(oldRecord);
     }
 };
 

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/MapPanel.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/MapPanel.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/MapPanel.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -182,5 +182,20 @@
     
 });
 
+/** api: function[guess]
+ *  :return: ``GeoExt.MapPanel`` The first map panel found by the Ext
+ *      component manager.
+ *  
+ *  Convenience function for guessing the map panel of an application. This
+ *     can reliably be used for all applications that just have one map panel
+ *     in the viewport.
+ */
+GeoExt.MapPanel.guess = function() {
+    return Ext.ComponentMgr.all.find(function(o) { 
+        return o instanceof GeoExt.MapPanel; 
+    }); 
+};
+
+
 /** api: xtype = gx_mappanel */
 Ext.reg('gx_mappanel', GeoExt.MapPanel); 

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/Popup.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/Popup.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/Popup.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,120 +1,112 @@
-Ext.namespace("GeoExt.popup");
-/**
- * Class: GeoExt.Popup
- * Popups are a specialized Window that supports anchoring
- *     to a particular feature in a MapPanel.  When a popup
- *     is anchored to a feature, that means that the popup
- *     will visibly point to the feature on the map, and move
- *     accordingly when the map is panned or zoomed.
- *
- * Usage example:
- * (start code)
- *
- * var popup = new GeoExt.Popup({
- *   title: 'My Popup',
- *   feature: feature,
- *   width: 200,
- *   html: "<div>Popup content</div>",
- *   collapsible: true
- * })
- *
- * (end)
- *
- * Inherits from:
- * - {Ext.Window}
+/* Copyright (C) 2008-2009 The Open Source Geospatial Foundation [1]
+ * Published under the BSD license.
+ * See http://geoext.org/svn/geoext/core/trunk/license.txt for the full text
+ * of the license.
+ * 
+ * [1] pending approval
  */
 
-/**
- * Constructor: GeoExt.Popup
+/** api: (define)
+ *  module = GeoExt
+ *  class = Popup
+ *  base_link = `Ext.Window <http://extjs.com/deploy/dev/docs/?class=Ext.Window>`_
+ */
+Ext.namespace("GeoExt");
+
+/** api: example
+ *  Sample code to create a popup anchored to a feature:
  * 
- * Parameters:
- * config - {Object} A config object. In addition to the config options
- *     of its parent class, this object can receive specific options,
- *     see the API properties to know about these specific options.
+ *  .. code-block:: javascript
+ *     
+ *      var popup = new GeoExt.Popup({
+ *          title: "My Popup",
+ *          feature: feature,
+ *          width: 200,
+ *          html: "<div>Popup content</div>",
+ *          collapsible: true
+ *      });
  */
+
+/** api: constructor
+ *  .. class:: Popup(config)
+ *   
+ *      Popups are a specialized Window that supports anchoring
+ *      to a particular feature in a MapPanel.  When a popup
+ *      is anchored to a feature, that means that the popup
+ *      will visibly point to the feature on the map, and move
+ *      accordingly when the map is panned or zoomed.
+ */
 GeoExt.Popup = Ext.extend(Ext.Window, {
 
-    /**
-     * APIProperty: anchored
-     * {Boolean} True if this popup begins anchored to
-     * its feature.  Defaults to true.
+    /** api: config[anchored]
+     *  ``Boolean``  The popup begins anchored to its feature.  Default is
+     *  ``true``.
      */
     anchored: true,
 
-    /**
-     * APIProperty: panIn
-     * {Boolean} True if the popup should pan the map so
-     * that the popup is fully in view when it is rendered.  Default is true.
+    /** api: config[panIn]
+     *  ``Boolean`` The popup should pan the map so that the popup is
+     *  fully in view when it is rendered.  Default is ``true``.
      */
     panIn: true,
 
-    /**
-     * APIProperty: unpinnable
-     * {Boolean} True if the popup should have a
-     * "unpin" tool that unanchors it from its feature.
-     * Default is true.
+    /** api: config[unpinnable]
+     *  ``Boolean`` The popup should have a "unpin" tool that unanchors it from
+     *  its feature.  Default is ``true``.
      */
     unpinnable: true,
 
-    /**
-     * APIProperty: feature
-     * {OpenLayers.Feature} An OpenLayers feature that is this
-     * popup's anchor. Either this or <lonlat> has to be provided.
+    /** api: config[feature]
+     *  ``OpenLayers.Feature`` A location for this popup's anchor.  One of
+     *  ``feature`` or ``lonlat`` must be provided.
      */
     feature: null,
 
-    /**
-     * APIProperty: lonlat
-     * {OpenLayers.LonLat} An OpenLayers lonlat from which an
-     * anchor feature's geometry is made if no feature is provided.
+    /** api: config[lonlat]
+     *  ``OpenLayers.LonLat`` A location for this popup's anchor.  One of
+     *  ``feature`` or ``lonlat`` must be provided.
      */
     lonlat: null,
 
-    /*
+    /**
      * Some Ext.Window defaults need to be overriden here
      * because some Ext.Window behavior is not currently supported.
      */    
 
-    /**
-     * Property: animCollapse
-     * {Boolean} True to animate the transition when the panel is 
-     * collapsed, false to skip the animation.
-     * Collapsing animation is not supported yet for popups.
+    /** private: config[animCollapse]
+     *  ``Boolean`` Animate the transition when the panel is collapsed.
+     *  Default is ``false``.  Collapsing animation is not supported yet for
+     *  popups.
      */
     animCollapse: false,
 
-    /**
-     * Property: draggable
-     * {Boolean} True to enable dragging of this Panel.
-     * Defaults to false because the popup defaults to being
-     * anchored, and anchored popups should not be draggable.
+    /** private: config[draggable]
+     *  ``Boolean`` Enable dragging of this Panel.  Defaults to ``false``
+     *  because the popup defaults to being anchored, and anchored popups
+     *  should not be draggable.
      */
     draggable: false,
 
-    /**
-     * Property: shadow
-     * {Boolean} True to give the popup window a shadow.
-     * Defaults to false because shadows are not supported 
-     * yet for popups (the shadow does not look good with 
-     * the anchor).
+    /** private: config[shadow]
+     *  ``Boolean`` Give the popup window a shadow.  Defaults to ``false``
+     *  because shadows are not supported yet for popups (the shadow does
+     *  not look good with the anchor).
      */
     shadow: false,
 
-    /**
-     * Property: popupCls
-     * {String} CSS class name for the popup DOM elements.
+    /** api: config[popupCls]
+     *  ``String`` CSS class name for the popup DOM elements.  Default is
+     *  "gx-popup".
      */
     popupCls: "gx-popup",
 
-    /**
-     * Property: ancCls
-     * {String} CSS class name for the popup's anchor.
+    /** api: config[ancCls
+     *  ``String``  CSS class name for the popup's anchor.
      */
     ancCls: null,
 
-    /**
-     * Method: initComponent
-     *     Initializes the popup.
+    /** private: method[initComponent]
+     *  Initializes the popup.
      */
     initComponent: function() {        
         if (!this.feature && this.lonlat) {
@@ -128,9 +120,8 @@
         GeoExt.Popup.superclass.initComponent.call(this);
     },
 
-    /**
-     * Method: onRender
-     *     Executes when the popup is rendered.
+    /** private: method[onRender]
+     *  Executes when the popup is rendered.
      */
     onRender: function(ct, position) {
         GeoExt.Popup.superclass.onRender.call(this, ct, position);
@@ -140,10 +131,9 @@
         this.createElement("anc", this.el);
     },
 
-    /**
-     * Method: initTools
-     *     Initializes the tools on the popup.  In particular,
-     *     it adds the 'unpin' tool if the popup is unpinnable.
+    /** private: method[initTools]
+     *  Initializes the tools on the popup.  In particular,
+     *  it adds the 'unpin' tool if the popup is unpinnable.
      */
     initTools : function() {
         if(this.unpinnable) {
@@ -156,15 +146,13 @@
         GeoExt.Popup.superclass.initTools.call(this);
     },
 
-    /**
-     * APIMethod: addToMapPanel
-     *      Adds this popup to a MapPanel.  Assumes that the
-     *      MapPanel's map is already initialized and that the
-     *      Popup's feature is on the map.
-     * 
-     * Parameters:
-     * mapPanel - {<GeoExt.MapPanel>} a MapPanel to which to
-     *     add this popup.
+    /** api: method[addToMapPanel]
+     *  :param mapPanel: :class:`MapPanel` The panel to which this popup should
+     *      be added.
+     *  
+     *  Adds this popup to a :class:`MapPanel`.  Assumes that the
+     *  MapPanel's map is already initialized and that the
+     *  Popup's feature is on the map.
      */
     addToMapPanel: function(mapPanel) {
         this.mapPanel = mapPanel;
@@ -188,14 +176,11 @@
         }
     },
 
-    /**
-     * Method: setSize
-     *     Sets the size of the popup, taking into account
-     *     the size of the anchor.
-     *     
-     * Parameters:
-     * w - {Integer}
-     * h - {Integer}
+    /** api: method[setSize]
+     *  :param w: ``Integer``
+     *  :param h: ``Integer``
+     *  
+     *  Sets the size of the popup, taking into account the size of the anchor.
      */
     setSize: function(w, h) {
         if(this.anc) {
@@ -210,9 +195,8 @@
         GeoExt.Popup.superclass.setSize.call(this, w, h);
     },
 
-    /**
-     * Method: position
-     *     Positions the popup relative to its feature
+    /** private: method[position]
+     *  Positions the popup relative to its feature
      */
     position: function() {
         var centerLonLat = this.feature.geometry.getBounds().getCenterLonLat();
@@ -233,12 +217,8 @@
         this.setPosition(centerPx.x - dx, centerPx.y - dy);
     },
 
-    /**
-     * Method: getAnchorElement
-     *     Returns the anchor element of the popup
-     *
-     * Returns:
-     * {Ext.Element}
+    /** private: method[getAnchorElement]
+     *  :returns: ``Ext.Element``  The anchor element of the popup.
      */
     getAnchorElement: function() {
         var anchorSelector = "div." + this.ancCls;
@@ -246,11 +226,9 @@
         return anc;
     },
 
-    /**
-     * Method: anchorPopup
-     *     Anchors a popup to its feature
-     *     by registering listeners that reposition the popup
-     *     when the map is moved.
+    /** private: method[anchorPopup]
+     *  Anchors a popup to its feature by registering listeners that reposition
+     *  the popup when the map is moved.
      */
     anchorPopup: function() {
         this.map.events.on({
@@ -266,11 +244,9 @@
         });
     },
 
-    /**
-     * APIMethod: unanchorPopup
-     *     Unanchors a popup from its feature.
-     *     Currently, this removes the popup from its MapPanel
-     *     and adds it to the page body.
+    /** private: method[unanchorPopup]
+     *  Unanchors a popup from its feature.  This removes the popup from its
+     *  MapPanel and adds it to the page body.
      */
     unanchorPopup: function() {
         this.unbindFromMapPanel();
@@ -308,9 +284,8 @@
         }
     },
 
-    /** Method: unbindFromMapPanel
-     *      Utility method for unbinding events that call for
-     *      popup repositioning.
+    /** private: method[unbindFromMapPanel]
+     *  Utility method for unbinding events that call for popup repositioning.
      */
     unbindFromMapPanel: function() {
         //stop position with feature
@@ -324,11 +299,10 @@
         this.un("expand", this.position);
     },
 
-    /**
-     *  APIMethod: panIntoView
-     *      Pans the MapPanel's map so that an anchored popup
-     *      can come entirely into view, with padding specified
-     *      as per normal OpenLayers.Map popup padding.
+    /** private: method[panIntoView]
+     *  Pans the MapPanel's map so that an anchored popup can come entirely
+     *  into view, with padding specified as per normal OpenLayers.Map popup
+     *  padding.
      */ 
     panIntoView: function() {
         if(!this.anchored) {
@@ -374,9 +348,8 @@
         this.map.pan(dx, dy);
     },
 
-    /**
-     * Method: beforeDestroy
-     *     Cleanup events before destroying the popup.
+    /** private: method[beforeDestroy]
+     *  Cleanup events before destroying the popup.
      */
     beforeDestroy: function() {
         this.unbindFromMapPanel();
@@ -384,4 +357,5 @@
     }
 });
 
+/** api: xtype = gx_mappanel */
 Ext.reg('gx_popup', GeoExt.Popup); 

Copied: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree (from rev 830, core/trunk/geoext/lib/GeoExt/widgets/tree)

Deleted: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,69 +0,0 @@
-/**
- * Copyright (c) 2008 The Open Planning Project
- */
-
-/**
- * @requires GeoExt/widgets/tree/LayerContainer.js
- */
-Ext.namespace("GeoExt.tree");
-
-/**
- * Class: GeoExt.tree.BaseLayerContainer
- * 
- * A layer container that will collect all base layers of an OpenLayers map.
- * Only layers that have displayInLayerSwitcher set to true will be included.
- * 
- * To use this node type in JSON config, set nodeType to
- * "olBaseLayerContainer".
- * 
- * Inherits from:
- * - <GeoExt.tree.LayerContainer>
- */
-GeoExt.tree.BaseLayerContainer = Ext.extend(GeoExt.tree.LayerContainer, {
-
-    /**
-     * Constructor: GeoExt.tree.BaseLayerContainer
-     * 
-     * Parameters:
-     * config - {Object}
-     */
-    constructor: function(config) {
-        config.text = config.text || "Base Layer";
-        GeoExt.tree.BaseLayerContainer.superclass.constructor.apply(this, arguments);
-    },
-
-    /**
-     * Method: addLayerNode
-     * Adds a child node representing a base layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to add a node for
-     */
-    addLayerNode: function(layerRecord) {
-        var layer = layerRecord.get("layer");
-        if (layer.isBaseLayer == true) {
-            GeoExt.tree.BaseLayerContainer.superclass.addLayerNode.call(this,
-                layerRecord);
-        }
-    },
-    
-    /**
-     * Method: removeLayerNode
-     * Removes a child node representing a base layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to remove the node for
-     */
-    removeLayerNode: function(layerRecord) {
-        var layer = layerRecord.get("layer");
-        if (layer.isBaseLayer == true) {
-            GeoExt.tree.BaseLayerContainer.superclass.removeLayerNode.call(this,
-                layerRecord);
-    	}
-    }
-});
-
-/**
- * NodeType: gx_baselayercontainer
- */
-Ext.tree.TreePanel.nodeTypes.gx_baselayercontainer = GeoExt.tree.BaseLayerContainer;

Copied: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js (from rev 830, core/trunk/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js)
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/BaseLayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2008 The Open Planning Project
+ */
+
+/**
+ * @requires GeoExt/widgets/tree/LayerContainer.js
+ */
+Ext.namespace("GeoExt.tree");
+
+/**
+ * Class: GeoExt.tree.BaseLayerContainer
+ * 
+ * A layer container that will collect all base layers of an OpenLayers map.
+ * Only layers that have displayInLayerSwitcher set to true will be included.
+ * 
+ * To use this node type in JSON config, set nodeType to
+ * "olBaseLayerContainer".
+ * 
+ * Inherits from:
+ * - <GeoExt.tree.LayerContainer>
+ */
+GeoExt.tree.BaseLayerContainer = Ext.extend(GeoExt.tree.LayerContainer, {
+
+    /**
+     * Constructor: GeoExt.tree.BaseLayerContainer
+     * 
+     * Parameters:
+     * config - {Object}
+     */
+    constructor: function(config) {
+        config.text = config.text || "Base Layer";
+        GeoExt.tree.BaseLayerContainer.superclass.constructor.apply(this, arguments);
+    },
+
+    /**
+     * Method: addLayerNode
+     * Adds a child node representing a base layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to add a node for
+     */
+    addLayerNode: function(layerRecord) {
+        var layer = layerRecord.get("layer");
+        if (layer.isBaseLayer == true) {
+            GeoExt.tree.BaseLayerContainer.superclass.addLayerNode.call(this,
+                layerRecord);
+        }
+    },
+    
+    /**
+     * Method: removeLayerNode
+     * Removes a child node representing a base layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to remove the node for
+     */
+    removeLayerNode: function(layerRecord) {
+        var layer = layerRecord.get("layer");
+        if (layer.isBaseLayer == true) {
+            GeoExt.tree.BaseLayerContainer.superclass.removeLayerNode.call(this,
+                layerRecord);
+    	}
+    }
+});
+
+/**
+ * NodeType: gx_baselayercontainer
+ */
+Ext.tree.TreePanel.nodeTypes.gx_baselayercontainer = GeoExt.tree.BaseLayerContainer;

Deleted: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/widgets/tree/LayerContainer.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,248 +0,0 @@
-/**
- * Copyright (c) 2008 The Open Planning Project
- */
-
-/**
- * @include GeoExt/widgets/tree/LayerNode.js
- */
-Ext.namespace("GeoExt.tree");
-
-/**
- * Class: GeoExt.tree.LayerContainer
- * 
- * A subclass of {Ext.tree.TreeNode} that will collect all layers of an
- * OpenLayers map. Only layers that have displayInLayerSwitcher set to true
- * will be included. The childrens' iconCls will be set to "baselayer-icon"
- * for base layers, and to "layer-icon" for overlay layers.
- * 
- * To use this node type in JSON config, set nodeType to "olLayerContainer".
- * 
- * Inherits from:
- * - <Ext.tree.TreeNode>
- */
-GeoExt.tree.LayerContainer = Ext.extend(Ext.tree.TreeNode, {
-    
-    /**
-     * APIProperty: layerStore
-     * {<GeoExt.data.LayerStore>} The layer store containing layers to be
-     *     displayed in the container.
-     */
-    layerStore: null,
-    
-    /**
-     * APIProperty: defaults
-     * {Object} a configuration object passed to all nodes that this
-     *     LayerContainer creates.
-     */
-    defaults: null,
-
-    /**
-     * Constructor: GeoExt.tree.LayerContainer
-     * 
-     * Parameters:
-     * config - {Object}
-     */
-    constructor: function(config) {
-        this.layerStore = config.layerStore;
-        this.defaults = config.defaults;
-        GeoExt.tree.LayerContainer.superclass.constructor.apply(this, arguments);
-    },
-
-    /**
-     * Method: render
-     * 
-     * Parameters:
-     * bulkRender - {Boolean}
-     */
-    render: function(bulkRender) {
-        if (!this.rendered) {
-            if(!this.layerStore) {
-                this.layerStore = GeoExt.MapPanel.guess().layers;
-            }
-            this.layerStore.each(function(record) {
-                this.addLayerNode(record);
-            }, this);
-            this.layerStore.on({
-                "add": this.onStoreAdd,
-                "remove": this.onStoreRemove,
-                scope: this
-            });
-        }
-        GeoExt.tree.LayerContainer.superclass.render.call(this, bulkRender);
-    },
-    
-    /**
-     * Method: onStoreAdd
-     * Listener for the store's add event.
-     *
-     * Parameters:
-     * store - {Ext.data.Store}
-     * records - {Array(Ext.data.Record)}
-     * index - {Number}
-     */
-    onStoreAdd: function(store, records, index) {
-        if(!this._reordering) {
-            var nodeIndex = this.recordIndexToNodeIndex(index);
-            for(var i=0; i<records.length; ++i) {
-                this.addLayerNode(records[i], nodeIndex);
-            }
-        }
-    },
-    
-    /**
-     * Method: onStoreRemove
-     * Listener for the store's remove event.
-     *
-     * Parameters:
-     * store - {Ext.data.Store}
-     * record - {Ext.data.Record}
-     * index - {Number}
-     */
-    onStoreRemove: function(store, record, index) {
-        if(!this._reordering) {
-            this.removeLayerNode(record);
-        }
-    },
-
-    /**
-     * Method: onDestroy
-     */
-    onDestroy: function() {
-        if(this.layerStore) {
-            this.layerStore.un("add", this.onStoreAdd, this);
-            this.layerStore.un("remove", this.onStoreRemove, this);
-        }
-        GeoExt.tree.LayerContainer.superclass.onDestroy.apply(this, arguments);
-    },
-    
-    /**
-     * Method: recordIndexToNodeIndex
-     * Convert a record index into a child node index.
-     *
-     * Parameters:
-     * index - {Number} The record index in the layer store.
-     *
-     * Returns:
-     * {Number} The appropriate child node index for the record.
-     */
-    recordIndexToNodeIndex: function(index) {
-        var store = this.layerStore;
-        var count = store.getCount();
-        var nodeIndex = -1;
-        for(var i=count-1; i>=0; --i) {
-            if(store.getAt(i).get("layer").displayInLayerSwitcher) {
-                ++nodeIndex;
-                if(index === i) {
-                    break;
-                }
-            }
-        };
-        return nodeIndex;
-    },
-    
-    /**
-     * Method: nodeIndexToRecordIndex
-     * Convert a child node index to a record index.
-     *
-     * Parameters:
-     * index - {Number} The child node index.
-     *
-     * Returns:
-     * {Number} The appropriate record index for the node.
-     */
-    nodeIndexToRecordIndex: function(index) {
-        var store = this.layerStore;
-        var count = store.getCount();
-        var nodeIndex = -1;
-        for(var i=count-1; i>=0; --i) {
-            if(store.getAt(i).get("layer").displayInLayerSwitcher) {
-                ++nodeIndex;
-                if(index === nodeIndex) {
-                    break;
-                }
-            }
-        }
-        return i;
-    },
-    
-    /**
-     * Method: addLayerNode
-     * Adds a child node representing a layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to add the layer for
-     * index - {Number} Optional index for the new layer.  Default is 0.
-     */
-    addLayerNode: function(layerRecord, index) {
-        index = index || 0;
-        var layer = layerRecord.get("layer");
-        if (layer.displayInLayerSwitcher === true) {
-            var node = new GeoExt.tree.LayerNode(Ext.applyIf({
-                iconCls: layer.isBayeLayer ? 'baselayer-icon' : 'layer-icon',
-                layer: layer,
-                layerStore: this.layerStore
-            }, this.defaults));
-            var sibling = this.item(index);
-            if(sibling) {
-                this.insertBefore(node, sibling);
-            } else {
-                this.appendChild(node);
-            }
-            node.on("move", this.onChildMove, this);
-        }
-    },
-    
-    /**
-     * Method: removeLayerNode
-     * Removes a child node representing a layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to remove the node for
-     */
-    removeLayerNode: function(layerRecord) {
-        var layer = layerRecord.get("layer");
-        if (layer.displayInLayerSwitcher == true) {
-            var node = this.findChildBy(function(node) {
-                return node.layer == layer;
-            });
-            if(node) {
-                node.un("move", this.onChildMove, this);
-                node.remove();
-            }
-    	}
-    },
-    
-    /**
-     * Method: onChildMove
-     * Listener for child node "move" events.  This updates the order of
-     *     records in the store based on new node order if the node has not
-     *     changed parents.
-     *
-     * Parameters:
-     * tree - {Ext.data.Tree}
-     * node - {Ext.tree.TreeNode}
-     * oldParent - {Ext.tree.TreeNode}
-     * newParent - {Ext.tree.TreeNode}
-     * index {Number}
-     */
-    onChildMove: function(tree, node, oldParent, newParent, index) {
-        if(oldParent === newParent) {
-            var newRecordIndex = this.nodeIndexToRecordIndex(index);
-            var oldRecordIndex = this.layerStore.findBy(function(record) {
-                return record.get("layer") === node.layer;
-            });
-            // remove the record and re-insert it at the correct index
-            var record = this.layerStore.getAt(oldRecordIndex);
-            this._reordering = true;
-            this.layerStore.remove(record);
-            this.layerStore.insert(newRecordIndex, [record]);
-            delete this._reordering;
-        }
-    }
-    
-});
-
-/**
- * NodeType: gx_layercontainer
- */
-Ext.tree.TreePanel.nodeTypes.gx_layercontainer = GeoExt.tree.LayerContainer;

Copied: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js (from rev 830, core/trunk/geoext/lib/GeoExt/widgets/tree/LayerContainer.js)
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2008 The Open Planning Project
+ */
+
+/**
+ * @include GeoExt/widgets/tree/LayerNode.js
+ */
+Ext.namespace("GeoExt.tree");
+
+/**
+ * Class: GeoExt.tree.LayerContainer
+ * 
+ * A subclass of {Ext.tree.TreeNode} that will collect all layers of an
+ * OpenLayers map. Only layers that have displayInLayerSwitcher set to true
+ * will be included. The childrens' iconCls will be set to "baselayer-icon"
+ * for base layers, and to "layer-icon" for overlay layers.
+ * 
+ * To use this node type in JSON config, set nodeType to "olLayerContainer".
+ * 
+ * Inherits from:
+ * - <Ext.tree.TreeNode>
+ */
+GeoExt.tree.LayerContainer = Ext.extend(Ext.tree.TreeNode, {
+    
+    /**
+     * APIProperty: layerStore
+     * {<GeoExt.data.LayerStore>} The layer store containing layers to be
+     *     displayed in the container.
+     */
+    layerStore: null,
+    
+    /**
+     * APIProperty: defaults
+     * {Object} a configuration object passed to all nodes that this
+     *     LayerContainer creates.
+     */
+    defaults: null,
+
+    /**
+     * Constructor: GeoExt.tree.LayerContainer
+     * 
+     * Parameters:
+     * config - {Object}
+     */
+    constructor: function(config) {
+        this.layerStore = config.layerStore;
+        this.defaults = config.defaults;
+        GeoExt.tree.LayerContainer.superclass.constructor.apply(this, arguments);
+    },
+
+    /**
+     * Method: render
+     * 
+     * Parameters:
+     * bulkRender - {Boolean}
+     */
+    render: function(bulkRender) {
+        if (!this.rendered) {
+            if(!this.layerStore) {
+                this.layerStore = GeoExt.MapPanel.guess().layers;
+            }
+            this.layerStore.each(function(record) {
+                this.addLayerNode(record);
+            }, this);
+            this.layerStore.on({
+                "add": this.onStoreAdd,
+                "remove": this.onStoreRemove,
+                scope: this
+            });
+        }
+        GeoExt.tree.LayerContainer.superclass.render.call(this, bulkRender);
+    },
+    
+    /**
+     * Method: onStoreAdd
+     * Listener for the store's add event.
+     *
+     * Parameters:
+     * store - {Ext.data.Store}
+     * records - {Array(Ext.data.Record)}
+     * index - {Number}
+     */
+    onStoreAdd: function(store, records, index) {
+        if(!this._reordering) {
+            var nodeIndex = this.recordIndexToNodeIndex(index);
+            for(var i=0; i<records.length; ++i) {
+                this.addLayerNode(records[i], nodeIndex);
+            }
+        }
+    },
+    
+    /**
+     * Method: onStoreRemove
+     * Listener for the store's remove event.
+     *
+     * Parameters:
+     * store - {Ext.data.Store}
+     * record - {Ext.data.Record}
+     * index - {Number}
+     */
+    onStoreRemove: function(store, record, index) {
+        if(!this._reordering) {
+            this.removeLayerNode(record);
+        }
+    },
+
+    /**
+     * Method: onDestroy
+     */
+    onDestroy: function() {
+        if(this.layerStore) {
+            this.layerStore.un("add", this.onStoreAdd, this);
+            this.layerStore.un("remove", this.onStoreRemove, this);
+        }
+        GeoExt.tree.LayerContainer.superclass.onDestroy.apply(this, arguments);
+    },
+    
+    /**
+     * Method: recordIndexToNodeIndex
+     * Convert a record index into a child node index.
+     *
+     * Parameters:
+     * index - {Number} The record index in the layer store.
+     *
+     * Returns:
+     * {Number} The appropriate child node index for the record.
+     */
+    recordIndexToNodeIndex: function(index) {
+        var store = this.layerStore;
+        var count = store.getCount();
+        var nodeIndex = -1;
+        for(var i=count-1; i>=0; --i) {
+            if(store.getAt(i).get("layer").displayInLayerSwitcher) {
+                ++nodeIndex;
+                if(index === i) {
+                    break;
+                }
+            }
+        };
+        return nodeIndex;
+    },
+    
+    /**
+     * Method: nodeIndexToRecordIndex
+     * Convert a child node index to a record index.
+     *
+     * Parameters:
+     * index - {Number} The child node index.
+     *
+     * Returns:
+     * {Number} The appropriate record index for the node.
+     */
+    nodeIndexToRecordIndex: function(index) {
+        var store = this.layerStore;
+        var count = store.getCount();
+        var nodeIndex = -1;
+        for(var i=count-1; i>=0; --i) {
+            if(store.getAt(i).get("layer").displayInLayerSwitcher) {
+                ++nodeIndex;
+                if(index === nodeIndex) {
+                    break;
+                }
+            }
+        }
+        return i;
+    },
+    
+    /**
+     * Method: addLayerNode
+     * Adds a child node representing a layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to add the layer for
+     * index - {Number} Optional index for the new layer.  Default is 0.
+     */
+    addLayerNode: function(layerRecord, index) {
+        index = index || 0;
+        var layer = layerRecord.get("layer");
+        if (layer.displayInLayerSwitcher === true) {
+            var node = new GeoExt.tree.LayerNode(Ext.applyIf({
+                iconCls: layer.isBayeLayer ? 'baselayer-icon' : 'layer-icon',
+                layer: layer,
+                layerStore: this.layerStore
+            }, this.defaults));
+            var sibling = this.item(index);
+            if(sibling) {
+                this.insertBefore(node, sibling);
+            } else {
+                this.appendChild(node);
+            }
+            node.on("move", this.onChildMove, this);
+        }
+    },
+    
+    /**
+     * Method: removeLayerNode
+     * Removes a child node representing a layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to remove the node for
+     */
+    removeLayerNode: function(layerRecord) {
+        var layer = layerRecord.get("layer");
+        if (layer.displayInLayerSwitcher == true) {
+            var node = this.findChildBy(function(node) {
+                return node.layer == layer;
+            });
+            if(node) {
+                node.un("move", this.onChildMove, this);
+                node.remove();
+            }
+    	}
+    },
+    
+    /**
+     * Method: onChildMove
+     * Listener for child node "move" events.  This updates the order of
+     *     records in the store based on new node order if the node has not
+     *     changed parents.
+     *
+     * Parameters:
+     * tree - {Ext.data.Tree}
+     * node - {Ext.tree.TreeNode}
+     * oldParent - {Ext.tree.TreeNode}
+     * newParent - {Ext.tree.TreeNode}
+     * index {Number}
+     */
+    onChildMove: function(tree, node, oldParent, newParent, index) {
+        if(oldParent === newParent) {
+            var newRecordIndex = this.nodeIndexToRecordIndex(index);
+            var oldRecordIndex = this.layerStore.findBy(function(record) {
+                return record.get("layer") === node.layer;
+            });
+            // remove the record and re-insert it at the correct index
+            var record = this.layerStore.getAt(oldRecordIndex);
+            this._reordering = true;
+            this.layerStore.remove(record);
+            this.layerStore.insert(newRecordIndex, [record]);
+            delete this._reordering;
+        }
+    }
+    
+});
+
+/**
+ * NodeType: gx_layercontainer
+ */
+Ext.tree.TreePanel.nodeTypes.gx_layercontainer = GeoExt.tree.LayerContainer;

Deleted: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/widgets/tree/LayerNode.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,307 +0,0 @@
-/**
- * Copyright (c) 2008 The Open Planning Project
- */
-Ext.namespace("GeoExt.tree");
-
-/**
- * Class: GeoExt.tree.LayerNodeUI
- * 
- * Inherits from:
- * - Ext.tree.TreeNodeUI
- */
-GeoExt.tree.LayerNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
-    
-    /**
-     * Property: radio
-     * {Ext.Element}
-     */
-    radio: null,
-    
-    /**
-     * Constructor: GeoExt.tree.LayerNodeUI
-     * 
-     * Parameters:
-     * config - {Object}
-     */
-    constructor: function(config) {
-        GeoExt.tree.LayerNodeUI.superclass.constructor.apply(this, arguments);
-    },
-    
-    /**
-     * Method: render
-     * 
-     * Parameters:
-     * bulkRender - {Boolean}
-     */
-    render: function(bulkRender) {
-        GeoExt.tree.LayerNodeUI.superclass.render.call(this, bulkRender);
-        var a = this.node.attributes;
-        if (a.radioGroup && this.radio !== undefined) {
-            this.radio = Ext.DomHelper.insertAfter(this.checkbox,
-                ['<input type="radio" class="x-tree-node-radio" name="',
-                a.radioGroup, '_radio"></input>'].join(""));
-        }
-    },
-    
-    /**
-     * Method: onClick
-     * 
-     * Parameters:
-     * e - {Object}
-     */
-    onClick: function(e) {
-        if (e.getTarget('input[type=radio]', 1)) {
-            this.fireEvent("radiochange", this.node);
-        } else {
-            GeoExt.tree.LayerNodeUI.superclass.onClick.call(this, e);
-        }
-    },
-    
-    /**
-     * Method: toggleCheck
-     * 
-     * Parameters:
-     * value - {Boolean}
-     */
-    toggleCheck: function(value) {
-        GeoExt.tree.LayerNodeUI.superclass.toggleCheck.call(this, value);
-        var node = this.node;
-        var layer = this.node.layer;
-        node.visibilityChanging = true;
-        if(this.checkbox && (layer.getVisibility() != this.isChecked())) {
-            layer.setVisibility(this.isChecked());
-        }
-        node.visibilityChanging = false;
-    },
-    
-    /**
-     * Method: onDestroy
-     */
-    onDestroy: function() {
-        delete this.radio;
-        GeoExt.tree.LayerNodeUI.superclass.onDestroy.call(this);
-    }
-});
-
-
-/**
- * Class: GeoExt.tree.LayerNode
- * 
- * A subclass of {<GeoExt.tree.TristateCheckboxNode>} that is connected to an
- * {OpenLayers.Layer} by setting the node's layer property. Checking or
- * unchecking the checkbox of this node will directly affect the layer and
- * vice versa. The default iconCls for this node's icon is "layer-icon",
- * unless it has children.
- * 
- * Setting the node's layer property to a layer name instead of an object
- * will also work. As soon as a layer is found, it will be stored as layer
- * property in the attributes hash.
- * 
- * The node's text property defaults to the layer name.
- * 
- * If the node has a radioGroup attribute configured, the node will be
- * rendered with a radio button. This works like the checkbox with the
- * checked attribute, but radioGroup is a string that identifies the options
- * group. Clicking the radio button will fire a radioChange event.
- * 
- * To use this node type in a JSON config, set nodeType to "gx_layer".
- * 
- * Inherits from:
- * - Ext.tree.TreeNode
- */
-GeoExt.tree.LayerNode = Ext.extend(Ext.tree.TreeNode, {
-    
-    /**
-     * APIProperty: layer
-     * {OpenLayers.Layer|String} The layer that this layer node will
-     *     be bound to, or the name of the layer (has to match the layer's
-     *     name property). If a layer name is provided, <layerStore> also has
-     *     to be provided.
-     */
-    layer: null,
-    
-    /**
-     * APIProperty: layerStore
-     * {<GeoExt.data.LayerStore|"auto"} The layer store containing the layer
-     *     that this node represents. If set to "auto", the node will query
-     *     the ComponentManager for a <GeoExt.MapPanel>, take the first one it
-     *     finds and take its layer store. This property is only required
-     *     if <layer> is provided as a string.
-     */
-    layerStore: null,
-    
-    /**
-     * APIProperty: childNodeType
-     * {Ext.tree.Node|String} node class or nodeType of childnodes for this
-     *     node. A node type provided here needs to have an add method, with
-     *     a scope argument. This method will be run by this node in the
-     *     context of this node, to create child nodes.
-     */
-    childNodeType: null,
-    
-    /**
-     * Property: visibilityChanging
-     * {Boolean} private property indicating layer visibility being changed
-     *     by this node in order to prevent visibilitychanged events bouncing
-     *     back and forth
-     */
-    visibilityChanging: false,
-    
-    /**
-     * Constructor: GeoExt.tree.LayerNode
-     * 
-     * Parameters:
-     * config - {Object}
-     */
-    constructor: function(config) {
-        config.leaf = config.leaf || !config.children;
-        
-        config.iconCls = typeof config.iconCls == "undefined" &&
-            !config.children ? "layer-icon" : config.iconCls;
-        // checked status will be set by layer event, so setting it to false
-        // to always get the checkbox rendered
-        config.checked = false;
-        
-        this.defaultUI = this.defaultUI || GeoExt.tree.LayerNodeUI;
-        this.addEvents(
-            /**
-             * Event: radiochange
-             * Notifies listener when a differnt radio button was selected.
-             * Will be called with the currently selected node as argument.
-             */
-            "radiochange"
-        );
-        
-        Ext.apply(this, {
-            layer: config.layer,
-            layerStore: config.layerStore,
-            childNodeType: config.childNodeType
-        });
-        GeoExt.tree.LayerNode.superclass.constructor.apply(this, arguments);
-    },
-
-    /**
-     * Method: render
-     * 
-     * Properties:
-     * bulkRender {Boolean} - optional
-     * layer {<OpenLayers.Layer>} - optional
-     */
-    render: function(bulkRender) {
-        var layer = this.layer instanceof OpenLayers.Layer && this.layer;
-        if(!layer) {
-            // guess the store if not provided
-            if(!this.layerStore || this.layerStore == "auto") {
-                this.layerStore = GeoExt.MapPanel.guess().layers;
-            }
-            // now we try to find the layer by its name in the layer store
-            var i = this.layerStore.findBy(function(o) {
-                return o.get("title") == this.layer;
-            }, this);
-            if(i != -1) {
-                // if we found the layer, we can assign it and everything
-                // will be fine
-                layer = this.layerStore.getAt(i).get("layer");
-            }
-        }
-        if (!this.rendered || !layer) {
-            var ui = this.getUI();
-            
-            if(layer) {
-                this.layer = layer;
-                if(!this.text) {
-                    this.text = layer.name;
-                }
-                
-                if(this.childNodeType) {
-                    this.addChildNodes();
-                }
-                
-                ui.show();
-                ui.toggleCheck(layer.getVisibility());
-                this.addVisibilityEventHandlers();
-                // set initial checked status
-                this.attributes.checked = layer.getVisibility();
-            } else {
-                ui.hide();
-            }
-            
-            if(this.layerStore instanceof GeoExt.data.LayerStore) {
-                this.addStoreEventHandlers(layer);
-            }            
-        }
-        GeoExt.tree.LayerNode.superclass.render.call(this, bulkRender);
-    },
-    
-    /**
-     * Method: addVisibilityHandlers
-     * Adds handlers that sync the checkbox state with the layer's visibility
-     * state
-     */
-    addVisibilityEventHandlers: function() {
-        this.layer.events.register("visibilitychanged", this, function() {
-            if(!this.visibilityChanging &&
-                    this.attributes.checked != this.layer.getVisibility()) {
-                this.getUI().toggleCheck(this.layer.getVisibility());
-            }
-        });
-        this.on({
-            "checkchange": function(node, checked) {
-                if (checked && this.layer.isBaseLayer && this.layer.map) {
-                    this.layer.map.setBaseLayer(this.layer);
-                }
-                this.layer.setVisibility(checked);
-            },
-            scope: this
-        });
-    },
-    
-    /**
-     * Method: addStoreEventHandlers
-     * Adds handlers that make sure the node disappeares when the layer is
-     * removed from the store, and appears when it is re-added.
-     */
-    addStoreEventHandlers: function() {
-        this.layerStore.on({
-            "add": function(store, records, index) {
-                var l;
-                for(var i=0; i<records.length; ++i) {
-                    l = records[i].get("layer");
-                    if(this.layer == l) {
-                        this.getUI().show();
-                    } else if (this.layer == l.name) {
-                        // layer is a string, which means the node has not yet
-                        // been rendered because the layer was not found. But
-                        // now we have the layer and can render.
-                        this.render(bulkRender);
-                        return;
-                    }
-                }
-            },
-            "remove": function(store, record, index) {
-                if(this.layer == record.get("layer")) {
-                    this.getUI().hide();
-                }
-            },
-            scope: this
-        });
-    },
-    
-    /**
-     * Method: addChildNodes
-     * Calls the add method of a node type configured as <childNodeType>
-     * to add children.
-     */
-    addChildNodes: function() {
-        if(typeof this.childNodeType == "string") {
-            Ext.tree.TreePanel.nodeTypes[this.childNodeType].add(this);
-        } else if(typeof this.childNodeType.add === "function") {
-            this.childNodeType.add(this);
-        }
-    }
-});
-
-/**
- * NodeType: gx_layer
- */
-Ext.tree.TreePanel.nodeTypes.gx_layer = GeoExt.tree.LayerNode;

Copied: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js (from rev 830, core/trunk/geoext/lib/GeoExt/widgets/tree/LayerNode.js)
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,307 @@
+/**
+ * Copyright (c) 2008 The Open Planning Project
+ */
+Ext.namespace("GeoExt.tree");
+
+/**
+ * Class: GeoExt.tree.LayerNodeUI
+ * 
+ * Inherits from:
+ * - Ext.tree.TreeNodeUI
+ */
+GeoExt.tree.LayerNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+    
+    /**
+     * Property: radio
+     * {Ext.Element}
+     */
+    radio: null,
+    
+    /**
+     * Constructor: GeoExt.tree.LayerNodeUI
+     * 
+     * Parameters:
+     * config - {Object}
+     */
+    constructor: function(config) {
+        GeoExt.tree.LayerNodeUI.superclass.constructor.apply(this, arguments);
+    },
+    
+    /**
+     * Method: render
+     * 
+     * Parameters:
+     * bulkRender - {Boolean}
+     */
+    render: function(bulkRender) {
+        GeoExt.tree.LayerNodeUI.superclass.render.call(this, bulkRender);
+        var a = this.node.attributes;
+        if (a.radioGroup && this.radio !== undefined) {
+            this.radio = Ext.DomHelper.insertAfter(this.checkbox,
+                ['<input type="radio" class="x-tree-node-radio" name="',
+                a.radioGroup, '_radio"></input>'].join(""));
+        }
+    },
+    
+    /**
+     * Method: onClick
+     * 
+     * Parameters:
+     * e - {Object}
+     */
+    onClick: function(e) {
+        if (e.getTarget('input[type=radio]', 1)) {
+            this.fireEvent("radiochange", this.node);
+        } else {
+            GeoExt.tree.LayerNodeUI.superclass.onClick.call(this, e);
+        }
+    },
+    
+    /**
+     * Method: toggleCheck
+     * 
+     * Parameters:
+     * value - {Boolean}
+     */
+    toggleCheck: function(value) {
+        GeoExt.tree.LayerNodeUI.superclass.toggleCheck.call(this, value);
+        var node = this.node;
+        var layer = this.node.layer;
+        node.visibilityChanging = true;
+        if(this.checkbox && (layer.getVisibility() != this.isChecked())) {
+            layer.setVisibility(this.isChecked());
+        }
+        node.visibilityChanging = false;
+    },
+    
+    /**
+     * Method: onDestroy
+     */
+    onDestroy: function() {
+        delete this.radio;
+        GeoExt.tree.LayerNodeUI.superclass.onDestroy.call(this);
+    }
+});
+
+
+/**
+ * Class: GeoExt.tree.LayerNode
+ * 
+ * A subclass of {<GeoExt.tree.TristateCheckboxNode>} that is connected to an
+ * {OpenLayers.Layer} by setting the node's layer property. Checking or
+ * unchecking the checkbox of this node will directly affect the layer and
+ * vice versa. The default iconCls for this node's icon is "layer-icon",
+ * unless it has children.
+ * 
+ * Setting the node's layer property to a layer name instead of an object
+ * will also work. As soon as a layer is found, it will be stored as layer
+ * property in the attributes hash.
+ * 
+ * The node's text property defaults to the layer name.
+ * 
+ * If the node has a radioGroup attribute configured, the node will be
+ * rendered with a radio button. This works like the checkbox with the
+ * checked attribute, but radioGroup is a string that identifies the options
+ * group. Clicking the radio button will fire a radioChange event.
+ * 
+ * To use this node type in a JSON config, set nodeType to "gx_layer".
+ * 
+ * Inherits from:
+ * - Ext.tree.TreeNode
+ */
+GeoExt.tree.LayerNode = Ext.extend(Ext.tree.TreeNode, {
+    
+    /**
+     * APIProperty: layer
+     * {OpenLayers.Layer|String} The layer that this layer node will
+     *     be bound to, or the name of the layer (has to match the layer's
+     *     name property). If a layer name is provided, <layerStore> also has
+     *     to be provided.
+     */
+    layer: null,
+    
+    /**
+     * APIProperty: layerStore
+     * {<GeoExt.data.LayerStore|"auto"} The layer store containing the layer
+     *     that this node represents. If set to "auto", the node will query
+     *     the ComponentManager for a <GeoExt.MapPanel>, take the first one it
+     *     finds and take its layer store. This property is only required
+     *     if <layer> is provided as a string.
+     */
+    layerStore: null,
+    
+    /**
+     * APIProperty: childNodeType
+     * {Ext.tree.Node|String} node class or nodeType of childnodes for this
+     *     node. A node type provided here needs to have an add method, with
+     *     a scope argument. This method will be run by this node in the
+     *     context of this node, to create child nodes.
+     */
+    childNodeType: null,
+    
+    /**
+     * Property: visibilityChanging
+     * {Boolean} private property indicating layer visibility being changed
+     *     by this node in order to prevent visibilitychanged events bouncing
+     *     back and forth
+     */
+    visibilityChanging: false,
+    
+    /**
+     * Constructor: GeoExt.tree.LayerNode
+     * 
+     * Parameters:
+     * config - {Object}
+     */
+    constructor: function(config) {
+        config.leaf = config.leaf || !config.children;
+        
+        config.iconCls = typeof config.iconCls == "undefined" &&
+            !config.children ? "layer-icon" : config.iconCls;
+        // checked status will be set by layer event, so setting it to false
+        // to always get the checkbox rendered
+        config.checked = false;
+        
+        this.defaultUI = this.defaultUI || GeoExt.tree.LayerNodeUI;
+        this.addEvents(
+            /**
+             * Event: radiochange
+             * Notifies listener when a differnt radio button was selected.
+             * Will be called with the currently selected node as argument.
+             */
+            "radiochange"
+        );
+        
+        Ext.apply(this, {
+            layer: config.layer,
+            layerStore: config.layerStore,
+            childNodeType: config.childNodeType
+        });
+        GeoExt.tree.LayerNode.superclass.constructor.apply(this, arguments);
+    },
+
+    /**
+     * Method: render
+     * 
+     * Properties:
+     * bulkRender {Boolean} - optional
+     * layer {<OpenLayers.Layer>} - optional
+     */
+    render: function(bulkRender) {
+        var layer = this.layer instanceof OpenLayers.Layer && this.layer;
+        if(!layer) {
+            // guess the store if not provided
+            if(!this.layerStore || this.layerStore == "auto") {
+                this.layerStore = GeoExt.MapPanel.guess().layers;
+            }
+            // now we try to find the layer by its name in the layer store
+            var i = this.layerStore.findBy(function(o) {
+                return o.get("title") == this.layer;
+            }, this);
+            if(i != -1) {
+                // if we found the layer, we can assign it and everything
+                // will be fine
+                layer = this.layerStore.getAt(i).get("layer");
+            }
+        }
+        if (!this.rendered || !layer) {
+            var ui = this.getUI();
+            
+            if(layer) {
+                this.layer = layer;
+                if(!this.text) {
+                    this.text = layer.name;
+                }
+                
+                if(this.childNodeType) {
+                    this.addChildNodes();
+                }
+                
+                ui.show();
+                ui.toggleCheck(layer.getVisibility());
+                this.addVisibilityEventHandlers();
+                // set initial checked status
+                this.attributes.checked = layer.getVisibility();
+            } else {
+                ui.hide();
+            }
+            
+            if(this.layerStore instanceof GeoExt.data.LayerStore) {
+                this.addStoreEventHandlers(layer);
+            }            
+        }
+        GeoExt.tree.LayerNode.superclass.render.call(this, bulkRender);
+    },
+    
+    /**
+     * Method: addVisibilityHandlers
+     * Adds handlers that sync the checkbox state with the layer's visibility
+     * state
+     */
+    addVisibilityEventHandlers: function() {
+        this.layer.events.register("visibilitychanged", this, function() {
+            if(!this.visibilityChanging &&
+                    this.attributes.checked != this.layer.getVisibility()) {
+                this.getUI().toggleCheck(this.layer.getVisibility());
+            }
+        });
+        this.on({
+            "checkchange": function(node, checked) {
+                if (checked && this.layer.isBaseLayer && this.layer.map) {
+                    this.layer.map.setBaseLayer(this.layer);
+                }
+                this.layer.setVisibility(checked);
+            },
+            scope: this
+        });
+    },
+    
+    /**
+     * Method: addStoreEventHandlers
+     * Adds handlers that make sure the node disappeares when the layer is
+     * removed from the store, and appears when it is re-added.
+     */
+    addStoreEventHandlers: function() {
+        this.layerStore.on({
+            "add": function(store, records, index) {
+                var l;
+                for(var i=0; i<records.length; ++i) {
+                    l = records[i].get("layer");
+                    if(this.layer == l) {
+                        this.getUI().show();
+                    } else if (this.layer == l.name) {
+                        // layer is a string, which means the node has not yet
+                        // been rendered because the layer was not found. But
+                        // now we have the layer and can render.
+                        this.render(bulkRender);
+                        return;
+                    }
+                }
+            },
+            "remove": function(store, record, index) {
+                if(this.layer == record.get("layer")) {
+                    this.getUI().hide();
+                }
+            },
+            scope: this
+        });
+    },
+    
+    /**
+     * Method: addChildNodes
+     * Calls the add method of a node type configured as <childNodeType>
+     * to add children.
+     */
+    addChildNodes: function() {
+        if(typeof this.childNodeType == "string") {
+            Ext.tree.TreePanel.nodeTypes[this.childNodeType].add(this);
+        } else if(typeof this.childNodeType.add === "function") {
+            this.childNodeType.add(this);
+        }
+    }
+});
+
+/**
+ * NodeType: gx_layer
+ */
+Ext.tree.TreePanel.nodeTypes.gx_layer = GeoExt.tree.LayerNode;

Deleted: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js
===================================================================
--- core/trunk/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,70 +0,0 @@
-/**
- * Copyright (c) 2008 The Open Planning Project
- */
-
-/**
- * @requires GeoExt/widgets/tree/LayerContainer.js
- */
-Ext.namespace("GeoExt.tree");
-
-/**
- * Class: GeoExt.tree.OverlayLayerContainer
- * 
- * A layer container that will collect all overlay layers of an OpenLayers map.
- * Only layers that have displayInLayerSwitcher set to true will be included.
- * 
- * To use this node type in JSON config, set nodeType to
- * "olOverlayLayerContainer".
- * 
- * Inherits from:
- * - <GeoExt.tree.LayerContainer>
- */
-GeoExt.tree.OverlayLayerContainer = Ext.extend(GeoExt.tree.LayerContainer, {
-
-    /**
-     * Constructor: GeoExt.tree.OverlayLayerContainer
-     * 
-     * Parameters:
-     * config - {Object}
-     */
-    constructor: function(config) {
-        config.text = config.text || "Overlays";
-        GeoExt.tree.OverlayLayerContainer.superclass.constructor.apply(this,
-            arguments);
-    },
-
-    /**
-     * Method: addLayerNode
-     * Adds a child node representing a overlay layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to add a node for
-     */
-    addLayerNode: function(layerRecord) {
-        var layer = layerRecord.get("layer");
-        if (layer.isBaseLayer == false) {
-            GeoExt.tree.OverlayLayerContainer.superclass.addLayerNode.call(this,
-                layerRecord);
-        }
-    },
-    
-    /**
-     * Method: removeLayerNode
-     * Removes a child node representing an overlay layer of the map
-     * 
-     * Parameters:
-     * layerRecord - {Ext.data.Record} the layer record to remove the node for
-     */
-    removeLayerNode: function(layerRecord) {
-        var layer = layerRecord.get("layer");
-        if (layer.isBaseLayer == false) {
-            GeoExt.tree.OverlayLayerContainer.superclass.removeLayerNode.call(
-                this, layerRecord);
-    	}
-    }
-});
-
-/**
- * NodeType: gx_overlaylayercontainer
- */
-Ext.tree.TreePanel.nodeTypes.gx_overlaylayercontainer = GeoExt.tree.OverlayLayerContainer;

Copied: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js (from rev 830, core/trunk/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js)
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/OverlayLayerContainer.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2008 The Open Planning Project
+ */
+
+/**
+ * @requires GeoExt/widgets/tree/LayerContainer.js
+ */
+Ext.namespace("GeoExt.tree");
+
+/**
+ * Class: GeoExt.tree.OverlayLayerContainer
+ * 
+ * A layer container that will collect all overlay layers of an OpenLayers map.
+ * Only layers that have displayInLayerSwitcher set to true will be included.
+ * 
+ * To use this node type in JSON config, set nodeType to
+ * "olOverlayLayerContainer".
+ * 
+ * Inherits from:
+ * - <GeoExt.tree.LayerContainer>
+ */
+GeoExt.tree.OverlayLayerContainer = Ext.extend(GeoExt.tree.LayerContainer, {
+
+    /**
+     * Constructor: GeoExt.tree.OverlayLayerContainer
+     * 
+     * Parameters:
+     * config - {Object}
+     */
+    constructor: function(config) {
+        config.text = config.text || "Overlays";
+        GeoExt.tree.OverlayLayerContainer.superclass.constructor.apply(this,
+            arguments);
+    },
+
+    /**
+     * Method: addLayerNode
+     * Adds a child node representing a overlay layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to add a node for
+     */
+    addLayerNode: function(layerRecord) {
+        var layer = layerRecord.get("layer");
+        if (layer.isBaseLayer == false) {
+            GeoExt.tree.OverlayLayerContainer.superclass.addLayerNode.call(this,
+                layerRecord);
+        }
+    },
+    
+    /**
+     * Method: removeLayerNode
+     * Removes a child node representing an overlay layer of the map
+     * 
+     * Parameters:
+     * layerRecord - {Ext.data.Record} the layer record to remove the node for
+     */
+    removeLayerNode: function(layerRecord) {
+        var layer = layerRecord.get("layer");
+        if (layer.isBaseLayer == false) {
+            GeoExt.tree.OverlayLayerContainer.superclass.removeLayerNode.call(
+                this, layerRecord);
+    	}
+    }
+});
+
+/**
+ * NodeType: gx_overlaylayercontainer
+ */
+Ext.tree.TreePanel.nodeTypes.gx_overlaylayercontainer = GeoExt.tree.OverlayLayerContainer;

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt.js	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt.js	2009-05-20 06:33:05 UTC (rev 831)
@@ -73,7 +73,11 @@
             "GeoExt/widgets/Popup.js",
             "GeoExt/widgets/form/SearchAction.js",
             "GeoExt/widgets/form/BasicForm.js",
-            "GeoExt/widgets/form/FormPanel.js"
+            "GeoExt/widgets/form/FormPanel.js",
+            "GeoExt/widgets/tree/LayerNode.js",
+            "GeoExt/widgets/tree/LayerContainer.js",
+            "GeoExt/widgets/tree/BaseLayerContainer.js",
+            "GeoExt/widgets/tree/OverlayLayerContainer.js"
         );
 
         var agent = navigator.userAgent;

Copied: sandbox/elemoine/playground/geoext/resources/css/gxtheme-gray.css (from rev 830, core/trunk/geoext/resources/css/gxtheme-gray.css)
===================================================================
--- sandbox/elemoine/playground/geoext/resources/css/gxtheme-gray.css	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/resources/css/gxtheme-gray.css	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,9 @@
+.gx-popup-anc {
+	background: transparent url(../images/gray/anchor.png) no-repeat 0 0;
+        position: relative;
+        top:-1px;
+        left:5px;
+        z-index:2;
+        height:16px;
+        width:31px;
+}
\ No newline at end of file

Modified: sandbox/elemoine/playground/geoext/resources/css/popup.css
===================================================================
--- sandbox/elemoine/playground/geoext/resources/css/popup.css	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/resources/css/popup.css	2009-05-20 06:33:05 UTC (rev 831)
@@ -8,14 +8,3 @@
         height:16px;
         width:31px;
 }
-
-
-.xtheme-gray .gx-popup-anc {
-	background: transparent url(../images/gray/anchor.png) no-repeat 0 0;
-        position: relative;
-        top:-1px;
-        left:5px;
-        z-index:2;
-        height:16px;
-        width:31px;
-}
\ No newline at end of file

Modified: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/FeatureRecord.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/FeatureRecord.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/FeatureRecord.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -50,24 +50,6 @@
             t.eq(record.get("foo"), "bar", "foo data row set correctly");
         }
 
-        function test_copy(t) {
-            
-            t.plan(2);
-            
-            var feature = new OpenLayers.Feature.Vector();
-            feature.fid = "foo";
-            var recordType = GeoExt.data.FeatureRecord.create();
-            
-            var record = new recordType({feature: feature, fid: feature.fid});
-            var copy = record.copy();
-            
-            record.set("fid", "bar");
-            t.ok(copy.get("fid") === "foo", "setting a property on original doesn't modify copy");
-            
-            t.ok(copy.get("feature") !== feature, "copy does not have original feature");
-            
-        }
-
     </script>
   <body>
     <div id="mappanel"></div>

Modified: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerRecord.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerRecord.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerRecord.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -44,23 +44,6 @@
             t.eq(record.get("foo"), "bar", "foo data row set correctly");
         }
         
-        function test_copy(t) {
-            
-            t.plan(2);
-            
-            var layer = new OpenLayers.Layer();
-            var recordType = GeoExt.data.LayerRecord.create();
-            
-            var record = new recordType({layer: layer, title: layer.name});
-            var copy = record.copy();
-            
-            record.set("title", "foo");
-            t.ok(copy.get("title") !== "foo", "setting a property on original doesn't modify copy");
-            
-            t.ok(copy.get("layer") !== layer, "copy does not have original layer");
-            
-        }
-        
     </script>
   <body>
     <div id="mappanel"></div>

Modified: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerStore.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerStore.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/data/LayerStore.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -169,7 +169,7 @@
 
         function test_add_remove(t) {
             
-            t.plan(2);
+            t.plan(6);
             
             var map = new OpenLayers.Map("mappanel");
             var store = new GeoExt.data.LayerStore({
@@ -184,7 +184,19 @@
             
             store.remove(record);
             t.eq(store.getCount(), 0, "removing a single record from the store removes one record");
+
+            // add back the original and prepare to add copy
+            store.add([record]);            
+            t.eq(store.getCount(), 1, "store has a single record before adding copy");
+            t.eq(map.layers.length, 1, "map has a single layer before adding copy");
             
+            // create a copy of the record with the same layer
+            var copy = record.copy(); // record with same id will replace original
+            copy.set("layer", record.get("layer")); // force records to have same layer            
+            store.add(copy);
+            t.eq(store.getCount(), 1, "store has a single record after adding copy");
+            t.eq(map.layers.length, 1, "map has a single layer after adding copy");
+            
         }
         
         function test_reorder(t) {

Modified: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/MapPanel.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/MapPanel.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/MapPanel.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -35,11 +35,12 @@
         }
 
         function test_mappanel(t) {
-            t.plan(2)
+            t.plan(3)
             
             loadMapPanel();
             t.eq(mapPanel.map.getCenter().toString(), "lon=5,lat=45", "Map center set correctly");
             t.eq(mapPanel.map.getZoom(), 4, "Zoom set correctly");
+            t.eq(GeoExt.MapPanel.guess().id, mapPanel.id, "MapPanel guessed correctly");
         }
         
         function test_allOverlays(t) {

Copied: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree (from rev 830, core/trunk/geoext/tests/lib/GeoExt/widgets/tree)

Deleted: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,65 +0,0 @@
-<html>
-    <head>
-        <script src="../../../../../../openlayers/lib/OpenLayers.js"></script>
-        <script src="../../../../../../ext/adapter/ext/ext-base.js"></script>
-        <script src="../../../../../../ext/ext-all-debug.js"></script>
-        <script src="../../../../../lib/GeoExt.js"></script>
-    
-        <script>
-        
-        function test_constructor(t) {
-            
-            t.plan(2);
-            
-            var store = new GeoExt.data.LayerStore();
-            var defaults = {};
-            
-            var node = new GeoExt.tree.LayerContainer({
-                layerStore: store,
-                defaults: defaults
-            });
-            
-            t.ok(node.layerStore === store, "layerStore set");
-            t.ok(node.defaults === defaults, "defaults set");
-            
-            node.destroy();
-            
-        }
-        
-        function test_render(t) {
-            
-            t.plan(2);
-            
-            var map = new OpenLayers.Map({
-                div: "map",
-                allOverlays: true
-            });
-            var layer = new OpenLayers.Layer();
-            map.addLayer(layer);
-            
-            var store = new GeoExt.data.LayerStore({
-                map: map
-            });
-            
-            var node = new GeoExt.tree.LayerContainer({
-                layerStore: store
-            });
-            
-            var panel = new Ext.tree.TreePanel({
-                renderTo: document.body,
-                root: node
-            });
-            
-            t.eq(node.childNodes && node.childNodes.length, 1, "container has one child");
-            t.ok(node.firstChild.layer === layer, "child layer is correct");
-
-            node.destroy();
-            
-        }
-        
-        </script>
-    </head>
-    <body>
-        <div id="map" style="width: 100px; height: 100px;"></div>
-    </body>
-</html>
\ No newline at end of file

Copied: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html (from rev 830, core/trunk/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html)
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerContainer.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,65 @@
+<html>
+    <head>
+        <script src="../../../../../../openlayers/lib/OpenLayers.js"></script>
+        <script src="../../../../../../ext/adapter/ext/ext-base.js"></script>
+        <script src="../../../../../../ext/ext-all-debug.js"></script>
+        <script src="../../../../../lib/GeoExt.js"></script>
+    
+        <script>
+        
+        function test_constructor(t) {
+            
+            t.plan(2);
+            
+            var store = new GeoExt.data.LayerStore();
+            var defaults = {};
+            
+            var node = new GeoExt.tree.LayerContainer({
+                layerStore: store,
+                defaults: defaults
+            });
+            
+            t.ok(node.layerStore === store, "layerStore set");
+            t.ok(node.defaults === defaults, "defaults set");
+            
+            node.destroy();
+            
+        }
+        
+        function test_render(t) {
+            
+            t.plan(2);
+            
+            var map = new OpenLayers.Map({
+                div: "map",
+                allOverlays: true
+            });
+            var layer = new OpenLayers.Layer();
+            map.addLayer(layer);
+            
+            var store = new GeoExt.data.LayerStore({
+                map: map
+            });
+            
+            var node = new GeoExt.tree.LayerContainer({
+                layerStore: store
+            });
+            
+            var panel = new Ext.tree.TreePanel({
+                renderTo: document.body,
+                root: node
+            });
+            
+            t.eq(node.childNodes && node.childNodes.length, 1, "container has one child");
+            t.ok(node.firstChild.layer === layer, "child layer is correct");
+
+            node.destroy();
+            
+        }
+        
+        </script>
+    </head>
+    <body>
+        <div id="map" style="width: 100px; height: 100px;"></div>
+    </body>
+</html>
\ No newline at end of file

Deleted: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html
===================================================================
--- core/trunk/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -1,78 +0,0 @@
-<html>
-    <head>
-        <script src="../../../../../../openlayers/lib/OpenLayers.js"></script>
-        <script src="../../../../../../ext/adapter/ext/ext-base.js"></script>
-        <script src="../../../../../../ext/ext-all-debug.js"></script>
-        <script src="../../../../../lib/GeoExt.js"></script>
-    
-        <script>
-        
-        function test_constructor(t) {
-            
-            t.plan(1);
-            
-            var store = new GeoExt.data.LayerStore();
-            
-            var node = new GeoExt.tree.LayerNode({
-                layer: "foo",
-                layerStore: store
-            });
-            
-            t.ok(node.layerStore === store, "layerStore set");
-            
-            node.destroy();
-            
-        }
-        
-        function test_render(t) {
-            
-            t.plan(5);
-            
-            var layer = new OpenLayers.Layer("foo");
-            
-            var mapPanel = new GeoExt.MapPanel({
-                layers: [layer],
-                allOverlays: true
-            });
-            
-            var node = new GeoExt.tree.LayerNode({
-                layer: "foo",
-                radioGroup: "group",
-                childNodeType: {
-                    add: function() {
-                        t.ok(true, "add function of childNodeType called");
-                    }
-                }
-            });
-            
-            node.on("radiochange", function() {
-                t.ok(arguments[0] === node, "radiochange event triggered with the selected node as first argument");
-            });
-                        
-            var panel = new Ext.tree.TreePanel({
-                renderTo: "tree",
-                root: node
-            });
-            
-            mapPanel.on("render", function() {
-                t.ok(node.layer === layer, "layer found on detected map panel");
-                
-                t.ok(node.ui.radio, "node has a radio button");
-                // simulate a click event for testing the radiochange event
-                node.ui.onClick({getTarget: function() {return true}});
-                
-                node.ui.toggleCheck();
-                t.eq(layer.visibility, false, "unchecking node hides layer");
-            });
-
-            mapPanel.render("map");
-            
-        }
-        
-        </script>
-    </head>
-    <body>
-        <div id="map" style="width: 100px; height: 100px;"></div>
-        <div id="tree" style="width: 100px; height: 100px;"></div>
-    </body>
-</html>
\ No newline at end of file

Copied: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html (from rev 830, core/trunk/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html)
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -0,0 +1,78 @@
+<html>
+    <head>
+        <script src="../../../../../../openlayers/lib/OpenLayers.js"></script>
+        <script src="../../../../../../ext/adapter/ext/ext-base.js"></script>
+        <script src="../../../../../../ext/ext-all-debug.js"></script>
+        <script src="../../../../../lib/GeoExt.js"></script>
+    
+        <script>
+        
+        function test_constructor(t) {
+            
+            t.plan(1);
+            
+            var store = new GeoExt.data.LayerStore();
+            
+            var node = new GeoExt.tree.LayerNode({
+                layer: "foo",
+                layerStore: store
+            });
+            
+            t.ok(node.layerStore === store, "layerStore set");
+            
+            node.destroy();
+            
+        }
+        
+        function test_render(t) {
+            
+            t.plan(5);
+            
+            var layer = new OpenLayers.Layer("foo");
+            
+            var mapPanel = new GeoExt.MapPanel({
+                layers: [layer],
+                allOverlays: true
+            });
+            
+            var node = new GeoExt.tree.LayerNode({
+                layer: "foo",
+                radioGroup: "group",
+                childNodeType: {
+                    add: function() {
+                        t.ok(true, "add function of childNodeType called");
+                    }
+                }
+            });
+            
+            node.on("radiochange", function() {
+                t.ok(arguments[0] === node, "radiochange event triggered with the selected node as first argument");
+            });
+                        
+            var panel = new Ext.tree.TreePanel({
+                renderTo: "tree",
+                root: node
+            });
+            
+            mapPanel.on("render", function() {
+                t.ok(node.layer === layer, "layer found on detected map panel");
+                
+                t.ok(node.ui.radio, "node has a radio button");
+                // simulate a click event for testing the radiochange event
+                node.ui.onClick({getTarget: function() {return true}});
+                
+                node.ui.toggleCheck();
+                t.eq(layer.visibility, false, "unchecking node hides layer");
+            });
+
+            mapPanel.render("map");
+            
+        }
+        
+        </script>
+    </head>
+    <body>
+        <div id="map" style="width: 100px; height: 100px;"></div>
+        <div id="tree" style="width: 100px; height: 100px;"></div>
+    </body>
+</html>
\ No newline at end of file

Modified: sandbox/elemoine/playground/geoext/tests/list-tests.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/list-tests.html	2009-05-20 06:30:32 UTC (rev 830)
+++ sandbox/elemoine/playground/geoext/tests/list-tests.html	2009-05-20 06:33:05 UTC (rev 831)
@@ -14,4 +14,6 @@
   <li>lib/GeoExt/widgets/form/SearchAction.html</li>
   <li>lib/GeoExt/widgets/form/BasicForm.html</li>
   <li>lib/GeoExt/widgets/form/FormPanel.html</li>
+  <li>lib/GeoExt/widgets/tree/LayerNode.html</li>
+  <li>lib/GeoExt/widgets/tree/LayerContainer.html</li>
 </ul>



More information about the Commits mailing list