[Commits] r1295 - in sandbox/elemoine/playground/geoext: examples lib/GeoExt/widgets/tree tests/lib/GeoExt/widgets/tree

commits at geoext.org commits at geoext.org
Wed Jul 29 16:06:15 CEST 2009


Author: elemoine
Date: 2009-07-29 16:06:15 +0200 (Wed, 29 Jul 2009)
New Revision: 1295

Added:
   sandbox/elemoine/playground/geoext/examples/delete.gif
   sandbox/elemoine/playground/geoext/examples/info.png
   sandbox/elemoine/playground/geoext/examples/move_down.png
   sandbox/elemoine/playground/geoext/examples/move_up.png
   sandbox/elemoine/playground/geoext/examples/tree-tools.html
   sandbox/elemoine/playground/geoext/examples/tree-tools.js
Modified:
   sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js
   sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html
Log:
ugly ugly code for demoing LayerNodeUI extensions


Added: sandbox/elemoine/playground/geoext/examples/delete.gif
===================================================================
(Binary files differ)


Property changes on: sandbox/elemoine/playground/geoext/examples/delete.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/elemoine/playground/geoext/examples/info.png
===================================================================
(Binary files differ)


Property changes on: sandbox/elemoine/playground/geoext/examples/info.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/elemoine/playground/geoext/examples/move_down.png
===================================================================
(Binary files differ)


Property changes on: sandbox/elemoine/playground/geoext/examples/move_down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/elemoine/playground/geoext/examples/move_up.png
===================================================================
(Binary files differ)


Property changes on: sandbox/elemoine/playground/geoext/examples/move_up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/elemoine/playground/geoext/examples/tree-tools.html
===================================================================
--- sandbox/elemoine/playground/geoext/examples/tree-tools.html	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/tree-tools.html	2009-07-29 14:06:15 UTC (rev 1295)
@@ -0,0 +1,67 @@
+<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.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+        -->
+
+        <script type"text/javascript" src="../../ext/adapter/ext/ext-base.js"></script>
+        <script type"text/javascript" src="../../ext/ext-all-debug.js"></script>
+        <link rel="stylesheet" type="text/css" href="../../ext/resources/css/ext-all.css"></script>
+
+        <script src="http://openlayers.org/api/2.8/OpenLayers.js"></script>
+        <script type="text/javascript" src="../lib/GeoExt.js"></script>
+
+        <script type="text/javascript" src="tree-tools.js"></script>
+
+        <style type="text/css">
+        .x-tree-node-actions{
+            float: right;
+            /*display: none;*/
+        }
+        .x-tree-node-action {
+            background-position:center center;
+            background-repeat:no-repeat;
+            border:0 none;
+            height:16px;
+            margin:0;
+            padding:0;
+            vertical-align:top;
+            width:16px;
+        }
+        .x-tree-node-actions .delete {
+            background:transparent url(delete.gif);
+        }
+        .x-tree-node-actions .move-up {
+            background:transparent url(move_up.png);
+        }
+        .x-tree-node-actions .move-down {
+            background:transparent url(move_down.png);
+        }
+        .info {
+            background-image:url(info.png) !important;
+            height:20px !important;
+            width:20px !important;
+        }
+        .gx-toolbar {
+            background:none;
+            border-style:none;
+        }
+        .x-tree-node-collapsed .x-tree-node-icon, .x-tree-node-expanded .x-tree-node-icon, .x-tree-node-leaf .gx-tree-layer-icon {
+           width: 0px; !important;
+        }
+    </style>
+
+    </head>
+    <body>
+        <div id="desc">
+            <h1>GeoExt.tree Components</h1>
+            <p>
+            <p>The js is not minified so it is readable. See
+            <a href="tree-tools.js">tree-tools.js</a>.</p>
+        </div>
+    </body>
+</html>

