making the layerswitcher a little smarter. Instead of fancy 'noEvent' parameters, we just keep track of the state at each redraw. When asked to redraw, we then check first to see if anything has changed before going ahead with the redraw. Also in this patch, we add a 'visibilitychanged' event to the layer's events object -- upon request by users. (Closes #878)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@4229 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
euzuro
2007-09-12 04:00:31 +00:00
parent 7a37ed4423
commit 0e8e7ab620
5 changed files with 78 additions and 16 deletions

View File

@@ -19,6 +19,14 @@ OpenLayers.Control.LayerSwitcher =
*/
activeColor: "darkblue",
/**
* Property: layerStates
* {Array(Object)} Basically a copy of the "state" of the map's layers
* the last time the control was drawn. We have this in order to avoid
* unnecessarily redrawing the control.
*/
layerStates: null,
// DOM Elements
@@ -86,6 +94,7 @@ OpenLayers.Control.LayerSwitcher =
*/
initialize: function(options) {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.layerStates = [];
},
/**
@@ -171,6 +180,32 @@ OpenLayers.Control.LayerSwitcher =
},
/**
* Method: checkRedraw
* Checks if the layer state has changed since the last redraw() call.
*
* Returns:
* {Boolean} The layer state changed since the last redraw() call.
*/
checkRedraw: function() {
var redraw = false;
if ( !this.layerStates.length ||
(this.map.layers.length != this.layerStates.length) ) {
redraw = true;
} else {
for (var i=0; i < this.layerStates.length; i++) {
var layerState = this.layerStates[i];
var layer = this.map.layers[i];
if ( (layerState.name != layer.name) ||
(layerState.visibility != layer.visibility) ) {
redraw = true;
break;
}
}
}
return redraw;
},
/**
* Method: redraw
* Goes through and takes the current state of the Map and rebuilds the
@@ -181,6 +216,11 @@ OpenLayers.Control.LayerSwitcher =
* {DOMElement} A reference to the DIV DOMElement containing the control
*/
redraw: function() {
//if the state hasn't changed since last redraw, no need
// to do anything. Just return the existing div.
if (!this.checkRedraw()) {
return this.div;
}
//clear out previous layers
this.clearLayersArray("base");
@@ -189,6 +229,19 @@ OpenLayers.Control.LayerSwitcher =
var containsOverlays = false;
var containsBaseLayers = false;
// Save state -- for checking layer if the map state changed.
// We save this before redrawing, because in the process of redrawing
// we will trigger more visibility changes, and we want to not redraw
// and enter an infinite loop.
this.layerStates = new Array(this.map.layers.length);
for (var i = 0; i < this.map.layers.length; i++) {
var layer = this.map.layers[i];
this.layerStates[i] = {
'name': layer.name,
'visibility': layer.visibility
};
}
var layers = this.map.layers.slice();
if (!this.ascending) { layers.reverse(); }
for( var i = 0; i < layers.length; i++) {
@@ -286,8 +339,7 @@ OpenLayers.Control.LayerSwitcher =
if (!this.inputElem.disabled) {
if (this.inputElem.type == "radio") {
this.inputElem.checked = true;
this.layer.map.setBaseLayer(this.layer, true);
this.layer.map.events.triggerEvent("changebaselayer");
this.layer.map.setBaseLayer(this.layer);
} else {
this.inputElem.checked = !this.inputElem.checked;
this.layerSwitcher.updateMap();
@@ -329,7 +381,7 @@ OpenLayers.Control.LayerSwitcher =
// set the correct visibilities for the overlays
for(var i=0; i < this.dataLayers.length; i++) {
var layerEntry = this.dataLayers[i];
layerEntry.layer.setVisibility(layerEntry.inputElem.checked, true);
layerEntry.layer.setVisibility(layerEntry.inputElem.checked);
}
},