[Commits] r1303 - in sandbox/camptocamp/geobretagne: examples lib lib/GeoExt/data lib/GeoExt/widgets lib/GeoExt/widgets/tree tests tests/lib/GeoExt/data tests/lib/GeoExt/widgets tests/lib/GeoExt/widgets/tree
commits at geoext.org
commits at geoext.org
Wed Aug 5 13:24:10 CEST 2009
Author: elemoine
Date: 2009-08-05 13:24:10 +0200 (Wed, 05 Aug 2009)
New Revision: 1303
Added:
sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeReader.js
sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeStore.js
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.html
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.js
Modified:
sandbox/camptocamp/geobretagne/examples/attributes.html
sandbox/camptocamp/geobretagne/examples/attributes.js
sandbox/camptocamp/geobretagne/examples/layeropacityslider.html
sandbox/camptocamp/geobretagne/examples/layeropacityslider.js
sandbox/camptocamp/geobretagne/lib/GeoExt.js
sandbox/camptocamp/geobretagne/lib/GeoExt/data/FeatureStore.js
sandbox/camptocamp/geobretagne/lib/GeoExt/data/ProtocolProxy.js
sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/LayerOpacitySlider.js
sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/MapPanel.js
sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerContainer.js
sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/FeatureStore.html
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/LayerOpacitySlider.html
sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html
sandbox/camptocamp/geobretagne/tests/list-tests.html
Log:
svn merge -r1289:HEAD http://svn.geoext.org/core/trunk/geoext .
Modified: sandbox/camptocamp/geobretagne/examples/attributes.html
===================================================================
--- sandbox/camptocamp/geobretagne/examples/attributes.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/examples/attributes.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -1,6 +1,6 @@
<html>
<head>
- <title>GeoExt AttributesReader and AttributesStore</title>
+ <title>GeoExt AttributeReader and AttributeStore</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" />
@@ -12,8 +12,8 @@
</head>
<body>
- <h1>AttributesReader and AttributesStore</h1>
- <p>This is example that shows how create an AttributesStore with
+ <h1>AttributeReader and AttributeStore</h1>
+ <p>This is example that shows how create an AttributeStore with
records read from a WFS DescribeFeatureType response.</p>
<p>Note that the js is not minified so it is readable.
Modified: sandbox/camptocamp/geobretagne/examples/attributes.js
===================================================================
--- sandbox/camptocamp/geobretagne/examples/attributes.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/examples/attributes.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -10,7 +10,7 @@
Ext.onReady(function() {
// create a new attributes store
- store = new GeoExt.data.AttributesStore({
+ store = new GeoExt.data.AttributeStore({
url: "data/describe_feature_type.xml"
});
store.load();
Modified: sandbox/camptocamp/geobretagne/examples/layeropacityslider.html
===================================================================
--- sandbox/camptocamp/geobretagne/examples/layeropacityslider.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/examples/layeropacityslider.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -7,6 +7,11 @@
<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/OpenLayers.js"></script>
<script type="text/javascript" src="../lib/GeoExt.js"></script>
+ <style type="text/css">
+ .x-tree-node-leaf .gx-tree-layer-icon {
+ width: 0px;
+ }
+ </style>
<script type="text/javascript" src="layeropacityslider.js"></script>
</head>
@@ -18,14 +23,22 @@
LayerOpacitySliderTip, which will show the opacity value while dragging
the slider (the content is configurable).<p>
- <p>In this example, the slider below the map is in aggressive mode: the
- opacity is changed as soon as the slider is moved. The slider into the
- map is not aggressive: the opacity is changed when the slider is
+ <p>In this example, the slider in below the map is in aggressive mode: the
+ opacity is changed as soon as the slider is moved. The slider inside
+ Map 1 is not aggressive: the opacity is changed when the slider is
released.</p>
+ <p>In Map 2 we have a fading effect between two layers. The slider is configured
+ with changeVisibility:true and a complementaryLayer. This avoids downloading images
+ when layer opacity is 0 or when complementaryLayer is fully covered by layer.
+ The effect on layer visibility is shown in the tree (checkboxes).</p>
+
<p>The js is not minified so it is readable. See <a
href="layeropacityslider.js">layeropacityslider.js</a>.</p>
- <div id="map-container"></div>
+ <div id="map1-container" style="float:left"></div>
+ <div id="map2-container" style="float:right"></div>
+ <div id="tree" style="float:right"></div>
+ <div id="slider" style="clear:both"></div>
</body>
</html>
Modified: sandbox/camptocamp/geobretagne/examples/layeropacityslider.js
===================================================================
--- sandbox/camptocamp/geobretagne/examples/layeropacityslider.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/examples/layeropacityslider.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -6,7 +6,7 @@
* of the license.
*/
-var panel, wms, slider;
+var panel1, panel2, wms, slider;
Ext.onReady(function() {
@@ -17,9 +17,9 @@
);
// create a map panel with an embedded slider
- panel = new GeoExt.MapPanel({
- title: "Map",
- renderTo: "map-container",
+ panel1 = new GeoExt.MapPanel({
+ title: "Map 1",
+ renderTo: "map1-container",
height: 300,
width: 400,
map: {
@@ -37,7 +37,6 @@
plugins: new GeoExt.LayerOpacitySliderTip()
}]
});
-
// create a separate slider bound to the map but displayed elsewhere
slider = new GeoExt.LayerOpacitySlider({
layer: wms,
@@ -45,6 +44,47 @@
width: 200,
isFormField: true,
fieldLabel: "opacity",
- renderTo: document.body
+ renderTo: "slider"
});
+
+ var clone = wms.clone();
+ var wms2 = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'}
+ );
+ panel2 = new GeoExt.MapPanel({
+ title: "Map 2",
+ renderTo: "map2-container",
+ height: 300,
+ width: 400,
+ map: {
+ controls: [new OpenLayers.Control.Navigation()]
+ },
+ layers: [wms2, clone],
+ extent: [-5, 35, 15, 55],
+ items: [{
+ xtype: "gx_opacityslider",
+ layer: clone,
+ complementaryLayer: wms2,
+ changeVisibility: true,
+ aggressive: true,
+ vertical: true,
+ height: 120,
+ x: 10,
+ y: 10,
+ plugins: new GeoExt.LayerOpacitySliderTip()
+ }]
+ });
+
+ var tree = new Ext.tree.TreePanel({
+ width: 145,
+ height: 300,
+ renderTo: "tree",
+ root: new GeoExt.tree.LayerContainer({
+ layerStore: panel2.layers,
+ expanded: true
+ })
+ });
+
});
Copied: sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeReader.js (from rev 1302, core/trunk/geoext/lib/GeoExt/data/AttributeReader.js)
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeReader.js (rev 0)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeReader.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -0,0 +1,119 @@
+/**
+ * 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.
+ */
+
+/** api: (define)
+ * module = GeoExt.data
+ * class = AttributeReader
+ * base_link = `Ext.data.DataReader <http://extjs.com/deploy/dev/docs/?class=Ext.data.DataReader>`_
+ */
+Ext.namespace("GeoExt.data");
+
+/** api: constructor
+ * .. class:: AttributeReader(meta, recordType)
+ *
+ * :arg meta: ``Object`` Reader configuration.
+ * :arg recordType: ``Array or Ext.data.Record`` An array of field
+ * configuration objects or a record object.
+ *
+ * Create a new attributes reader object.
+ *
+ * Valid meta properties:
+ *
+ * * format - ``OpenLayers.Format`` A parser for transforming the XHR response
+ * into an array of objects representing attributes. Defaults to
+ * an ``OpenLayers.Format.WFSDescribeFeatureType`` parser.
+ * * ignore - ``Object`` Properties of the ignore object should be field names.
+ * Values are either arrays or regular expressions.
+ */
+GeoExt.data.AttributeReader = function(meta, recordType) {
+ meta = meta || {};
+ if(!meta.format) {
+ meta.format = new OpenLayers.Format.WFSDescribeFeatureType();
+ }
+ GeoExt.data.AttributeReader.superclass.constructor.call(
+ this, meta, recordType || meta.fields
+ );
+};
+
+Ext.extend(GeoExt.data.AttributeReader, Ext.data.DataReader, {
+
+ /** private: method[read]
+ * :arg request: ``Object`` The XHR object that contains the parsed doc.
+ * :return: ``Object`` A data block which is used by an ``Ext.data.Store``
+ * as a cache of ``Ext.data.Records``.
+ *
+ * This method is only used by a DataProxy which has retrieved data from a
+ * remote server.
+ */
+ read: function(request) {
+ var data = request.responseXML;
+ if(!data || !data.documentElement) {
+ data = request.responseText;
+ }
+ return this.readRecords(data);
+ },
+
+ /** private: method[readRecords]
+ * :arg data: ``DOMElement or String or Array`` A document element or XHR
+ * response string. As an alternative to fetching attributes data from
+ * a remote source, an array of attribute objects can be provided given
+ * that the properties of each attribute object map to a provided field
+ * name.
+ * :return: ``Object`` A data block which is used by an ``Ext.data.Store``
+ * as a cache of ``Ext.data.Records``.
+ *
+ * Create a data block containing Ext.data.Records from an XML document.
+ */
+ readRecords: function(data) {
+ var attributes;
+ if(data instanceof Array) {
+ attributes = data;
+ } else {
+ // only works with one featureType in the doc
+ attributes = this.meta.format.read(data).featureTypes[0].properties;
+ }
+ var recordType = this.recordType;
+ var fields = recordType.prototype.fields;
+ var numFields = fields.length;
+ var attr, values, name, record, ignore, matches, value, records = [];
+ for(var i=0, len=attributes.length; i<len; ++i) {
+ ignore = false;
+ attr = attributes[i];
+ values = {};
+ for(var j=0; j<numFields; ++j) {
+ name = fields.items[j].name;
+ value = attr[name];
+ if(this.meta.ignore && this.meta.ignore[name]) {
+ matches = this.meta.ignore[name];
+ if(typeof matches == "string") {
+ ignore = (matches === value);
+ } else if(matches instanceof Array) {
+ ignore = (matches.indexOf(value) > -1);
+ } else if(matches instanceof RegExp) {
+ ignore = (matches.test(value));
+ }
+ if(ignore) {
+ break;
+ }
+ }
+ values[name] = attr[name];
+ }
+ if(!ignore) {
+ records[records.length] = new recordType(values);
+ }
+ }
+
+ return {
+ success: true,
+ records: records,
+ totalRecords: records.length
+ };
+
+ }
+
+});
Copied: sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeStore.js (from rev 1302, core/trunk/geoext/lib/GeoExt/data/AttributeStore.js)
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeStore.js (rev 0)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/data/AttributeStore.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+/**
+ * @include GeoExt/data/AttributeReader.js
+ */
+
+/** api: (define)
+ * module = GeoExt.data
+ * class = AttributeStore
+ * base_link = `Ext.data.DataStore <http://extjs.com/deploy/dev/docs/?class=Ext.data.DataStore>`_
+ */
+Ext.namespace("GeoExt.data");
+
+/** api: constructor
+ * .. class:: AttributeStore(config)
+ *
+ * Small helper class to make creating stores for remotely-loaded attributes
+ * data easier. AttributeStore is pre-configured with a built-in
+ * ``Ext.data.HttpProxy`` and :class:`gxp.data.AttributeReader`. The
+ * HttpProxy is configured to allow caching (disableCaching: false) and
+ * uses GET. If you require some other proxy/reader combination then you'll
+ * have to configure this with your own proxy or create a basic
+ * ``Ext.data.Store`` and configure as needed.
+ */
+
+/** api: config[format]
+ * ``OpenLayers.Format``
+ * A parser for transforming the XHR response into an array of objects
+ * representing attributes. Defaults to an
+ * ``OpenLayers.Format.WFSDescribeFeatureType`` parser.
+ */
+
+/** api: config[fields]
+ * ``Array or Function``
+ * Either an array of field definition objects as passed to
+ * ``Ext.data.Record.create``, or a record constructor created using
+ * ``Ext.data.Record.create``. Defaults to ``["name", "type"]``.
+ */
+GeoExt.data.AttributeStore = function(c) {
+ GeoExt.data.AttributeStore.superclass.constructor.call(
+ this,
+ Ext.apply(c, {
+ proxy: c.proxy || (!c.data ?
+ new Ext.data.HttpProxy({url: c.url, disableCaching: false, method: "GET"}) :
+ undefined
+ ),
+ reader: new GeoExt.data.AttributeReader(
+ c, c.fields || ["name", "type"]
+ )
+ })
+ );
+};
+Ext.extend(GeoExt.data.AttributeStore, Ext.data.Store);
\ No newline at end of file
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/data/FeatureStore.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/data/FeatureStore.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/data/FeatureStore.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -261,7 +261,9 @@
// endEdit
record.set("state", feature.state);
record.set("fid", feature.fid);
- record.set("feature", feature);
+ // Ext 3.0 does not allow circular references in objects passed
+ // to record.set
+ record.data["feature"] = feature;
this._updating = true;
record.endEdit();
delete this._updating;
@@ -369,16 +371,25 @@
*/
onUpdate: function(store, record, operation) {
if(!this._updating) {
+ /**
+ * TODO: remove this if the FeatureReader adds attributes
+ * for all fields that map to feature.attributes.
+ * In that case, it would be sufficient to check (key in feature.attributes).
+ */
+ var defaultFields = new GeoExt.data.FeatureRecord().fields;
var feature = record.get("feature");
if(record.fields) {
var cont = this.layer.events.triggerEvent(
"beforefeaturemodified", {feature: feature}
);
if(cont !== false) {
+ var attributes = feature.attributes;
record.fields.each(
function(field) {
- feature.attributes[field.mapping || field.name] =
- record.get(field.name);
+ var key = field.mapping || field.name;
+ if (!defaultFields.containsKey(key)) {
+ attributes[key] = record.get(field.name);
+ }
}
);
this._updating = true;
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/data/ProtocolProxy.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/data/ProtocolProxy.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/data/ProtocolProxy.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -14,8 +14,8 @@
Ext.namespace('GeoExt', 'GeoExt.data');
GeoExt.data.ProtocolProxy = function(config) {
- GeoExt.data.ProtocolProxy.superclass.constructor.call(this);
Ext.apply(this, config);
+ GeoExt.data.ProtocolProxy.superclass.constructor.apply(this, arguments);
};
/** api: constructor
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/LayerOpacitySlider.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/LayerOpacitySlider.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/LayerOpacitySlider.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -65,9 +65,24 @@
/** api: config[layer]
* ``OpenLayers.Layer`` or :class:`GeoExt.data.LayerRecord`
+ * The layer this slider changes the opacity of. (required)
*/
+ /** private: property[layer]
+ * ``OpenLayers.Layer``
+ */
layer: null,
+ /** api: config[complementaryLayer]
+ * ``OpenLayers.Layer`` or :class:`GeoExt.data.LayerRecord`
+ * If provided, a layer that will be made invisible (its visibility is
+ * set to false) when the slider value is set to its max value. If this
+ * slider is used to fade visibility between to layers, setting
+ * ``complementaryLayer`` and ``changeVisibility`` will make sure that
+ * only visible tiles are loaded when the slider is set to its min or max
+ * value. (optional)
+ */
+ complementaryLayer: null,
+
/** api: config[delay]
* ``Number`` Time in milliseconds before setting the opacity value to the
* layer. If the value change again within that time, the original value
@@ -75,6 +90,14 @@
*/
delay: 5,
+ /** api: config[changeVisibilityDelay]
+ * ``Number`` Time in milliseconds before changing the layer's visibility.
+ * If the value changes again within that time, the layer's visibility
+ * change does not occur. Only applicable if changeVisibility is true.
+ * Defaults to 5.
+ */
+ changeVisibilityDelay: 5,
+
/** api: config[aggressive]
* ``Boolean``
* If set to true, the opacity is changed as soon as the thumb is moved.
@@ -82,17 +105,27 @@
*/
aggressive: false,
- /** private: property[minValue]
- * ``Number``
- * The minimum slider value, layer is fully transparent
+ /** api: config[changeVisibility]
+ * ``Boolean``
+ * If set to true, the layer's visibility is handled by the
+ * slider, the slider makes the layer invisible when its
+ * value is changed to the min value, and makes the layer
+ * visible again when its value goes from the min value
+ * to some other value. The layer passed to the constructor
+ * must be visible, as its visibility is fully handled by
+ * the slider. Defaults to false.
*/
- minValue: 0,
+ changeVisibility: false,
- /** private: property[maxValue]
+ /** api: config[value]
* ``Number``
- * The maximum slider value, layer is fully opaque.
+ * The value to initialize the slider with. This value is
+ * taken into account only if the layer's opacity is null.
+ * If the layer's opacity is null and this value is not
+ * defined in the config object then the slider initializes
+ * it to the max value.
*/
- maxValue: 100,
+ value: null,
/** private: method[constructor]
* Construct the component.
@@ -104,7 +137,17 @@
} else if (config.layer instanceof GeoExt.data.LayerRecord) {
this.layer = config.layer.get('layer');
}
+
+ if (config.complementaryLayer instanceof OpenLayers.Layer) {
+ this.complementaryLayer = config.complementaryLayer;
+ } else if (config.complementaryLayer instanceof
+ GeoExt.data.LayerRecord) {
+ this.complementaryLayer =
+ config.complementaryLayer.get('layer');
+ }
+
delete config.layer;
+ delete config.complementaryLayer;
}
GeoExt.LayerOpacitySlider.superclass.constructor.call(this, config);
},
@@ -115,35 +158,93 @@
initComponent: function() {
// set the slider initial value
if (this.layer && this.layer.opacity !== null) {
- this.value = parseInt(this.layer.opacity * 100);
- } else {
- // assume that the layer has no opacity
- this.value = 100;
+ this.value = parseInt(
+ this.layer.opacity * (this.maxValue - this.minValue)
+ );
+ } else if (this.value == null) {
+ this.value = this.maxValue;
}
GeoExt.LayerOpacitySlider.superclass.initComponent.call(this);
+ if (this.changeVisibility && this.layer &&
+ (this.layer.opacity == 0 || this.value == this.minValue)) {
+ this.layer.setVisibility(false);
+ }
+
+ if (this.complementaryLayer &&
+ ((this.layer && this.layer.opacity == 1) ||
+ (this.value == this.maxValue))) {
+ this.complementaryLayer.setVisibility(false);
+ }
+
if (this.aggressive === true) {
- this.on('change', this.opacityChanged, this, {
+ this.on('change', this.changeLayerOpacity, this, {
buffer: this.delay
});
} else {
- this.on('changecomplete', this.opacityChanged, this);
+ this.on('changecomplete', this.changeLayerOpacity, this);
}
+
+ if (this.changeVisibility === true) {
+ this.on('change', this.changeLayerVisibility, this, {
+ buffer: this.changeVisibilityDelay
+ });
+ }
+
+ if (this.complementaryLayer) {
+ this.on('change', this.changeComplementaryLayerVisibility, this, {
+ buffer: this.changeVisibilityDelay
+ });
+ }
},
- /** private: method[opacityChanged]
+ /** private: method[changeLayerOpacity]
* :param slider: :class:`GeoExt.LayerOpacitySlider`
* :param value: ``Number`` The slider value
*
* Updates the ``OpenLayers.Layer`` opacity value.
*/
- opacityChanged: function(slider, value) {
+ changeLayerOpacity: function(slider, value) {
if (this.layer) {
this.layer.setOpacity(value / 100.0);
}
},
+ /** private: method[changeLayerVisibility]
+ * :param slider: :class:`GeoExt.LayerOpacitySlider`
+ * :param value: ``Number`` The slider value
+ *
+ * Updates the ``OpenLayers.Layer`` visibility.
+ */
+ changeLayerVisibility: function(slider, value) {
+ var currentVisibility = this.layer.getVisibility();
+ if (value == this.minValue &&
+ currentVisibility === true) {
+ this.layer.setVisibility(false);
+ } else if (value > this.minValue &&
+ currentVisibility == false) {
+ this.layer.setVisibility(true);
+ }
+ },
+
+ /** private: method[changeComplementaryLayerVisibility]
+ * :param slider: :class:`GeoExt.LayerOpacitySlider`
+ * :param value: ``Number`` The slider value
+ *
+ * Updates the complementary ``OpenLayers.Layer`` visibility.
+ */
+ changeComplementaryLayerVisibility: function(slider, value) {
+ var currentVisibility = this.complementaryLayer.getVisibility();
+ if (value == this.maxValue &&
+ currentVisibility === true) {
+ this.complementaryLayer.setVisibility(false);
+ } else if (value < this.maxValue &&
+ currentVisibility == false) {
+ this.complementaryLayer.setVisibility(true);
+ }
+ },
+
/** private: method[addToMapPanel]
* :param panel: :class:`GeoExt.MapPanel`
*
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/MapPanel.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/MapPanel.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/MapPanel.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -140,16 +140,7 @@
*/
renderMap: function() {
var map = this.map;
-
- // hack: prevent map.updateSize (called from within map.render) from
- // zooming to the map extent. This hack is a workaround for
- // <http://trac.openlayers.org/ticket/2105> and must be
- // removed once this ticket is closed.
- var setCenter = map.setCenter;
- map.setCenter = function() {};
map.render(this.body.dom);
- map.setCenter = setCenter;
-
if(map.layers.length > 0) {
if(this.center || this.zoom != null) {
// both do not have to be defined
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerContainer.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerContainer.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerContainer.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -20,7 +20,7 @@
/** api: constructor
* .. class:: LayerContainer
*
- * A subclass of ``Ext.tree.TreeNode`` that will collect all layers of an
+ * A subclass of ``Ext.tree.AsyncTreeNode`` that will collect all layers of an
* OpenLayers map. Only layers that have displayInLayerSwitcher set to true
* will be included. The childrens' iconCls defaults to
* "gx-tree-layer-icon".
@@ -59,7 +59,7 @@
});
this.loader = config.loader instanceof GeoExt.tree.LayerLoader ?
config.loader :
- new GeoExt.tree.LayerLoader(Ext.applyIf(config.loader, {
+ new GeoExt.tree.LayerLoader(Ext.applyIf(config.loader || {}, {
store: config.layerStore
}));
Modified: sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt/widgets/tree/LayerNode.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -34,22 +34,25 @@
if (a.checked === undefined) {
a.checked = this.node.layer.getVisibility();
}
- GeoExt.tree.LayerNodeUI.superclass.render.call(this, bulkRender);
+ GeoExt.tree.LayerNodeUI.superclass.render.apply(this, arguments);
+ var cb = this.checkbox;
if (a.radioGroup && this.radio === null) {
- this.radio = Ext.DomHelper.insertAfter(this.checkbox,
+ this.radio = Ext.DomHelper.insertAfter(cb,
['<input type="radio" class="gx-tree-layer-radio" name="',
a.radioGroup, '_radio"></input>'].join(""));
}
if(a.checkedGroup) {
// replace the checkbox with a radio button
- var radio = Ext.DomHelper.insertAfter(this.checkbox,
+ var radio = Ext.DomHelper.insertAfter(cb,
['<input type="radio" name="', a.checkedGroup,
- '_checkbox" class="', this.checkbox.className,
- this.checkbox.checked ? '" checked="checked"' : '',
+ '_checkbox" class="', cb.className,
+ cb.checked ? '" checked="checked"' : '',
'"></input>'].join(""));
- Ext.get(this.checkbox).remove();
+ radio.defaultChecked = cb.defaultChecked;
+ Ext.get(cb).remove();
this.checkbox = radio;
}
+ this.enforceOneVisible();
},
/** private: method[onClick]
@@ -59,34 +62,85 @@
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 {
- 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 +210,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 +262,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 +287,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 +309,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 +319,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 +355,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 +426,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/camptocamp/geobretagne/lib/GeoExt.js
===================================================================
--- sandbox/camptocamp/geobretagne/lib/GeoExt.js 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/lib/GeoExt.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -66,6 +66,8 @@
var jsfiles = new Array(
"GeoExt/data/AttributesReader.js",
"GeoExt/data/AttributesStore.js",
+ "GeoExt/data/AttributeReader.js",
+ "GeoExt/data/AttributeStore.js",
"GeoExt/data/FeatureRecord.js",
"GeoExt/data/FeatureReader.js",
"GeoExt/data/FeatureStore.js",
Copied: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.html (from rev 1302, core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.html)
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.html (rev 0)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html debug="true">
+ <head>
+ <script type="text/javascript" src="../../../../../ext/adapter/ext/ext-base.js"></script>
+ <script type="text/javascript" src="../../../../../ext/ext-all-debug.js"></script>
+
+ <script type="text/javascript" src="../../../../../openlayers/lib/OpenLayers.js"></script>
+ <script type="text/javascript" src="../../../../lib/GeoExt.js"></script>
+ <script type="text/javascript" src="AttributeReader.js"></script>
+
+ <script type="text/javascript">
+
+ function test_read(t) {
+ t.plan(3);
+
+ var reader = new GeoExt.data.AttributeReader({}, [
+ "name",
+ "type"
+ ]);
+
+ var records = reader.read({responseXML : doc});
+
+ //1 test
+ t.eq(records.totalRecords, 23, 'readRecords returns correct number of records');
+
+ var record = records.records[2];
+
+ //2 tests -- testing the fields of a record
+ t.eq(record.get("name"), "STATE_FIPS", "[2] correct attribute name");
+ t.eq(record.get("type"), "xsd:string", "[2] correct attribute type name");
+
+ }
+
+ function test_ignoreString(t) {
+ t.plan(1);
+
+ var reader = new GeoExt.data.AttributeReader({
+ ignore: {type: "xsd:string"}
+ }, [
+ "name",
+ "type"
+ ]);
+
+ var records = reader.read({responseXML : doc});
+
+ //1 test
+ t.eq(records.totalRecords, 19, 'right number of records are ignored (ignores String)');
+ }
+
+ function test_ignoreArray(t) {
+ t.plan(1);
+
+ var reader = new GeoExt.data.AttributeReader({
+ ignore: {type: ["xsd:double", "gml:MultiSurfacePropertyType"]}
+ }, [
+ "name",
+ "type"
+ ]);
+
+ var records = reader.read({responseXML : doc});
+
+ //1 test
+ t.eq(records.totalRecords, 4, 'right number of records are ignored (ignores Array)');
+ }
+
+ function test_ignoreRegexp(t) {
+ t.plan(1);
+
+ var reader = new GeoExt.data.AttributeReader({
+ ignore: {name: new RegExp('^S')}
+ }, [
+ "name",
+ "type"
+ ]);
+
+ var records = reader.read({responseXML : doc});
+
+ //1 test
+ t.eq(records.totalRecords, 17, 'right number of records are ignored (ignores RegExp)');
+ }
+
+ </script>
+ <body>
+ <div id="map"></div>
+ </body>
+</html>
Copied: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.js (from rev 1302, core/trunk/geoext/tests/lib/GeoExt/data/AttributeReader.js)
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.js (rev 0)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/AttributeReader.js 2009-08-05 11:24:10 UTC (rev 1303)
@@ -0,0 +1,39 @@
+var doc = (new OpenLayers.Format.XML).read(
+'<?xml version="1.0" encoding="UTF-8"?>' +
+'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:topp="http://www.openplans.org/topp" elementFormDefault="qualified" targetNamespace="http://www.openplans.org/topp">' +
+ '<xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://sigma.openplans.org:80/geoserver/schemas/gml/3.1.1/base/gml.xsd"/>' +
+ '<xsd:complexType name="statesType">' +
+ '<xsd:complexContent>' +
+ '<xsd:extension base="gml:AbstractFeatureType">' +
+ '<xsd:sequence>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="the_geom" nillable="true" type="gml:MultiSurfacePropertyType"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_NAME" nillable="true" type="xsd:string"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_FIPS" nillable="true" type="xsd:string"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="SUB_REGION" nillable="true" type="xsd:string"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="STATE_ABBR" nillable="true" type="xsd:string"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="LAND_KM" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="WATER_KM" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="PERSONS" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="FAMILIES" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="HOUSHOLD" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="MALE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="FEMALE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="WORKERS" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="DRVALONE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="CARPOOL" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="PUBTRANS" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="EMPLOYED" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="UNEMPLOY" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="SERVICE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="MANUAL" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="P_MALE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="P_FEMALE" nillable="true" type="xsd:double"/>' +
+ '<xsd:element maxOccurs="1" minOccurs="0" name="SAMP_POP" nillable="true" type="xsd:double"/>' +
+ '</xsd:sequence>' +
+ '</xsd:extension>' +
+ '</xsd:complexContent>' +
+ '</xsd:complexType>' +
+ '<xsd:element name="states" substitutionGroup="gml:_Feature" type="topp:statesType"/>' +
+'</xsd:schema>'
+);
+
Modified: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/FeatureStore.html
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/FeatureStore.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/data/FeatureStore.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -187,19 +187,28 @@
}
function test_featuremodified_update(t) {
- t.plan(6);
+ t.plan(8);
/*
* Set up
*/
var feature, id, layer, store, recordType, record;
-
+
feature = new OpenLayers.Feature.Vector(null, {
foo: "foo",
bar: "bar"
});
id = feature.id;
+
+ function keys(obj) {
+ var list = [];
+ for(var k in obj) {
+ list.push(k);
+ }
+ return list;
+ }
+ var originalAttrs = keys(feature.attributes);
recordType = GeoExt.data.FeatureRecord.create([
{name: "foo"}, {name: "bar"}
@@ -244,6 +253,19 @@
t.eq(layer.getFeatureById(id).attributes.bar, "bar3",
"update event causes update of feature property \"bar\"");
+
+ // make sure calling record.set didn't add any attributes
+ var currentAttrs = keys(feature.attributes);
+ t.eq(originalAttrs.length, currentAttrs.length,
+ "no new attributes added: " + currentAttrs.join(", "));
+
+ var feature2 = new OpenLayers.Feature.Vector(null, {
+ "foo": "foo_f2"
+ });
+ layer.addFeatures([feature2]);
+ store.getById(feature2.id).set("bar", "bar_f2");
+
+ t.eq(feature2.attributes.bar, "bar_f2", "previously undefined attribute set correctly");
}
</script>
Modified: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/LayerOpacitySlider.html
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/LayerOpacitySlider.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/LayerOpacitySlider.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -9,7 +9,7 @@
<script type="text/javascript">
function test_constructor(t) {
- t.plan(2);
+ t.plan(8);
var record, store, slider;
var layer = new OpenLayers.Layer("a");
@@ -23,13 +23,138 @@
t.eq(slider.layer.id, record.id, "layer parameter is a GeoExt.data.LayerRecord");
slider.destroy();
- var slider = new GeoExt.LayerOpacitySlider({
+ slider = new GeoExt.LayerOpacitySlider({
layer: layer
});
t.eq(layer.id, slider.layer.id, "layer parameter is a OpenLayers.Layer.WMS");
slider.destroy();
+
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer
+ });
+ t.eq(slider.value, 100,
+ "ctor sets value to max value if layer opacity is " +
+ "null and value isn't defined in config");
+
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer,
+ changeVisibility: true
+ });
+ t.eq(slider.changeVisibility, true,
+ "ctor sets changeVisibility to true in instance");
+ slider.destroy();
+
+ layer.setOpacity(0.0);
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer,
+ changeVisibility: true
+ });
+ t.eq(layer.getVisibility(), false,
+ "ctor makes layer invisible if layer opacity is 0");
+ layer.setVisibility(true);
+ slider.destroy();
+
+ layer.setOpacity(0.5);
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer,
+ changeVisibility: true
+ });
+ t.eq(layer.getVisibility(), true,
+ "ctor does not change layer visibility if layer opacity is non 0");
+ slider.destroy();
+
+ layer.opacity = null;
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer,
+ value: 0,
+ changeVisibility: true
+ });
+ t.eq(layer.getVisibility(), false,
+ "ctor makes layer invisible if layer opacity is " +
+ "null and value is min value");
+ layer.setVisibility(true);
+ slider.destroy();
+
+ layer.opacity = null;
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer,
+ value: 0.5,
+ changeVisibility: true
+ });
+ t.eq(layer.getVisibility(), true,
+ "ctor does not change layer visibility if layer " +
+ "opacity is null and value is not min value");
+ layer.setVisibility(true);
+ slider.destroy();
}
+ function test_constructor_complementary(t) {
+ t.plan(5);
+
+ var layer1, layer2, record1, record2, slider;
+
+ var layer1 = new OpenLayers.Layer("1");
+ var layer2 = new OpenLayers.Layer("2");
+
+ record1 = new (GeoExt.data.LayerRecord.create())(
+ {layer: layer1, title: layer1.name}, layer1.id
+ );
+ record2 = new (GeoExt.data.LayerRecord.create())(
+ {layer: layer2, title: layer2.name}, layer2.id
+ );
+
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer1,
+ complementaryLayer: layer2
+ });
+ t.ok(slider.complementaryLayer == layer2,
+ "ctor correctly sets complementary layer in " +
+ "the instance [layer]");
+ slider.destroy();
+
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: record1,
+ complementaryLayer: record2
+ });
+ t.ok(slider.complementaryLayer == layer2,
+ "ctor correctly sets complementary layer in " +
+ "the instance [record]");
+ slider.destroy();
+
+ layer1.setOpacity(1);
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer1,
+ complementaryLayer: layer2
+ });
+ t.eq(layer2.getVisibility(), false,
+ "ctor makes complementary layer invisible if the " +
+ "main layer opacity is 1");
+ layer2.setVisibility(true);
+ slider.destroy();
+
+ layer1.setOpacity(0.5);
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer1,
+ complementaryLayer: layer2
+ });
+ t.eq(layer2.getVisibility(), true,
+ "ctor does not change complementary layer visibility "+
+ "if the main layer opacity is not 1");
+ slider.destroy();
+
+ layer1.opacity = null;
+ slider = new GeoExt.LayerOpacitySlider({
+ layer: layer1,
+ complementaryLayer: layer2,
+ value: 100
+ });
+ t.eq(layer2.getVisibility(), false,
+ "ctor makes complementary layer invisible if the " +
+ "main layer opacity is null but the slider " +
+ "value is set to max value in the config");
+ slider.destroy();
+ }
+
function test_initalOpacity(t) {
t.plan(3);
@@ -85,6 +210,79 @@
slider1.destroy();
slider2.destroy();
}
+
+ function test_visibility(t) {
+ t.plan(3);
+
+ var slider, layer;
+
+ layer = new OpenLayers.Layer("a");
+
+ slider = new GeoExt.LayerOpacitySlider({
+ renderTo: document.body,
+ layer: layer,
+ changeVisibility: true,
+ changeVisibilityDelay: 0
+ });
+
+ slider.setValue(slider.minValue);
+ t.eq(layer.getVisibility(), false,
+ "setting slider value to min value makes the " +
+ "layer invisible");
+
+ slider.setValue(slider.minValue + 1);
+ t.eq(layer.getVisibility(), true,
+ "setting slider value to some value different " +
+ "than min value makes the layer visible again");
+
+ slider.setValue(slider.minValue + 2);
+ t.eq(layer.getVisibility(), true,
+ "setting slider value to some other value different " +
+ "than min value does not make the layer invisible");
+
+ slider.destroy();
+ }
+
+ function test_visibility_complementary_layer(t) {
+ t.plan(4);
+
+ var layer1, layer2, slider;
+
+ var layer1 = new OpenLayers.Layer("1");
+ var layer2 = new OpenLayers.Layer("2");
+
+ slider = new GeoExt.LayerOpacitySlider({
+ renderTo: document.body,
+ layer: layer1,
+ complementaryLayer: layer2,
+ changeVisibilityDelay: 0
+ });
+
+ slider.value = 99;
+ slider.setValue(slider.maxValue);
+ t.eq(layer2.getVisibility(), false,
+ "setting slider value to max value makes " +
+ "complementary layer invisible");
+
+ slider.setValue(slider.maxValue - 1);
+ t.eq(layer2.getVisibility(), true,
+ "setting slider value to some value different " +
+ "than max value makes the complementary layer " +
+ "visible again");
+
+ slider.setValue(slider.maxValue - 2);
+ t.eq(layer2.getVisibility(), true,
+ "setting slider value to some other value different " +
+ "than max value does not make the complementary layer " +
+ "invisible");
+
+ slider.setValue(slider.minValue);
+ t.eq(layer2.getVisibility(), true,
+ "setting slider value to min value does not make " +
+ "the complementary layer invisible");
+
+ slider.destroy();
+ }
</script>
<body>
</body>
Modified: sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html
===================================================================
--- sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/tests/lib/GeoExt/widgets/tree/LayerNode.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -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);
Modified: sandbox/camptocamp/geobretagne/tests/list-tests.html
===================================================================
--- sandbox/camptocamp/geobretagne/tests/list-tests.html 2009-08-04 21:05:17 UTC (rev 1302)
+++ sandbox/camptocamp/geobretagne/tests/list-tests.html 2009-08-05 11:24:10 UTC (rev 1303)
@@ -1,5 +1,6 @@
<ul id="testlist">
<li>lib/GeoExt/adapter/override-ext-ajax.html</li>
+ <li>lib/GeoExt/data/AttributeReader.html</li>
<li>lib/GeoExt/data/FeatureRecord.html</li>
<li>lib/GeoExt/data/FeatureReader.html</li>
<li>lib/GeoExt/data/FeatureStore.html</li>
More information about the Commits
mailing list