Changeset 262


Ignore:
Timestamp:
03/24/09 14:27:23 (9 years ago)
Author:
ahocevar
Message:

updated to treenodes.2.patch, but only TristateCheckboxNode, LayerNode and LayerContainer (see #22)

Location:
sandbox/opengeo/geoexplorer
Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/MapPanel.js

    r238 r262  
    150150});
    151151
     152/**
     153 * APIFunction GeoExt.MapPanel.guess
     154 * Convenience function for guessing the map panel of an application. This can
     155 * reliably be used for all applications that just have one map panel in the
     156 * viewport.
     157 *
     158 * Returns:
     159 * {<GeoExt.MapPanel>} The first map panel found by the Ext component manager.
     160 */
     161GeoExt.MapPanel.guess = function() {
     162    return Ext.ComponentMgr.all.find(function(o) {
     163            return o instanceof GeoExt.MapPanel;
     164        });
     165}
     166
    152167Ext.reg('gx_mappanel', GeoExt.MapPanel);
  • sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerContainer.js

    r249 r262  
    1212 * for base layers, and to "layer-icon" for overlay layers.
    1313 *
    14  * To use this node type in JSON config, set nodeType to "gxLayerContainer".
     14 * To use this node type in JSON config, set nodeType to "olLayerContainer".
    1515 *
    1616 * Inherits from:
     
    1919GeoExt.tree.LayerContainer = Ext.extend(Ext.tree.TreeNode, {
    2020   
     21    layerStore: null,
     22   
    2123    /**
    22      * ConfigProperty: map
    23      * {OpenLayers.Map} or {String} - map or id of an {Ext.Component} that
    24      *     has a map property with an {OpenLayers.Map} set. This node will
    25      *     be connected to that map. If omitted, the node will query the
    26      *     ComponentManager for the first component that has a map property
    27      *     with an {OpenLayers.Map} set.
     24     * ConfigProperty: defaults
     25     * {Object} a configuration object passed to all nodes that this
     26     *     LayerContainer creates.
    2827     */
    29     map: null,
     28    defaults: null,
    3029
    3130    /**
     
    3635     */
    3736    constructor: function(config) {
    38         this.map = config.map;
    39        
    40         this.addEvents("customizeconfig");
    41        
     37        this.layerStore = config.layerStore;
     38        this.defaults = config.defaults;
    4239        GeoExt.tree.LayerContainer.superclass.constructor.apply(this, arguments);
    4340    },
     
    5148    render: function(bulkRender) {
    5249        if (!this.rendered) {
    53             var map = this.map instanceof OpenLayers.Map ? this.map :
    54                 (typeof this.map == "string" ? Ext.getCmp(this.map).map :
    55                 Ext.ComponentMgr.all.find(function(o) {
    56                     return o.map instanceof OpenLayers.Map;
    57                 }).map);
    58             if (map.layers) {
    59                 var layer, node;
    60                 for (var i = 0, len = map.layers.length; i < len; ++i) {
    61                     layer = map.layers[i];
    62                     this.addLayerNode(layer);
    63                 }
     50            if(!this.layerStore) {
     51                this.layerStore = GeoExt.MapPanel.guess().layers;
    6452            }
    65             map.events.register("addlayer", this, function(e) {
    66                 this.addLayerNode(e.layer);
    67             });
    68             map.events.register("removelayer", this, function(e) {
    69                 this.removeLayerNode(e.layer);
     53            this.layerStore.each(function(record) {
     54                this.addLayerNode(record);
     55            }, this)
     56            this.layerStore.on({
     57                "add": function(store, records, index){
     58                    for(var i=0; i<records.length; ++i) {
     59                        this.addLayerNode(records[i]);
     60                    }
     61                },
     62                "remove": function(store, record, index) {
     63                    this.removeLayerNode(record);
     64                },
     65                scope: this
    7066            });
    7167        }
     
    7874     *
    7975     * Parameters:
    80      * layer - {OpenLayers.Layer} the layer to add a node for
     76     * layerRecord - {Ext.data.Record} the layer record to add the layer for
    8177     */
    82     addLayerNode: function(layer) {
     78    addLayerNode: function(layerRecord) {
     79        var layer = layerRecord.get("layer");
    8380        if (layer.displayInLayerSwitcher == true) {
    84 
    85             var config = {
    86                 iconCls: layer.isBaseLayer ? 'baselayer-icon' : 'layer-icon',
    87                 layer: layer
    88             }
    89 
    90             this.fireEvent("customizeconfig", config, layer);
    91 
    92             node = new GeoExt.tree.LayerNode(config);
    93 
     81            var node = new GeoExt.tree.LayerNode(Ext.applyIf({
     82                iconCls: layer.isBayeLayer ? 'baselayer-icon' : 'layer-icon',
     83                layer: layer,
     84                layerStore: this.layerStore
     85            }, this.defaults));
    9486            this.appendChild(node);
    9587        }
     
    10193     *
    10294     * Parameters:
    103      * layer - {OpenLayers.Layer} the layer to remove the node for
     95     * layerRecord - {Ext.data.Record} the layer record to remove the node for
    10496     */
    105     removeLayerNode: function(layer) {
     97    removeLayerNode: function(layerRecord) {
     98        var layer = layerRecord.get("layer");
    10699        if (layer.displayInLayerSwitcher == true) {
    107100            var node = this.findChildBy(function(node) {
     
    116109
    117110/**
    118  * NodeType: gxLayerContainer
     111 * NodeType: gx_layercontainer
    119112 */
    120 Ext.tree.TreePanel.nodeTypes.gxLayerContainer = GeoExt.tree.LayerContainer;
     113Ext.tree.TreePanel.nodeTypes.gx_layercontainer = GeoExt.tree.LayerContainer;
  • sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerNode.js

    r249 r262  
    11/**
    22 * Copyright (c) 2008 The Open Planning Project
    3  *
    4  * @requires GeoExt/widgets/tree/TristateCheckboxNode.js
    53 */
    64Ext.namespace("GeoExt.tree");
    75
    86/**
     7 * Class: GeoExt.tree.LayerNodeUI
     8 *
     9 * Inherits from:
     10 * - <GeoExt.tree.TristateCheckboxNodeUI>
     11 */
     12GeoExt.tree.LayerNodeUI = Ext.extend(GeoExt.tree.TristateCheckboxNodeUI, {
     13   
     14    /**
     15     * Property: radio
     16     * {Ext.Element}
     17     */
     18    radio: null,
     19   
     20    /**
     21     * Constructor: GeoExt.tree.LayerNodeUI
     22     *
     23     * Parameters:
     24     * config - {Object}
     25     */
     26    constructor: function(config) {
     27        GeoExt.tree.LayerNodeUI.superclass.constructor.apply(this, arguments);
     28    },
     29   
     30    /**
     31     * Method: render
     32     *
     33     * Parameters:
     34     * bulkRender - {Boolean}
     35     */
     36    render: function(bulkRender) {
     37        GeoExt.tree.LayerNodeUI.superclass.render.call(this, bulkRender);
     38        var a = this.node.attributes;
     39        if (a.radioGroup && !this.radio) {
     40            this.radio = Ext.DomHelper.insertAfter(this.checkbox,
     41                ['<input type="radio" class="x-tree-node-cb" name="',
     42                a.radioGroup, '_querylayer"></input>'].join(""));
     43        }
     44    },
     45   
     46    /**
     47     * Method: onClick
     48     *
     49     * Parameters:
     50     * e - {Object}
     51     */
     52    onClick: function(e) {
     53        if (e.getTarget('input[type=radio]', 1)) {
     54            this.fireEvent("querylayerchange", this.node.layer);
     55        } else {
     56            GeoExt.tree.LayerNodeUI.superclass.onClick.call(this, e);
     57        }
     58    },
     59   
     60    /**
     61     * Method: toggleCheck
     62     *
     63     * Parameters:
     64     * value - {Boolean}
     65     */
     66    toggleCheck: function(value) {
     67        GeoExt.tree.LayerNodeUI.superclass.toggleCheck.apply(this, arguments);
     68        var node = this.node;
     69        var layer = this.node.layer;
     70        node.visibilityChanging = true;
     71        if(layer.getVisibility() != value) {
     72            layer.setVisibility(value);
     73        }
     74        node.visibilityChanging = false;
     75    },
     76   
     77    /**
     78     * Method: destroy
     79     */
     80    destroy: function() {
     81        GeoExt.tree.LayerNodeUI.superclass.destroy.call(this);
     82        delete this.radio;
     83    }
     84});
     85
     86
     87/**
    988 * Class: GeoExt.tree.LayerNode
    1089 *
    11  * A subclass of {Ext.tree.AsyncTreeNode} that is connected to an
     90 * A subclass of {<GeoExt.tree.TristateCheckboxNode>} that is connected to an
    1291 * {OpenLayers.Layer} by setting the node's layer property. Checking or
    1392 * unchecking the checkbox of this node will directly affect the layer and
     
    28107 * attribute, set to the map's id, will be added to the attributes hash.
    29108 *
    30  * To use this node type in a JSON config, set nodeType to "gxLayer".
     109 * To use this node type in a JSON config, set nodeType to "olLayer".
    31110 *
    32111 * Inherits from:
     
    37116    /**
    38117     * ConfigProperty: layer
    39      * {OpenLayers.Layer} or {String}. The layer that this layer node will
    40      * be bound to, or the name of the layer (has to match the layer's name
    41      * property). Subclasses or applications can always rely on finding an
    42      * {OpenLayers.Layer} object in attributes.layer.
     118     * {OpenLayers.Layer|String} The layer that this layer node will
     119     *     be bound to, or the name of the layer (has to match the layer's
     120     *     name property). If a layer name is provided, <layerStore> also has
     121     *     to be provided.
    43122     */
    44123    layer: null,
    45124   
    46125    /**
    47      * ConfigProperty: map
    48      * {OpenLayers.Map} or {String}. Map or id of an {Ext.Component} that
    49      * has a map property with an {OpenLayers.Map} set. This node will
    50      * be connected to that map. If omitted, the node will query the
    51      * ComponentManager for the first component that has a map property
    52      * with an {OpenLayers.Map} set.
    53      */
    54     map: null,
    55    
    56     /**
    57      * Property: haveLayer
    58      * {Boolean} will be set to true as soon as this node is connected to a
    59      * layer.
    60      */
    61     haveLayer: null,
    62    
    63     /**
    64      * Property: updating
    65      * {Boolean} The visibility status of the layer is being updated by itself
    66      *     (i.e. not by clicking on this node, but by layer visibilitychanged)
    67      */
    68     updating: false,
    69 
     126     * ConfigProperty: layerStore
     127     * {<GeoExt.data.LayerStore|"auto"} The layer store containing the layer
     128     *     that this node represents. If set to "auto", the node will query
     129     *     the ComponentManager for a <GeoExt.MapPanel>, take the first one it
     130     *     finds and takes its layer store. This property is only required
     131     *     if <layer> is provided as a string.
     132     */
     133    layerStore: null,
     134   
     135    /**
     136     * ConfigProperty: childNodeType
     137     * {Ext.tree.Node|String} node class or nodeType of childnodes for this
     138     *     node. A node type provided here needs to have an add method, with
     139     *     a scope argument. This method will be run by this node in the
     140     *     context of this node, to create child nodes. See
     141     *     {<GeoExt.tree.LayerParamsNode>} for an example implementation that
     142     *     adds nodes based on a layer's params object.
     143     */
     144    childNodeType: null,
     145   
     146    /**
     147     * Property: visibilityChanging
     148     * {Boolean} private property indicating layer visibility being changed
     149     *     by this node in order to prevent visibilitychanged events bouncing
     150     *     back and forth
     151     */
     152    visibilityChanging: false,
     153   
    70154    /**
    71155     * Constructor: GeoExt.tree.LayerNode
     
    75159     */
    76160    constructor: function(config) {
    77         this.layer = config.layer;
    78         this.map = config.map;
    79         this.haveLayer = false;
    80 
    81161        config.leaf = config.leaf || !config.children;
     162       
    82163        config.iconCls = typeof config.iconCls == "undefined" &&
    83164            !config.children ? "layer-icon" : config.iconCls;
     
    89170        this.addEvents.apply(this, GeoExt.tree.LayerNode.EVENT_TYPES);
    90171       
     172        Ext.apply(this, {
     173            layer: config.layer,
     174            layerStore: config.layerStore,
     175            childNodeType: config.childNodeType
     176        });
    91177        GeoExt.tree.LayerNode.superclass.constructor.apply(this, arguments);
    92178    },
     
    100186     */
    101187    render: function(bulkRender) {
    102         if (!this.rendered || !this.haveLayer) {
    103             var map = this.map instanceof OpenLayers.Map ? this.map :
    104                 (typeof this.map == "string" ? Ext.getCmp(this.map).map :
    105                 Ext.ComponentMgr.all.find(function(o) {
    106                     return o.map instanceof OpenLayers.Map;
    107                 }).map);
    108             var layer = this.attributes.layer || this.layer;
    109             this.haveLayer = layer && typeof layer == "object";
    110             if(typeof layer == "string") {
    111                 var matchingLayers = map.getLayersByName(layer);
    112                 if(matchingLayers.length > 0) {
    113                     layer = matchingLayers[0];
    114                     this.haveLayer = true;
    115                 }
     188        var layer = this.layer instanceof OpenLayers.Layer && this.layer;
     189        if(!layer) {
     190            // guess the store if not provided
     191            if(!this.layerStore || this.layerStore == "auto") {
     192                this.layerStore = GeoExt.MapPanel.guess().layers;
    116193            }
     194            // now we try to find the layer by its name in the layer store
     195            var i = this.layerStore.findBy(function(o) {
     196                return o.get("title") == this.layer;
     197            }, this);
     198            if(i != -1) {
     199                // if we found the layer, we can assign it and everything
     200                // will be fine
     201                layer = this.layerStore.getAt(i).get("layer");
     202            }
     203        }
     204        if (!this.rendered || !layer) {
    117205            var ui = this.getUI();
    118             if(this.haveLayer) {
    119                 this.attributes.layer = layer;
    120                 if(layer.queryable == true) {
    121                     this.attributes.radioGroup = layer.map.id;
    122                 }
     206           
     207            if(layer) {
     208                this.layer = layer;
    123209                if(!this.text) {
    124210                    this.text = layer.name;
    125211                }
     212               
     213                if(this.childNodeType) {
     214                    this.addChildNodes();
     215                }
     216               
    126217                ui.show();
    127218                ui.toggleCheck(layer.getVisibility());
    128                 layer.events.register("visibilitychanged", this, function(){
    129                     this.updating = true;
    130                     if(this.attributes.checked != layer.getVisibility()) {
    131                         ui.toggleCheck(layer.getVisibility());
    132                     }
    133                     this.updating = false;
    134                 });
    135                 this.on("checkchange", function(node, checked){
    136                     if(!this.updating) {
    137                         if(checked && layer.isBaseLayer) {
    138                             map.setBaseLayer(layer);
    139                         }
    140                         layer.setVisibility(checked);
    141                     }
    142                 }, this);
    143                
     219                this.addVisibilityEventHandlers();
    144220                // set initial checked status
    145221                this.attributes.checked = layer.getVisibility();
     
    147223                ui.hide();
    148224            }
    149             map.events.register("addlayer", this, function(e) {
    150                 if(layer == e.layer) {
    151                     this.getUI().show();
    152                 } else if (layer == e.layer.name) {
    153                     // layer is a string, which means the node has not
    154                     // yet been rendered because the layer was not found.
    155                     // But now we have the layer and can render.
    156                     this.render(bulkRender);
    157                     return;
    158                 }
    159             });
    160             map.events.register("removelayer", this, function(e) {
    161                 if(layer == e.layer) {
     225           
     226            if(this.layerStore instanceof GeoExt.data.LayerStore) {
     227                this.addStoreEventHandlers(layer);
     228            }           
     229        }
     230        GeoExt.tree.LayerNode.superclass.render.call(this, bulkRender);
     231    },
     232   
     233    /**
     234     * Method: addVisibilityHandlers
     235     * Adds handlers that sync the checkbox state with the layer's visibility
     236     * state
     237     */
     238    addVisibilityEventHandlers: function() {
     239        this.layer.events.register("visibilitychanged", this, function() {
     240            if(!this.visibilityChanging &&
     241                    this.attributes.checked != this.layer.getVisibility()) {
     242                this.getUI().toggleCheck(this.layer.getVisibility());
     243            }
     244        });
     245        this.on({
     246            "checkchange": function(node, checked) {
     247                if (checked && this.layer.isBaseLayer) {
     248                    this.layer.map.setBaseLayer(this.layer);
     249                }
     250                this.layer.setVisibility(checked);
     251            },
     252            scope: this
     253        });
     254    },
     255   
     256    /**
     257     * Method: addStoreEventHandlers
     258     * Adds handlers that make sure the node disappeares when the layer is
     259     * removed from the store, and appears when it is re-added.
     260     */
     261    addStoreEventHandlers: function() {
     262        this.layerStore.on({
     263            "add": function(store, records, index) {
     264                var l;
     265                for(var i=0; i<records.length; ++i) {
     266                    l = records[i].get("layer");
     267                    if(this.layer == l) {
     268                        this.getUI().show();
     269                    } else if (this.layer == l.name) {
     270                        // layer is a string, which means the node has not yet
     271                        // been rendered because the layer was not found. But
     272                        // now we have the layer and can render.
     273                        this.render(bulkRender);
     274                        return;
     275                    }
     276                }
     277            },
     278            "remove": function(store, record, index) {
     279                if(this.layer == record.get("layer")) {
    162280                    this.getUI().hide();
    163281                }
    164             });
    165         }
    166         GeoExt.tree.LayerNode.superclass.render.call(this, bulkRender);
    167     }
     282            },
     283            scope: this
     284        });
     285    },
     286   
     287    /**
     288     * Method: addChildNodes
     289     * If the layer's layers param is an array of layer names, a subnode for
     290     * each name will be created.
     291     */
     292    addChildNodes: function() {
     293        if(typeof this.childNodeType == "string") {
     294            Ext.tree.TreePanel.nodeTypes[this.childNodeType].add(this);
     295        } else if(this.childNodeType.add) {
     296            this.childNodeType.add(this);
     297        }
     298    },
     299
     300    /**
     301     * Method: updateCheckedChildNodes
     302     *
     303     * Parameters:
     304     * node - {Ext.tree.node}
     305     * checked - {Boolean}
     306     */
     307    updateCheckedChildNodes: function(node, checked) {
     308        GeoExt.tree.LayerNode.superclass.updateCheckedChildNodes.call(this,
     309            node, checked);
     310    }   
    168311});
    169312
     
    180323
    181324/**
    182  * NodeType: gxLayer
    183  */
    184 Ext.tree.TreePanel.nodeTypes.gxLayer = GeoExt.tree.LayerNode;
     325 * NodeType: gx_layer
     326 */
     327Ext.tree.TreePanel.nodeTypes.gx_layer = GeoExt.tree.LayerNode;
  • sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/TristateCheckboxNode.js

    r249 r262  
    33 */
    44Ext.namespace("GeoExt.tree");
     5
     6/**
     7 * Class: GeoExt.tree.TristateCheckboxNodeUI
     8 *
     9 * Inherits from:
     10 * - <Ext.tree.TreeNodeUI>
     11 */
     12GeoExt.tree.TristateCheckboxNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
     13   
     14    /**
     15     * Constructor: GeoExt.tree.TristateCheckbosNodeUI
     16     *
     17     * Parameters:
     18     * config - {Object}
     19     */
     20    constructor: function(config) {
     21        GeoExt.tree.TristateCheckboxNodeUI.superclass.constructor.apply(this, arguments);
     22    },
     23   
     24    /**
     25     * Method: toggleCheck
     26     *
     27     * Parameters:
     28     * value - {Boolean} checked status
     29     * thirdState - {Boolean}
     30     * options - {Object} Hash of options for this method
     31     *
     32     * Currently supported options:
     33     * silent - {Boolean} set to true if no checkchange event should be
     34     *     fired
     35     */
     36    toggleCheck: function(value, thirdState, options) {
     37        options = options || {}
     38        var cb = this.checkbox;
     39        if(thirdState == true) {
     40            if(cb) {
     41                Ext.get(cb).setOpacity(0.5);
     42            }
     43            this.node.attributes.thirdState = true;
     44        } else {
     45            if(cb) {
     46                Ext.get(cb).clearOpacity();
     47            }
     48            delete this.node.attributes.thirdState;
     49        }
     50
     51        options.silent && this.node.suspendEvents();
     52        GeoExt.tree.TristateCheckboxNodeUI.superclass.toggleCheck.call(this,
     53            value);
     54        options.silent && this.node.resumeEvents();
     55    }
     56});
    557
    658/**
     
    2577 *
    2678 * Inherits from:
    27  * - <Ext.tree.TreeNode>
    28  */
    29 GeoExt.tree.TristateCheckboxNode = Ext.extend(Ext.tree.TreeNode, {
     79 * - <Ext.tree.AsyncTreeNode>
     80 */
     81GeoExt.tree.TristateCheckboxNode = Ext.extend(Ext.tree.AsyncTreeNode, {
    3082   
    3183    /**
    3284     * Property: checkedChildNodes
    3385     * {Object} Hash of 0.1 for thirdState nodes and 1 for fully checked
    34      *     nodes, keyed by node ids. In combination with
    35      *     {<checkedCount>}, this provides an
    36      *     efficient way of keeping track of the childnodes' checked status.
     86     *     nodes, keyed by node ids. In combination with <checkedCount>,
     87     *     this provides an efficient way of keeping track of the childnodes'
     88     *     checked state.
    3789     */
    3890    checkedChildNodes: null,
     
    140192        // parent.
    141193        node.on("checkchange", function(node, checked) {
    142             if (this.childrenRendered) {
     194            if(this.childrenRendered) {
    143195                this.fireEvent("childcheckchange", node, checked);
    144196            }
     
    186238 *
    187239 * Event types supported for this class, in additon to the ones inherited
    188  * from {<GeoExt.tree.TristateCheckboxNode>}:
     240 * from {<Ext.tree.AsyncTreeNode>}:
    189241 * - *childcheckchange* fired to notify a parent node that the status of
    190242 *     its checked child nodes has changed
     
    193245
    194246/**
    195  * NodeType: tristateCheckbox
    196  */
    197 Ext.tree.TreePanel.nodeTypes.tristateCheckbox = GeoExt.tree.TristateCheckboxNode;
     247 * NodeType: gx_tristatecheckbox
     248 */
     249Ext.tree.TreePanel.nodeTypes.gx_tristatecheckbox = GeoExt.tree.TristateCheckboxNode;
  • sandbox/opengeo/geoexplorer/tests/widgets/MapPanel.html

    r238 r262  
    3636
    3737        function test_mappanel(t) {
    38             t.plan(2)
     38            t.plan(3)
    3939           
    4040            loadMapPanel();
    4141            t.eq(mapPanel.map.getCenter().toString(), "lon=5,lat=45", "Map center set correctly");
    4242            t.eq(mapPanel.map.getZoom(), 4, "Zoom set correctly");
     43            t.eq(GeoExt.MapPanel.guess().id, mapPanel.id, "MapPanel guessed correctly");
    4344        }
    4445
Note: See TracChangeset for help on using the changeset viewer.