Changeset 262
- Timestamp:
- 03/24/09 14:27:23 (1 year ago)
- Files:
-
- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/MapPanel.js (modified) (1 diff)
- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerContainer.js (modified) (7 diffs)
- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerNode.js (modified) (8 diffs)
- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/TristateCheckboxNode.js (modified) (5 diffs)
- sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/TristateCheckboxNodeUI.js (deleted)
- sandbox/opengeo/geoexplorer/tests/widgets/MapPanel.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/MapPanel.js
r238 r262 150 150 }); 151 151 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 */ 161 GeoExt.MapPanel.guess = function() { 162 return Ext.ComponentMgr.all.find(function(o) { 163 return o instanceof GeoExt.MapPanel; 164 }); 165 } 166 152 167 Ext.reg('gx_mappanel', GeoExt.MapPanel); sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerContainer.js
r249 r262 12 12 * for base layers, and to "layer-icon" for overlay layers. 13 13 * 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". 15 15 * 16 16 * Inherits from: … … 19 19 GeoExt.tree.LayerContainer = Ext.extend(Ext.tree.TreeNode, { 20 20 21 layerStore: null, 22 21 23 /** 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. 28 27 */ 29 map: null,28 defaults: null, 30 29 31 30 /** … … 36 35 */ 37 36 constructor: function(config) { 38 this.map = config.map; 39 40 this.addEvents("customizeconfig"); 41 37 this.layerStore = config.layerStore; 38 this.defaults = config.defaults; 42 39 GeoExt.tree.LayerContainer.superclass.constructor.apply(this, arguments); 43 40 }, … … 51 48 render: function(bulkRender) { 52 49 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; 64 52 } 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 70 66 }); 71 67 } … … 78 74 * 79 75 * Parameters: 80 * layer - {OpenLayers.Layer} the layer to add a nodefor76 * layerRecord - {Ext.data.Record} the layer record to add the layer for 81 77 */ 82 addLayerNode: function(layer) { 78 addLayerNode: function(layerRecord) { 79 var layer = layerRecord.get("layer"); 83 80 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)); 94 86 this.appendChild(node); 95 87 } … … 101 93 * 102 94 * Parameters: 103 * layer - {OpenLayers.Layer} the layerto remove the node for95 * layerRecord - {Ext.data.Record} the layer record to remove the node for 104 96 */ 105 removeLayerNode: function(layer) { 97 removeLayerNode: function(layerRecord) { 98 var layer = layerRecord.get("layer"); 106 99 if (layer.displayInLayerSwitcher == true) { 107 100 var node = this.findChildBy(function(node) { … … 116 109 117 110 /** 118 * NodeType: gx LayerContainer111 * NodeType: gx_layercontainer 119 112 */ 120 Ext.tree.TreePanel.nodeTypes.gx LayerContainer = GeoExt.tree.LayerContainer;113 Ext.tree.TreePanel.nodeTypes.gx_layercontainer = GeoExt.tree.LayerContainer; sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/LayerNode.js
r249 r262 1 1 /** 2 2 * Copyright (c) 2008 The Open Planning Project 3 *4 * @requires GeoExt/widgets/tree/TristateCheckboxNode.js5 3 */ 6 4 Ext.namespace("GeoExt.tree"); 7 5 8 6 /** 7 * Class: GeoExt.tree.LayerNodeUI 8 * 9 * Inherits from: 10 * - <GeoExt.tree.TristateCheckboxNodeUI> 11 */ 12 GeoExt.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 /** 9 88 * Class: GeoExt.tree.LayerNode 10 89 * 11 * A subclass of { Ext.tree.AsyncTreeNode} that is connected to an90 * A subclass of {<GeoExt.tree.TristateCheckboxNode>} that is connected to an 12 91 * {OpenLayers.Layer} by setting the node's layer property. Checking or 13 92 * unchecking the checkbox of this node will directly affect the layer and … … 28 107 * attribute, set to the map's id, will be added to the attributes hash. 29 108 * 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". 31 110 * 32 111 * Inherits from: … … 37 116 /** 38 117 * ConfigProperty: layer 39 * {OpenLayers.Layer } or {String}.The layer that this layer node will40 * be bound to, or the name of the layer (has to match the layer's name41 * property). Subclasses or applications can always rely on finding an42 * {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. 43 122 */ 44 123 layer: null, 45 124 46 125 /** 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 70 154 /** 71 155 * Constructor: GeoExt.tree.LayerNode … … 75 159 */ 76 160 constructor: function(config) { 77 this.layer = config.layer;78 this.map = config.map;79 this.haveLayer = false;80 81 161 config.leaf = config.leaf || !config.children; 162 82 163 config.iconCls = typeof config.iconCls == "undefined" && 83 164 !config.children ? "layer-icon" : config.iconCls; … … 89 170 this.addEvents.apply(this, GeoExt.tree.LayerNode.EVENT_TYPES); 90 171 172 Ext.apply(this, { 173 layer: config.layer, 174 layerStore: config.layerStore, 175 childNodeType: config.childNodeType 176 }); 91 177 GeoExt.tree.LayerNode.superclass.constructor.apply(this, arguments); 92 178 }, … … 100 186 */ 101 187 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; 116 193 } 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) { 117 205 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; 123 209 if(!this.text) { 124 210 this.text = layer.name; 125 211 } 212 213 if(this.childNodeType) { 214 this.addChildNodes(); 215 } 216 126 217 ui.show(); 127 218 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(); 144 220 // set initial checked status 145 221 this.attributes.checked = layer.getVisibility(); … … 147 223 ui.hide(); 148 224 } 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")) { 162 280 this.getUI().hide(); 163 281 } 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 } 168 311 }); 169 312 … … 180 323 181 324 /** 182 * NodeType: gx Layer183 */ 184 Ext.tree.TreePanel.nodeTypes.gx Layer = GeoExt.tree.LayerNode;325 * NodeType: gx_layer 326 */ 327 Ext.tree.TreePanel.nodeTypes.gx_layer = GeoExt.tree.LayerNode; sandbox/opengeo/geoexplorer/lib/GeoExt/widgets/tree/TristateCheckboxNode.js
r249 r262 3 3 */ 4 4 Ext.namespace("GeoExt.tree"); 5 6 /** 7 * Class: GeoExt.tree.TristateCheckboxNodeUI 8 * 9 * Inherits from: 10 * - <Ext.tree.TreeNodeUI> 11 */ 12 GeoExt.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 }); 5 57 6 58 /** … … 25 77 * 26 78 * Inherits from: 27 * - <Ext.tree. TreeNode>28 */ 29 GeoExt.tree.TristateCheckboxNode = Ext.extend(Ext.tree. TreeNode, {79 * - <Ext.tree.AsyncTreeNode> 80 */ 81 GeoExt.tree.TristateCheckboxNode = Ext.extend(Ext.tree.AsyncTreeNode, { 30 82 31 83 /** 32 84 * Property: checkedChildNodes 33 85 * {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 an36 * 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. 37 89 */ 38 90 checkedChildNodes: null, … … 140 192 // parent. 141 193 node.on("checkchange", function(node, checked) { 142 if (this.childrenRendered) {194 if(this.childrenRendered) { 143 195 this.fireEvent("childcheckchange", node, checked); 144 196 } … … 186 238 * 187 239 * Event types supported for this class, in additon to the ones inherited 188 * from {< GeoExt.tree.TristateCheckboxNode>}:240 * from {<Ext.tree.AsyncTreeNode>}: 189 241 * - *childcheckchange* fired to notify a parent node that the status of 190 242 * its checked child nodes has changed … … 193 245 194 246 /** 195 * NodeType: tristateCheckbox196 */ 197 Ext.tree.TreePanel.nodeTypes. tristateCheckbox = GeoExt.tree.TristateCheckboxNode;247 * NodeType: gx_tristatecheckbox 248 */ 249 Ext.tree.TreePanel.nodeTypes.gx_tristatecheckbox = GeoExt.tree.TristateCheckboxNode; sandbox/opengeo/geoexplorer/tests/widgets/MapPanel.html
r238 r262 36 36 37 37 function test_mappanel(t) { 38 t.plan( 2)38 t.plan(3) 39 39 40 40 loadMapPanel(); 41 41 t.eq(mapPanel.map.getCenter().toString(), "lon=5,lat=45", "Map center set correctly"); 42 42 t.eq(mapPanel.map.getZoom(), 4, "Zoom set correctly"); 43 t.eq(GeoExt.MapPanel.guess().id, mapPanel.id, "MapPanel guessed correctly"); 43 44 } 44 45