Added: sandbox/elemoine/playground/geoext/examples/tree-tools.js
===================================================================
--- sandbox/elemoine/playground/geoext/examples/tree-tools.js	                        (rev 0)
+++ sandbox/elemoine/playground/geoext/examples/tree-tools.js	2009-07-29 14:06:15 UTC (rev 1295)
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+Ext.onReady(function() {
+
+    var mapPanel = new GeoExt.MapPanel({
+        border: true,
+        region: "center",
+        //map: new OpenLayers.Map({allOverlays: false}),
+        center: [146.1569825, -41.6109735],
+        zoom: 6,
+        layers: [
+            new OpenLayers.Layer.WMS("Global Imagery",
+                "http://demo.opengeo.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
+                })
+        ]
+    });
+    
+    var tree = new Ext.tree.TreePanel({
+        border: true,
+        region: "west",
+        title: "Layers",
+        width: 300,
+        split: true,
+        collapsible: true,
+        //collapseMode: "mini",
+        autoScroll: true,
+        loader: {
+            applyLoader: false
+        },
+        root: {
+            nodeType: "gx_layercontainer",
+            loader: {
+                baseAttrs: {
+                    deleteAction: true,
+                    upAction: true,
+                    downAction: true,
+                    opacitySlider: true
+                }
+            }
+        },
+        rootVisible: false,
+        lines: false
+    });
+    
+    new Ext.Viewport({
+        layout: "fit",
+        hideBorders: true,
+        items: {
+            layout: "border",
+            deferredRender: false,
+            items: [mapPanel, tree]
+        }
+    });
+});

Modified: sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js
===================================================================
--- sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js	2009-07-29 09:38:05 UTC (rev 1294)
+++ sandbox/elemoine/playground/geoext/lib/GeoExt/widgets/tree/LayerNode.js	2009-07-29 14:06:15 UTC (rev 1295)
@@ -14,6 +14,9 @@
  *      Place in a separate file if this should be documented.
  */
 GeoExt.tree.LayerNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+    // FIXME
+    actionsCls: 'x-tree-node-actions',
+    actionCls: 'x-tree-node-action',
     
     /** private: property[radio]
      *  ``Ext.Element``
@@ -34,22 +37,114 @@
         if (a.checked === undefined) {
             a.checked = this.node.layer.getVisibility();
         }
-        GeoExt.tree.LayerNodeUI.superclass.render.call(this, bulkRender);
-        if (a.radioGroup && this.radio === null) {
-            this.radio = Ext.DomHelper.insertAfter(this.checkbox,
-                ['<input type="radio" class="gx-tree-layer-radio" name="',
-                a.radioGroup, '_radio"></input>'].join(""));
+        var rendered = this.rendered;
+        GeoExt.tree.LayerNodeUI.superclass.render.apply(this, arguments);
+        if(!rendered) {
+            var cb = this.checkbox;
+            var rg = a.radioGroup || this.radioGroup;
+            var cg = a.checkedGroup || this.checkedGroup;
+
+            if (rg && this.radio === null) {
+                this.radio = Ext.DomHelper.insertAfter(cb,
+                    ['<input type="radio" class="gx-tree-layer-radio" name="',
+                    rg, '_radio"></input>'].join(""));
+            }
+            if(cg) {
+                // replace the checkbox with a radio button
+                var radio = Ext.DomHelper.insertAfter(cb,
+                    ['<input type="radio" name="', cg,
+                    '_checkbox" class="', cb.className,
+                    cb.checked ? '" checked="checked"' : '',
+                    '"></input>'].join(""));
+                radio.defaultChecked = cb.defaultChecked;
+                Ext.get(cb).remove();
+                this.checkbox = radio;
+            }
+            this.enforceOneVisible();
+
+            var actions = a.actions || this.actions || [];
+            var deleteAction = a.deleteAction || this.deleteAction;
+            if(deleteAction) {
+                if(typeof deleteAction != "object") {
+                    deleteAction = {};
+                }
+                actions.push(Ext.apply({
+                    action: "delete",
+                    qtip: "delete"
+                }, deleteAction));
+            }
+            var upAction = a.upAction || this.upAction;
+            if(upAction) {
+                if(typeof upAction != "object") {
+                    upAction = {};
+                }
+                actions.push(Ext.apply({
+                    action: "move-up",
+                    qtip: "move up"
+                }, upAction));
+            }
+            var downAction = a.downAction || this.downAction;
+            if(downAction) {
+                if(typeof downAction != "object") {
+                    downAction = {};
+                }
+                actions.push(Ext.apply({
+                    action: "move-down",
+                    qtip: "move down"
+                }, downAction));
+            }
+            if(actions.length > 0) {
+                var html = ['<div class="', this.actionsCls, '">'];
+                for(var i=0,len=actions.length; i<len; i++) {
+                    var _a = actions[i];
+                    html = html.concat(['<img id="'+this.node.id+'_'+_a.action,
+                                 '" ext:qtip="'+_a.qtip,
+                                 '" src="'+this.emptyIcon,
+                                 '" class="'+this.actionCls+' '+_a.action+'" />'
+                                ]);
+                }
+                html.concat(['</div>']);
+                Ext.DomHelper.insertFirst(this.elNode, html.join(''));
+            }
+
+            var component = a.component || this.component;
+            var opacitySlider = a.opacitySlider || this.opacitySlider;
+            if(opacitySlider) {
+                // add div in the node
+                var elt = Ext.DomHelper.append(this.elNode, [
+                    {"tag": "div"}//, "style": "position:relative;left:20"}
+                ]);
+                var slider = new GeoExt.LayerOpacitySlider({
+                    layer: this.node.layer,
+                    width: 200
+                });
+                new Ext.Toolbar({
+                    renderTo: elt,
+                    cls: "gx-toolbar",
+                    buttons: [slider, "->", {
+                        iconCls: "info",
+                        handler: function() {
+                            new Ext.Window({
+                                html: this.node.layer.name,
+                                height: 200,
+                                width: 200
+                            }).show();
+                        },
+                        scope: this
+                    }]
+                });
+                /*
+                if(typeof comp == "function") {
+                    comp(this.node, elt);
+                } else if(typeof comp == "object" &&
+                          typeof comp.fn == "function") {
+                    comp.apply(comp.scope, [this.node, elt]);
+                } else if(comp instanceof Ext.Component) {
+                    comp.render(elt);
+                }
+                */
+            }
         }
