On Tue, Mar 3, 2009 at 7:05 PM, Eric Lemoine <eric....@gmail.com> wrote: > Alexandre > > I fully support the idea of being able to have two "highlight feature" > controls working at the same time, one on hover and one on click. > However i don't like the renderIntent array in the feature class, it > brings extra complexity that I think is undesirable. I have to say > though that i cannot think of a better solution at this point. Still > thinking... > > Thanks for bringing this back up.
Alexandre, What about this: add an highlightOnly boolean option to the select feature control, if highlightOnly is true then do not select features, just highlight them. Also, if highlightOnly is set to true, when clicking or moving out of an highlighted feature do not unhighlight the feature if it is in the selected features array, i.e. if it was previously selected (by another select feature control). See the attached patch. Note that patch isn't complete - the select feature control should trigger "featurehighlighted" and "featureunhighlighted" events to complete the picture. What do you think? -- Eric
Index: lib/OpenLayers/Control/SelectFeature.js =================================================================== --- lib/OpenLayers/Control/SelectFeature.js (revision 8869) +++ lib/OpenLayers/Control/SelectFeature.js (working copy) @@ -58,6 +58,15 @@ * ignores clicks and only listens to mouse moves. */ hover: false, + + /** + * APIProperty: highlightOnly + * {Boolean} If true do not actually select features, i.e. place them in the + * layer's selected features array, just highlight them (calling drawFeature + * on the layer), when clicking or moving out of an highlighted feature, it + * isn't unhighlighted if it's in selected features arra. Defaults to false. + */ + highlightOnly: false, /** * APIProperty: box @@ -233,19 +242,23 @@ */ clickFeature: function(feature) { if(!this.hover) { - var selected = (OpenLayers.Util.indexOf(this.layer.selectedFeatures, - feature) > -1); - if(selected) { - if(this.toggleSelect()) { - this.unselect(feature); - } else if(!this.multipleSelect()) { - this.unselectAll({except: feature}); - } + if(this.highlightOnly) { + this.drawFeature(feature); } else { - if(!this.multipleSelect()) { - this.unselectAll({except: feature}); + var selected = OpenLayers.Util.indexOf( + this.layer.selectedFeatures, feature) > -1; + if(selected) { + if(this.toggleSelect()) { + this.unselect(feature); + } else if(!this.multipleSelect()) { + this.unselectAll({except: feature}); + } + } else { + if(!this.multipleSelect()) { + this.unselectAll({except: feature}); + } + this.select(feature); } - this.select(feature); } } }, @@ -284,7 +297,16 @@ */ clickoutFeature: function(feature) { if(!this.hover && this.clickout) { - this.unselectAll(); + if(this.highlightOnly) { + // unhighlight the feature only of it's not in the + // array of selected features + if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, + feature) == -1) { + this.drawFeature(feature, "default"); + } + } else { + this.unselectAll(); + } } }, @@ -297,9 +319,13 @@ * feature - {<OpenLayers.Feature.Vector>} */ overFeature: function(feature) { - if(this.hover && - (OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) == -1)) { - this.select(feature); + if(this.hover) { + if(this.highlightOnly) { + this.drawFeature(feature); + } else if(OpenLayers.Util.indexOf( + this.layer.selectedFeatures, feature) == -1) { + this.select(feature); + } } }, @@ -313,9 +339,32 @@ */ outFeature: function(feature) { if(this.hover) { - this.unselect(feature); + if(this.highlightOnly) { + // unhighlight the feature only of it's not in the + // array of selected features + if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, + feature) == -1) { + this.drawFeature(feature, "default"); + } + } else { + this.unselect(feature); + } } }, + + /** + * Method: drawFeature + * Draw the feature with the given render intent, if none is provided + * the feature is drawn using the selectStyle or renderIntent property. + * + * Parameters: + * feature - {<OpenLayers.Feature.Vector>} The feature. + * renderIntent - {String} The render intent. + */ + drawFeature: function(feature, renderIntent) { + renderIntent = renderIntent || this.selectStyle || this.renderIntent; + this.layer.drawFeature(feature, renderIntent); + }, /** * Method: select @@ -333,10 +382,7 @@ }); if(cont !== false) { this.layer.selectedFeatures.push(feature); - - var selectStyle = this.selectStyle || this.renderIntent; - - this.layer.drawFeature(feature, selectStyle); + this.drawFeature(feature); this.layer.events.triggerEvent("featureselected", {feature: feature}); this.onSelect.call(this.scope, feature); } @@ -353,12 +399,12 @@ */ unselect: function(feature) { // Store feature style for restoration later - this.layer.drawFeature(feature, "default"); + this.drawFeature(feature, "default"); OpenLayers.Util.removeItem(this.layer.selectedFeatures, feature); this.layer.events.triggerEvent("featureunselected", {feature: feature}); this.onUnselect.call(this.scope, feature); }, - + /** * Method: selectBox * Callback from the handlers.box set up when <box> selection is true Index: examples/highlight-feature.html =================================================================== --- examples/highlight-feature.html (revision 0) +++ examples/highlight-feature.html (revision 0) @@ -0,0 +1,123 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>SelectFeature Control on Layer.Vector</title> + <link rel="stylesheet" href="../theme/default/style.css" type="text/css" /> + <link rel="stylesheet" href="style.css" type="text/css" /> + <style type="text/css"> + #controlToggle li { + list-style: none; + } + </style> + <script src="../lib/OpenLayers.js"></script> + <script type="text/javascript"> + var map, drawControls; + OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2'; + function init(){ + map = new OpenLayers.Map('map'); + var wmsLayer = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'} + ); + + var vectors = new OpenLayers.Layer.Vector("Vector Layer"); + map.addLayers([wmsLayer, vectors]); + map.addControl(new OpenLayers.Control.LayerSwitcher()); + + drawControls = { + point: new OpenLayers.Control.DrawFeature( + vectors, OpenLayers.Handler.Point + ), + line: new OpenLayers.Control.DrawFeature( + vectors, OpenLayers.Handler.Path + ), + polygon: new OpenLayers.Control.DrawFeature( + vectors, OpenLayers.Handler.Polygon + ), + highlight: [ + new OpenLayers.Control.SelectFeature( + vectors, { + multiple: false, hover: true, highlightOnly: true, + toggleKey: "ctrlKey", // ctrl key removes from selection + multipleKey: "shiftKey" // shift key adds to selection + }), + new OpenLayers.Control.SelectFeature( + vectors, { + clickout: true, toggle: false, + multiple: false, hover: false, + toggleKey: "ctrlKey", // ctrl key removes from selection + multipleKey: "shiftKey", // shift key adds to selection + box: true + }) + ] + }; + + for(var key in drawControls) { + var controls = drawControls[key]; + if(!(controls instanceof Array)) { + controls = [controls]; + } + for(var i = 0; i < controls.length; i++) { + map.addControl(controls[i]); + } + } + map.setCenter(new OpenLayers.LonLat(0, 0), 3); + + } + + function toggleControl(element) { + for(key in drawControls) { + var controls = drawControls[key]; + if(!(controls instanceof Array)) { + controls = [controls]; + } + for(var i = 0; i < controls.length; i++) { + if(element.value == key && element.checked) { + controls[i].activate(); + } else { + controls[i].deactivate(); + } + } + } + } + </script> + </head> + <body onload="init()"> + <h1 id="title">OpenLayers Select Feature Example</h1> + <p id="shortdesc"> + Select a feature on hover or click with the Control.SelectFeature on a + vector layer. + </p> + <div id="map" class="smallmap"></div> + <ul id="controlToggle"> + <li> + <input type="radio" name="type" value="none" id="noneToggle" + onclick="toggleControl(this);" checked="checked" /> + <label for="noneToggle">navigate</label> + </li> + <li> + <input type="radio" name="type" value="point" id="pointToggle" + onclick="toggleControl(this);" /> + <label for="pointToggle">draw point</label> + </li> + <li> + <input type="radio" name="type" value="line" id="lineToggle" + onclick="toggleControl(this);" /> + <label for="lineToggle">draw line</label> + </li> + <li> + <input type="radio" name="type" value="polygon" id="polygonToggle" + onclick="toggleControl(this);" /> + <label for="polygonToggle">draw polygon</label> + </li> + <li> + <input type="radio" name="type" value="highlight" id="highlightToggle" + onclick="toggleControl(this);" /> + <label for="highlightToggle">highlight feature</label> + </li> + </ul> + <p>Use the shift key to select multiple features. Use the ctrl key to + toggle selection on features one at a time. Note: the "clickout" option has no + effect when "hover" is selected.</p> + </body> +</html>
_______________________________________________ Dev mailing list Dev@openlayers.org http://openlayers.org/mailman/listinfo/dev