SelectFeature now takes a hilightOnly config options, that way user can hover features without actually selecting
them, combining two differents controls will allow to separate hover and click events, patches from ahocevar, elemoine and pgiraud, reviewers are ahocevar, elemoine and pgiraud git-svn-id: http://svn.openlayers.org/trunk/openlayers@9176 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
80
examples/highlight-feature.html
Normal file
80
examples/highlight-feature.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>SelectFeature Control for Select and Highlight</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/Firebug/firebug.js"></script>
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map, controls;
|
||||
|
||||
OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';
|
||||
|
||||
function init(){
|
||||
map = new OpenLayers.Map('map');
|
||||
|
||||
var vectors = new OpenLayers.Layer.Vector("vector", {isBaseLayer: true});
|
||||
map.addLayers([vectors]);
|
||||
|
||||
var feature = new OpenLayers.Feature.Vector(
|
||||
OpenLayers.Geometry.fromWKT(
|
||||
"POLYGON((28.828125 0.3515625, 132.1875 -13.0078125, -1.40625 -59.4140625, 28.828125 0.3515625))"
|
||||
)
|
||||
);
|
||||
vectors.addFeatures([feature]);
|
||||
|
||||
var feature2 = new OpenLayers.Feature.Vector(
|
||||
OpenLayers.Geometry.fromWKT(
|
||||
"POLYGON((-120.828125 -50.3515625, -80.1875 -80.0078125, -40.40625 -20.4140625, -120.828125 -50.3515625))"
|
||||
)
|
||||
);
|
||||
vectors.addFeatures([feature2]);
|
||||
|
||||
var report = function(e) {
|
||||
OpenLayers.Console.log(e.type, e.feature.id);
|
||||
};
|
||||
|
||||
var highlightCtrl = new OpenLayers.Control.SelectFeature(vectors, {
|
||||
hover: true,
|
||||
highlightOnly: true,
|
||||
renderIntent: "temporary",
|
||||
eventListeners: {
|
||||
beforefeaturehighlighted: report,
|
||||
featurehighlighted: report,
|
||||
featureunhighlighted: report
|
||||
}
|
||||
});
|
||||
|
||||
var selectCtrl = new OpenLayers.Control.SelectFeature(vectors,
|
||||
{clickout: true}
|
||||
);
|
||||
|
||||
map.addControl(highlightCtrl);
|
||||
map.addControl(selectCtrl);
|
||||
|
||||
highlightCtrl.activate();
|
||||
selectCtrl.activate();
|
||||
|
||||
map.addControl(new OpenLayers.Control.EditingToolbar(vectors));
|
||||
|
||||
map.setCenter(new OpenLayers.LonLat(0, 0), 1);
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<h1 id="title">OpenLayers Select and Highlight Feature Example</h1>
|
||||
<p id="shortdesc">
|
||||
Select features on click, highlight features on hover.
|
||||
</p>
|
||||
<div id="map" class="smallmap"></div>
|
||||
<p>Select features by clicking on them. Just highlight features by hovering over
|
||||
them.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -20,6 +20,16 @@
|
||||
*/
|
||||
OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* Constant: EVENT_TYPES
|
||||
*
|
||||
* Supported event types:
|
||||
* - *beforefeaturehighlighted* Triggered before a feature is highlighted
|
||||
* - *featurehighlighted* Triggered when a feature is highlighted
|
||||
* - *featureunhighlighted* Triggered when a feature is unhighlighted
|
||||
*/
|
||||
EVENT_TYPES: ["beforefeaturehighlighted", "featurehighlighted", "featureunhighlighted"],
|
||||
|
||||
/**
|
||||
* Property: multipleKey
|
||||
* {String} An event modifier ('altKey' or 'shiftKey') that temporarily sets
|
||||
@@ -61,6 +71,14 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
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. This property has
|
||||
* no effect if hover is false. Defaults to false.
|
||||
*/
|
||||
highlightOnly: false,
|
||||
|
||||
/**
|
||||
* APIProperty: box
|
||||
* {Boolean} Allow feature selection by drawing a box.
|
||||
@@ -150,6 +168,11 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* options - {Object}
|
||||
*/
|
||||
initialize: function(layers, options) {
|
||||
// concatenate events specific to this control with those from the base
|
||||
this.EVENT_TYPES =
|
||||
OpenLayers.Control.SelectFeature.prototype.EVENT_TYPES.concat(
|
||||
OpenLayers.Control.prototype.EVENT_TYPES
|
||||
);
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
if(!(layers instanceof Array)) {
|
||||
layers = [layers];
|
||||
@@ -331,10 +354,15 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
*/
|
||||
overFeature: function(feature) {
|
||||
if(this.hover &&
|
||||
(OpenLayers.Util.indexOf(feature.layer.selectedFeatures, feature) == -1)) {
|
||||
var layer = feature.layer;
|
||||
if(this.hover) {
|
||||
if(this.highlightOnly) {
|
||||
this.highlight(feature);
|
||||
} else if(OpenLayers.Util.indexOf(
|
||||
layer.selectedFeatures, feature) == -1) {
|
||||
this.select(feature);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -347,8 +375,67 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
outFeature: function(feature) {
|
||||
if(this.hover) {
|
||||
if(this.highlightOnly) {
|
||||
// we do nothing if we're not the last highlighter of the
|
||||
// feature
|
||||
if(feature._lastHighlighter == this.id) {
|
||||
// if another select control had highlighted the feature before
|
||||
// we did it ourself then we use that control to highlight the
|
||||
// feature as it was before we highlighted it, else we just
|
||||
// unhighlight it
|
||||
if(feature._prevHighlighter &&
|
||||
feature._prevHighlighter != this.id) {
|
||||
delete feature._lastHighlighter;
|
||||
var control = this.map.getControl(
|
||||
feature._prevHighlighter);
|
||||
if(control) {
|
||||
control.highlight(feature);
|
||||
}
|
||||
} else {
|
||||
this.unhighlight(feature);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.unselect(feature);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: highlight
|
||||
* Redraw feature with the select style.
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
*/
|
||||
highlight: function(feature) {
|
||||
var layer = feature.layer;
|
||||
var cont = this.events.triggerEvent("beforefeaturehighlighted", {
|
||||
feature : feature
|
||||
});
|
||||
if(cont !== false) {
|
||||
feature._prevHighlighter = feature._lastHighlighter;
|
||||
feature._lastHighlighter = this.id;
|
||||
var style = this.selectStyle || this.renderIntent;
|
||||
layer.drawFeature(feature, style);
|
||||
this.events.triggerEvent("featurehighlighted", {feature : feature});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: unhighlight
|
||||
* Redraw feature with the "default" style
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
*/
|
||||
unhighlight: function(feature) {
|
||||
var layer = feature.layer;
|
||||
feature._lastHighlighter = feature._prevHighlighter;
|
||||
delete feature._prevHighlighter;
|
||||
layer.drawFeature(feature, feature.style || feature.layer.style ||
|
||||
"default");
|
||||
this.events.triggerEvent("featureunhighlighted", {feature : feature});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -369,10 +456,7 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
if(cont !== false) {
|
||||
layer.selectedFeatures.push(feature);
|
||||
this.layerData = {};
|
||||
|
||||
var selectStyle = this.selectStyle || this.renderIntent;
|
||||
|
||||
layer.drawFeature(feature, selectStyle);
|
||||
this.highlight(feature);
|
||||
layer.events.triggerEvent("featureselected", {feature: feature});
|
||||
this.onSelect.call(this.scope, feature);
|
||||
}
|
||||
@@ -390,7 +474,7 @@ OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
|
||||
unselect: function(feature) {
|
||||
var layer = feature.layer;
|
||||
// Store feature style for restoration later
|
||||
layer.drawFeature(feature, "default");
|
||||
this.unhighlight(feature);
|
||||
OpenLayers.Util.removeItem(layer.selectedFeatures, feature);
|
||||
layer.events.triggerEvent("featureunselected", {feature: feature});
|
||||
this.onUnselect.call(this.scope, feature);
|
||||
|
||||
@@ -206,6 +206,167 @@
|
||||
control.deactivate();
|
||||
}
|
||||
|
||||
function test_highlighyOnly(t) {
|
||||
t.plan(23);
|
||||
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
|
||||
var map, layer, ctrl1, ctrl2, _feature, feature, evt, _style;
|
||||
|
||||
map = new OpenLayers.Map("map");
|
||||
layer = new OpenLayers.Layer.Vector("name", {isBaseLayer: true});
|
||||
map.addLayer(layer);
|
||||
|
||||
ctrl1 = new OpenLayers.Control.SelectFeature(layer, {
|
||||
highlightOnly: false,
|
||||
hover: false
|
||||
});
|
||||
map.addControl(ctrl1);
|
||||
|
||||
ctrl2 = new OpenLayers.Control.SelectFeature(layer, {
|
||||
highlightOnly: true,
|
||||
hover: true
|
||||
});
|
||||
map.addControl(ctrl2);
|
||||
|
||||
ctrl2.activate();
|
||||
ctrl1.activate();
|
||||
|
||||
feature = new OpenLayers.Feature.Vector();
|
||||
feature.layer = layer;
|
||||
|
||||
// override the layer's getFeatureFromEvent func so that it always
|
||||
// returns the feature referenced to by _feature
|
||||
layer.getFeatureFromEvent = function(evt) { return _feature; };
|
||||
|
||||
evt = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};
|
||||
|
||||
map.zoomToMaxExtent();
|
||||
|
||||
/*
|
||||
* tests
|
||||
*/
|
||||
|
||||
// with renderIntent
|
||||
|
||||
ctrl1.renderIntent = "select";
|
||||
ctrl2.renderIntent = "temporary";
|
||||
|
||||
// mouse over feature, feature is drawn with "temporary"
|
||||
_feature = feature;
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
t.eq(feature.renderIntent, "temporary",
|
||||
"feature drawn with expected render intent after \"mouseover\"");
|
||||
t.eq(feature._lastHighlighter, ctrl2.id,
|
||||
"feature._lastHighlighter properly set after \"mouseover\"");
|
||||
t.eq(feature._prevHighlighter, undefined,
|
||||
"feature._prevHighlighter properly set after \"mouseover\"");
|
||||
|
||||
// click in feature, feature is drawn with "select"
|
||||
_feature = feature;
|
||||
evt.type = "click";
|
||||
map.events.triggerEvent("click", evt);
|
||||
t.eq(feature.renderIntent, "select",
|
||||
"feature drawn with expected render intent after \"clickin\"");
|
||||
t.eq(feature._lastHighlighter, ctrl1.id,
|
||||
"feature._lastHighlighter properly set after \"clickin\"");
|
||||
t.eq(feature._prevHighlighter, ctrl2.id,
|
||||
"feature._prevHighlighter properly set after \"clickin\"");
|
||||
|
||||
// mouse out of feature, feature is still drawn with "select"
|
||||
_feature = null;
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
t.eq(feature.renderIntent, "select",
|
||||
"feature drawn with expected render intent after \"mouseout\"");
|
||||
t.eq(feature._lastHighlighter, ctrl1.id,
|
||||
"feature._lastHighlighter properly set after \"nouseout\"");
|
||||
t.ok(feature._prevHighlighter, ctrl2.id,
|
||||
"feature._prevHighlighter properly set after \"mouseout\"");
|
||||
|
||||
// mouse over feature again, feature is drawn with "temporary"
|
||||
_feature = feature;
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
t.eq(feature.renderIntent, "temporary",
|
||||
"feature drawn with expected render intent after \"mouseover\"");
|
||||
t.eq(feature._lastHighlighter, ctrl2.id,
|
||||
"feature._lastHighlighter properly set after \"mouseover\"");
|
||||
t.eq(feature._prevHighlighter, ctrl1.id,
|
||||
"feature._prevHighlighter properly set after \"mouseover\"");
|
||||
|
||||
// mouve out of feature again, feature is still drawn with "select"
|
||||
_feature = null;
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
t.eq(feature.renderIntent, "select",
|
||||
"feature drawn with expected render intent after \"mouseout\"");
|
||||
t.eq(feature._lastHighlighter, ctrl1.id,
|
||||
"feature._lastHighlighter properly set after \"mouseout\"");
|
||||
t.eq(feature._prevHighlighter, undefined,
|
||||
"feature._prevHighlighter properly set after \"mouseout\"");
|
||||
|
||||
// click out of feature, feature is drawn with "default"
|
||||
_feature = null;
|
||||
evt.type = "click";
|
||||
map.events.triggerEvent("click", evt);
|
||||
t.eq(feature.renderIntent, "default",
|
||||
"feature drawn with expected render intent after \"clickout\"");
|
||||
t.eq(feature._lastHighlighter, undefined,
|
||||
"feature._lastHighlighter properly set after \"clickout\"");
|
||||
t.eq(feature._prevHighlighter, undefined,
|
||||
"feature._prevHighlighter properly set after \"clickout\"");
|
||||
|
||||
// with selectStyle
|
||||
|
||||
ctrl1.selectStyle = OpenLayers.Feature.Vector.style["select"];
|
||||
ctrl2.selectStyle = OpenLayers.Feature.Vector.style["temporary"];
|
||||
|
||||
layer.renderer.drawFeature = function(f, s) {
|
||||
var style = OpenLayers.Feature.Vector.style[_style];
|
||||
t.eq(s, style, "renderer drawFeature called with expected style obj (" + _style + ")");
|
||||
};
|
||||
|
||||
// mouse over feature, feature is drawn with "temporary"
|
||||
_feature = feature;
|
||||
_style = "temporary";
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
|
||||
// click in feature, feature is drawn with "select"
|
||||
_feature = feature;
|
||||
_style = "select";
|
||||
evt.type = "click";
|
||||
map.events.triggerEvent("click", evt);
|
||||
|
||||
// mouse out of feature, feature is still drawn with "select" and
|
||||
// the renderer drawFeature method should not be called
|
||||
_feature = null;
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
|
||||
// mouse over feature again, feature is drawn with "temporary"
|
||||
_feature = feature;
|
||||
_style = "temporary";
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
|
||||
// mouve out of feature again, feature is still drawn with "select"
|
||||
_feature = null;
|
||||
_style = "select";
|
||||
evt.type = "mousemove";
|
||||
map.events.triggerEvent("mousemove", evt);
|
||||
|
||||
// click out of feature, feature is drawn with "default"
|
||||
_feature = null;
|
||||
_style = "default";
|
||||
evt.type = "click";
|
||||
map.events.triggerEvent("click", evt);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user