-        if(a.checkedGroup) {
-            // replace the checkbox with a radio button
-            var radio = Ext.DomHelper.insertAfter(this.checkbox,
-                ['<input type="radio" name="', a.checkedGroup,
-                '_checkbox" class="', this.checkbox.className, 
-                this.checkbox.checked ? '" checked="checked"' : '',
-                '"></input>'].join(""));
-            Ext.get(this.checkbox).remove();
-            this.checkbox = radio;
-        }
     },
     
     /** private: method[onClick]
@@ -59,34 +154,89 @@
         if (e.getTarget('.gx-tree-layer-radio', 1)) {
             this.fireEvent("radiochange", this.node);
         } else if(e.getTarget('.x-tree-node-cb', 1)) {
-            GeoExt.tree.LayerNodeUI.superclass.onCheckChange.call(this);
+            this.onCheckChange();
+        } else if(e.getTarget('.' + this.actionCls, 1)) {
+            //var action = t.className.replace(this.actionCls + ' ', '');
+            //FIXME
+            alert("yo");
         } else {
-            GeoExt.tree.LayerNodeUI.superclass.onClick.call(this, e);
+            GeoExt.tree.LayerNodeUI.superclass.onClick.apply(this, arguments);
         }
     },
     
     /** private: method[toggleCheck]
-     *  :param value: ``Boolean``
+     * :param 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());
+        if(!this._visibilityChanging) {
+            this._visibilityChanging = true;
+            
+            // make sure we do not hide the checked layer from a checkedGroup
+            value = (value === undefined ? !this.isChecked() : value) ||
+                    (this.isChecked() && !!this.node.attributes.checkedGroup);
+            GeoExt.tree.LayerNodeUI.superclass.toggleCheck.call(this, value);
+            
+            this.enforceOneVisible();
+
+            delete this._visibilityChanging;
         }
-        node.visibilityChanging = false;
     },
     
+    /** private: method[enforceOneVisible]
+     * 
+     *  Makes sure that only one layer is visible if checkedGroup is set.
+     *  This can only work when ``layer.setVisibility()`` does not trigger
+     *  ``this.toggleCheck()``. If it does, ``this._visibilityChanging`` has
+     *  to be set to true before calling this method.
+     */
+    enforceOneVisible: function() {
+        var attributes = this.node.attributes;
+        var group = attributes.checkedGroup;
+        if(group) {
+            var layer = this.node.layer;
+            var checkedNodes = this.node.getOwnerTree().getChecked();
+            var checkedCount = 0;
+            // enforce "not more than one visible"
+            Ext.each(checkedNodes, function(n){
+                var ui = n.getUI();
+                var l = n.layer
+                if(!n.hidden && n.attributes.checkedGroup === group) {
+                    checkedCount++;
+                    if(l != layer && attributes.checked) {
+                        // toggleCheck won't be called (_visibilityChanging
+                        // set to true when we are called from toggleCheck(),
+                        // and layer visibility handler is not yet set when we
+                        // are called from render()), so we synchronize the
+                        // button state manually
+                        ui.checkbox.defaultChecked = false;
+                        ui.checkbox.checked = false;
+                        l.setVisibility(false);
+                    }
+                }
+            });
+            // enforce "at least one visible"
+            if(checkedCount === 0 && attributes.checked == false) {
+                var ui = this.node.getUI();
+                // toggleCheck won't be called (_visibilityChanging set to
+                // true when we are called from toggleCheck(), and layer
+                // visibility handler is not yet set when we are called from
+                // render()), so we synchronize the button state manually
+                ui.checkbox.defaultChecked = true;
+                ui.checkbox.checked = true;
+                layer.setVisibility(true);
+            }
+        }
+    },
+    
     /** private: method[destroy]
      */
     destroy: function() {
         delete this.radio;
-        GeoExt.tree.LayerNodeUI.superclass.destroy.call(this);
+        GeoExt.tree.LayerNodeUI.superclass.destroy.apply(this, arguments);
     }
 });
 
