/** * Copyright (c) 2008-2010 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.namespace("GeoExt.tree"); /** api: (define) * module = GeoExt.tree * class = LayerParamNode * base_link = `Ext.tree.TreeNode `_ */ /** api: constructor * .. class:: LayerParamNode * * A subclass of ``Ext.tree.TreeNode`` that represents a value of a list of * values provided as one of an ``OpenLayers.Layer.HTTPRequest``'s params. * The default iconCls for this node's icon is "gx-tree-layerparam-icon". * * To use this node type in a ``TreePanel`` config, set ``nodeType`` to * "gx_layerparam". */ GeoExt.tree.LayerParamNode = Ext.extend(Ext.tree.TreeNode, { /** api: config[layer] * ``OpenLayers.Layer.HTTPRequest|String`` The layer that this node * represents a subnode of. If provided as string, the string has to * match the title of one of the records in the ``layerStore``. */ /** private: property[layer] * ``OpenLayers.Layer.HTTPRequest`` */ layer: null, /** api: config[layerStore] * :class:`GeoExt.data.LayerStore` Only used if layer is provided as * string. The store where we can find the layer. If not provided, the * store of a map panel found by ``GeoExt.MapPanel::guess`` will be used. */ /** api: config[param] * ``String`` Key for a param (key-value pair in the params object of the * layer) that this node represents an item of. The value can either be an * ``Array`` or a ``String``, delimited by the character (or string) * provided as ``delimiter`` config option. */ /** private: property[param] * ``String`` */ param: null, /** api: config[item] * ``String`` The param's value's item that this node represents. */ /** private: property[item] * ``String`` */ item: null, /** api: config[delimiter] * ``String`` Delimiter of the ``param``'s value's items. Default is * ``,`` (comma). If the ``param``'s value is an array, this property * has no effect. */ /** private: property[delimiter] * ``String`` */ delimiter: null, /** private: property[allItems] * ``Array`` All items in the param value. */ allItems: null, /** private: method[constructor] * Private constructor override. */ constructor: function(attributes) { var config = attributes || {}; config.iconCls = config.iconCls || "gx-tree-layerparam-icon"; config.text = config.text || config.item; this.param = config.param; this.item = config.item; this.delimiter = config.delimiter || ","; this.allItems = config.allItems; GeoExt.tree.LayerParamNode.superclass.constructor.apply(this, arguments); this.getLayer(); if(this.layer) { // read items from layer if allItems isn't set // in the attributes if(!this.allItems) { this.allItems = this.getItemsFromLayer(); } // if the "checked" attribute isn't set we derive // it from what we have in the layer. Else, we need // to update the layer param based on the value of // the "checked" attribute if(this.attributes.checked == null) { this.attributes.checked = this.layer.getVisibility() && this.getItemsFromLayer().indexOf(this.item) >= 0; } else { this.onCheckChange(this, this.attributes.checked); } this.layer.events.on({ "visibilitychanged": this.onLayerVisibilityChanged, scope: this }); this.on({ "checkchange": this.onCheckChange, scope: this }); } }, /** private: method[getLayer] * :return: ``OpenLayers.Layer.HTTPRequest`` the layer * * Sets this.layer and returns the layer. */ getLayer: function() { if(!this.layer) { var layer = this.attributes.layer; if(typeof layer == "string") { var store = this.attributes.layerStore || GeoExt.MapPanel.guess().layers; var i = store.findBy(function(o) { return o.get("title") == layer; }); layer = i != -1 ? store.getAt(i).getLayer() : null; } this.layer = layer; } return this.layer; }, /** private: method[getItemsFromLayer] * :return: ``Array`` the items of this node's layer's param */ getItemsFromLayer: function() { var paramValue = this.layer.params[this.param]; return paramValue instanceof Array ? paramValue : (paramValue ? paramValue.split(this.delimiter) : []); }, /** private: method[createParams] * :param items: ``Array`` * :return: ``Object`` The params object to pass to mergeNewParams */ createParams: function(items) { var params = {}; params[this.param] = this.layer.params[this.param] instanceof Array ? items : items.join(this.delimiter); return params; }, /** private: method[onLayerVisibilityChanged] * Handler for visibilitychanged events on the layer. */ onLayerVisibilityChanged: function() { if(this.getItemsFromLayer().length === 0) { this.layer.mergeNewParams(this.createParams(this.allItems)); } var visible = this.layer.getVisibility(); if(visible && this.getItemsFromLayer().indexOf(this.item) !== -1) { this.getUI().toggleCheck(true); } if(!visible) { this.layer.mergeNewParams(this.createParams([])); this.getUI().toggleCheck(false); } }, /** private: method[onCheckChange] * :param node: :class:`GeoExt.tree.LayerParamNode`` * :param checked: ``Boolean`` * * Handler for checkchange events. */ onCheckChange: function(node, checked) { var layer = this.layer; var newItems = []; var curItems = this.getItemsFromLayer(); // if the layer is invisible, and a subnode is checked for the first // time, we need to pretend that no subnode param items are set. if(checked === true && layer.getVisibility() === false && curItems.length === this.allItems.length) { curItems = []; } Ext.each(this.allItems, function(item) { if((item !== this.item && curItems.indexOf(item) !== -1) || (checked === true && item === this.item)) { newItems.push(item); } }, this); var visible = (newItems.length > 0); // if there is something to display, we want to update the params // before the layer is turned on visible && layer.mergeNewParams(this.createParams(newItems)); if(visible !== layer.getVisibility()) { layer.setVisibility(visible); } // if there is nothing to display, we want to update the params // when the layer is turned off, so we don't fire illegal requests // (i.e. param value being empty) (!visible) && layer.mergeNewParams(this.createParams([])); }, /** private: method[destroy] */ destroy: function() { var layer = this.layer; if (layer instanceof OpenLayers.Layer) { layer.events.un({ "visibilitychanged": this.onLayerVisibilityChanged, scope: this }); } delete this.layer; this.un("checkchange", this.onCheckChange, this); GeoExt.tree.LayerParamNode.superclass.destroy.apply(this, arguments); } }); /** * NodeType: gx_layerparam */ Ext.tree.TreePanel.nodeTypes.gx_layerparam = GeoExt.tree.LayerParamNode;