+
 /** api: (define)
  *  module = GeoExt.tree
  *  class = LayerNode
@@ -156,21 +306,15 @@
      */
     childNodeType: null,
     
-    /** private: 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,
-    
     /** private: method[constructor]
      *  Private constructor override.
      */
     constructor: function(config) {
         config.leaf = config.leaf || !config.children;
         
-        config.iconCls = typeof config.iconCls == "undefined" &&
-            !config.children ? "layer-icon" : config.iconCls;
+        if(!config.iconCls && !config.children) {
+            config.iconCls = "gx-tree-layer-icon";
+        }
         
         this.defaultUI = this.defaultUI || GeoExt.tree.LayerNodeUI;
         this.addEvents(
@@ -214,6 +358,13 @@
             
             if(layer) {
                 this.layer = layer;
+                // no DD and radio buttons for base layers
+                if(layer.isBaseLayer) {
+                    this.draggable = false;
+                    Ext.applyIf(this.attributes, {
+                        checkedGroup: "gx_baselayer"
+                    });
+                }
                 if(!this.text) {
                     this.text = layer.name;
                 }
@@ -232,7 +383,7 @@
                 this.addStoreEventHandlers(layer);
             }            
         }
-        GeoExt.tree.LayerNode.superclass.render.call(this, bulkRender);
+        GeoExt.tree.LayerNode.superclass.render.apply(this, arguments);
     },
     
     /** private: method[addVisibilityHandlers]
@@ -254,10 +405,7 @@
      *  handler for visibilitychanged events on the layer
      */
     onLayerVisibilityChanged: function() {
-        if(!this.visibilityChanging &&
-                this.attributes.checked != this.layer.getVisibility()) {
-            this.getUI().toggleCheck(this.layer.getVisibility());
-        }
+        this.getUI().toggleCheck(this.layer.getVisibility());
     },
     
     /** private: method[onCheckChange]
@@ -267,10 +415,14 @@
      *  handler for checkchange events 
      */
     onCheckChange: function(node, checked) {
-        if (checked && this.layer.isBaseLayer && this.layer.map) {
-            this.layer.map.setBaseLayer(this.layer);
+        if(checked != this.layer.getVisibility()) {
+            var layer = this.layer;
+            if(checked && layer.isBaseLayer && layer.map) {
+                layer.map.setBaseLayer(layer);
+            } else {
+                layer.setVisibility(checked);
+            }
         }
-        this.layer.setVisibility(checked);
     },
     
     /** private: method[addStoreEventHandlers]
@@ -299,12 +451,13 @@
             l = records[i].get("layer");
             if(this.layer == l) {
                 this.getUI().show();
+                break;
             } 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;
+                this.render();
+                break;
             }
         }
     },
@@ -369,7 +522,7 @@
         delete this.layerStore;
         this.un("checkchange", this.onCheckChange, this);
 
-        GeoExt.tree.LayerNode.superclass.destroy.call(this);
+        GeoExt.tree.LayerNode.superclass.destroy.apply(this, arguments);
     }
 });
 

Modified: sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html
===================================================================
--- sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	2009-07-29 09:38:05 UTC (rev 1294)
+++ sandbox/elemoine/playground/geoext/tests/lib/GeoExt/widgets/tree/LayerNode.html	2009-07-29 14:06:15 UTC (rev 1295)
@@ -26,7 +26,7 @@
         
         function test_render(t) {
             
-            t.plan(8);
+            t.plan(9);
             
             var layer = new OpenLayers.Layer("foo");
             
@@ -64,16 +64,93 @@
                 node.ui.onClick({getTarget: function() {return true}});
                 
                 t.eq(node.ui.checkbox.type, "radio", "checkbox rendered as radio button when checkedGroup is configured");
-                t.eq(node.ui.checkbox.name, "check_checkbox", "option group name set correclty according to checkedGroup");
+                t.eq(node.ui.checkbox.name, "check_checkbox", "option group name set correctly according to checkedGroup");
                 
+                layer.setVisibility(false);
+                t.eq(layer.visibility, true, "unchecking a layer with checkedGroup has no effect");
+                
+                delete node.attributes.checkedGroup;
                 node.ui.toggleCheck();
-                t.eq(layer.visibility, false, "unchecking node hides layer");
+                t.eq(layer.visibility, false, "unchecking a layer without checkedGroup hides the layer");
             });
 
             mapPanel.render("map");
             
+            mapPanel.destroy();
         }
+        
+        function test_enforceOneVisible(t) {
+            t.plan(8);
 
+            var layers = [
+                new OpenLayers.Layer("foo"),
+                new OpenLayers.Layer("bar")
+            ];
+            var mapPanel = new GeoExt.MapPanel({
+                layers: layers,
+                allOverlays: true
+            });
+            var root = new GeoExt.tree.LayerContainer({
+                loader: {
+                    baseAttrs: {checkedGroup: "group"}
+                },
+                expanded: true
+            });
+            var panel = new Ext.tree.TreePanel({
+                renderTo: "tree",
+                root: root
+            });
+            mapPanel.render("map");
+
+            // two overlay layers in the same checkedGroup: only one can be visible
+            var nodes = panel.getRootNode().childNodes;
+            t.eq(nodes[0].layer.getVisibility(), false, "Layer on top is hidden");
+            t.eq(nodes[1].layer.getVisibility(), true, "Layer on bottom is visible");
+            
+            delete root.loader.baseAttrs.checkedGroup;
+            mapPanel.map.allOverlays = false;
+            
+            // without a custom checkedGroup, base layers get the gx_baselayer group assigned
+            mapPanel.layers.on("add", function(){
+                t.eq(nodes[0].attributes.checkedGroup, "gx_baselayer", "gx_baselayer checkedGroup set for base layer");
+            }, this, {single: true});
+            mapPanel.map.addLayer(new OpenLayers.Layer("foo1", {isBaseLayer: true}));
+                        
+            root.loader.baseAttrs.checkedGroup = "another_group";
+            
+            // a custom checkedGroup will override the gx_baselayer default
+            mapPanel.layers.on("add", function() {
+                t.eq(nodes[0].attributes.checkedGroup, "another_group", "custom checkedGroup set for base layer");
+            }, this, {single: true});
+            mapPanel.map.addLayer(new OpenLayers.Layer("bar", {isBaseLayer: true}));
+            
+            // overlays also get the custom checkedGroup assigned
+            mapPanel.layers.on("add", function() {
+                t.eq(nodes[0].attributes.checkedGroup, "another_group", "custom checkedGroup set for overlay");
+                // the another_group baselayer from above is invisible (the gx_baselayer one is visible)
+                t.eq(nodes[0].layer.getVisibility(), true, "overlay in checkedGroup visible because no other layer in group is visible");
+                // now making it visible
+                nodes[1].layer.setVisibility(true);
+                // and the overlay in the same checkedGroup gets hidden
+                t.eq(nodes[0].layer.getVisibility(), false, "overlay in checkedGroup now hidden because base layer in group is visible");
+            }, this, {single: true});
+            mapPanel.map.addLayer(new OpenLayers.Layer("foo2", {isBaseLayer: false}));
+            
+            // remove all layers except one visible and one invisible layer
+            mapPanel.map.removeLayer(nodes[0].layer);
+            mapPanel.map.removeLayer(nodes[0].layer);
+            mapPanel.map.removeLayer(nodes[0].layer);
+            // now there is only one layer in the another_group
+            // "bar" (invisible) is now in the group at position [0], "foo" (visible) at [1]
+            mapPanel.layers.on("remove", function() {
+                t.eq(nodes[0].layer.getVisibility(), true, "Previously invisible layer was made visible because the visible layer has been removed")
+            }, this, {single: true});
+            // removing "foo", so "bar" will have to be made visible
+            mapPanel.map.removeLayer(nodes[1].layer);
+            
+            mapPanel.destroy();
+        }
+
         function test_changelayername(t) {
             t.plan(2);
 



More information about the Commits mailing list