Changeset 5335
- Timestamp:
- 12/04/07 04:54:05 (1 year ago)
- Files:
-
- sandbox/elemoine/playground/examples/select-feature.html (modified) (3 diffs)
- sandbox/elemoine/playground/lib/OpenLayers/Control/DragFeature.js (modified) (1 diff)
- sandbox/elemoine/playground/lib/OpenLayers/Control/SelectFeature.js (modified) (8 diffs)
- sandbox/elemoine/playground/lib/OpenLayers/Handler/Feature.js (modified) (4 diffs)
- sandbox/elemoine/playground/tests/Handler/test_Feature.html (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
sandbox/elemoine/playground/examples/select-feature.html
r5211 r5335 14 14 <script src="../lib/OpenLayers.js"></script> 15 15 <script type="text/javascript"> 16 var map, drawControls , select;16 var map, drawControls; 17 17 OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2'; 18 18 function init(){ … … 39 39 vectors, OpenLayers.Handler.Polygon 40 40 ), 41 select: new OpenLayers.Control.SelectFeature(vectors), 41 click: new OpenLayers.Control.SelectFeature( 42 vectors 43 ), 44 multiple: new OpenLayers.Control.SelectFeature( 45 vectors, {multiple: true} 46 ), 47 clickout: new OpenLayers.Control.SelectFeature( 48 vectors, {clickout: true} 49 ), 50 clickoutmulti : new OpenLayers.Control.SelectFeature( 51 vectors, {clickout: true, multiple: true} 52 ), 42 53 hover: new OpenLayers.Control.SelectFeature( 43 54 vectors, {hover: true} … … 89 100 </li> 90 101 <li> 91 <input type="radio" name="type" value=" select" id="selectToggle"102 <input type="radio" name="type" value="click" id="clickToggle" 92 103 onclick="toggleControl(this);" /> 93 <label for="selectToggle">select feature on click</label> 104 <label for="clickToggle">select feature on click</label> 105 </li> 106 <li> 107 <input type="radio" name="type" value="multiple" id="multipleToggle" 108 onclick="toggleControl(this);" /> 109 <label for="multipleToggle">select multiple features on click</label> 110 </li> 111 <li> 112 <input type="radio" name="type" value="clickout" id="clickoutToggle" 113 onclick="toggleControl(this);" /> 114 <label for="clickoutToggle">select feature on click, unselect feature on clickout</label> 115 </li> 116 <li> 117 <input type="radio" name="type" value="clickoutmulti" id="clickoutmultiToggle" 118 onclick="toggleControl(this);" /> 119 <label for="clickoutmultiToggle">select multiple features on click, unselect features on clickout</label> 94 120 </li> 95 121 <li> sandbox/elemoine/playground/lib/OpenLayers/Control/DragFeature.js
r4985 r5335 125 125 }, this.dragCallbacks); 126 126 this.dragHandler = new OpenLayers.Handler.Drag(this, this.dragCallbacks); 127 this.featureCallbacks = OpenLayers.Util.extend({ over: this.overFeature,128 out: this.outFeature127 this.featureCallbacks = OpenLayers.Util.extend({movein: this.overFeature, 128 moveout: this.outFeature 129 129 }, this.featureCallbacks); 130 130 var handlerOptions = {geometryTypes: this.geometryTypes}; sandbox/elemoine/playground/lib/OpenLayers/Control/SelectFeature.js
r5157 r5335 23 23 24 24 /** 25 * APIProperty: clickout 26 * {Boolean} Unselect features when clicking outside any feature. 27 */ 28 clickout: false, 29 30 /** 25 31 * APIProperty: hover 26 32 * {Boolean} Select on mouse over and deselect on mouse out. If true, this … … 85 91 this.layer = layer; 86 92 this.callbacks = OpenLayers.Util.extend({ 87 click: this.clickFeature, 88 over: this.overFeature, 89 out: this.outFeature 93 clickin: this.clickinFeature, 94 clickout: this.clickoutFeature, 95 movein: this.moveinFeature, 96 moveout: this.moveoutFeature 90 97 }, this.callbacks); 91 var handlerOptions = {geometryTypes: this.geometryTypes}; 98 var handlerOptions = { 99 geometryTypes: this.geometryTypes, 100 multiple: this.multiple}; 92 101 this.handler = new OpenLayers.Handler.Feature(this, layer, 93 102 this.callbacks, … … 96 105 97 106 /** 98 * Method: clickFeature 99 * Called when the feature handler detects a click on a feature 107 * Method: unselectAll 108 * Unselect all selected features. 109 */ 110 unselectAll: function() { 111 while (this.layer.selectedFeatures.length > 0) { 112 this.unselect(this.layer.selectedFeatures[0]); 113 } 114 }, 115 116 /** 117 * Method: clickinFeature 118 * Called on click in a feature 119 * Only responds if this.hover is false. 100 120 * 101 121 * Parameters: 102 122 * feature - {<OpenLayers.Vector.Feature>} 103 123 */ 104 click Feature: function(feature) {124 clickinFeature: function(feature) { 105 125 if(this.hover) { 106 126 return; 107 127 } 108 128 if (this.multiple) { 109 if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) > -1) { 129 if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) > -1 && 130 !this.clickout) { 110 131 this.unselect(feature); 111 132 } else { … … 113 134 } 114 135 } else { 115 if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) > -1) { 116 this.unselect(feature); 136 if(this.clickout) { 137 if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) < 0) { 138 this.select(feature); 139 } 117 140 } else { 118 if (this.layer.selectedFeatures) { 119 for (var i = 0; i < this.layer.selectedFeatures.length; i++) { 120 this.unselect(this.layer.selectedFeatures[i]); 121 } 141 if(OpenLayers.Util.indexOf(this.layer.selectedFeatures, feature) > -1) { 142 this.unselect(feature); 143 } else { 144 this.unselectAll(); 145 this.select(feature); 122 146 } 123 this.select(feature);124 147 } 125 148 } … … 127 150 128 151 /** 129 * Method: overFeature 130 * Called when the feature handler detects a mouse-over on a feature. 152 * Method: clickoutFeature 153 * Called on click outside a previously clicked (selected) feature. 154 * Only responds if this.hover is false. 155 * 156 * Parameters: 157 * feature - {<OpenLayers.Vector.Feature>} 158 */ 159 clickoutFeature: function(feature) { 160 if(this.hover || !this.clickout) { 161 return; 162 } 163 this.unselectAll(); 164 }, 165 166 /** 167 * Method: moveinFeature 168 * Called on move in a feature (mouseover). 131 169 * Only responds if this.hover is true. 132 170 * … … 134 172 * feature - {<OpenLayers.Feature.Vector>} 135 173 */ 136 overFeature: function(feature) {174 moveinFeature: function(feature) { 137 175 if(!this.hover) { 138 176 return; … … 144 182 145 183 /** 146 * Method: outFeature147 * Called when the feature handler detects a mouse-out on a feature.184 * Method: moveoutFeature 185 * Called on move out of a selected feature (mouseout). 148 186 * Only responds if this.hover is true. 149 187 * … … 151 189 * feature - {<OpenLayers.Feature.Vector>} 152 190 */ 153 outFeature: function(feature) {191 moveoutFeature: function(feature) { 154 192 if(!this.hover) { 155 193 return; sandbox/elemoine/playground/lib/OpenLayers/Handler/Feature.js
r4985 r5335 9 9 * Class: OpenLayers.Handler.Feature 10 10 * Handler to respond to mouse events related to a drawn feature. 11 * Callbacks will be called for over, move, out, up, down, and click 12 * (corresponding to the equivalent mouse events). 11 * Callbacks will be called for move, out, up, down, click, and 12 * dblclick. 13 * 14 * The high-level events supported by this handler are: clickin 15 * clickout, downin, downout, upin, upout, movein, moveout, 16 * dblclickin, and dblclickout. 13 17 */ 14 18 OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, { 15 19 16 20 /** 21 * Property: clickFeature 22 * {<OpenLayers.Feature.Vector>} 23 */ 24 clickFeature: null, 25 26 /** 27 * Property: moveFeature 28 * {<OpenLayers.Feature.Vector>} 29 */ 30 moveFeature: null, 31 32 /** 33 * Property: downFeature 34 * {<OpenLayers.Feature.Vector>} 35 */ 36 downFeature: null, 37 38 /** 39 * Property: upFeature 40 * {<OpenLayers.Feature.Vector>} 41 */ 42 upFeature: null, 43 44 /** 45 * Property: dblclickFeature 46 * {<OpenLayers.Feature.Vector>} 47 */ 48 dblclickFeature: null, 49 50 /** 51 * Property: multiple 52 * If set to true, the out callback isn't called if out of last 53 * feature and in to a new one. 54 */ 55 multiple: false, 56 57 /** 17 58 * To restrict dragging to a limited set of geometry types, send a list 18 59 * of strings corresponding to the geometry class names. … … 27 68 */ 28 69 layerIndex: null, 29 30 /**31 * Property: feature32 * {<OpenLayers.Feature.Vector>}33 */34 feature: null,35 70 36 71 /** … … 50 85 }, 51 86 87 52 88 /** 53 89 * Method: click 54 * Handle click. Call the "click" callback if down on a feature. 55 * 56 * Parameters: 57 * evt - {Event} 90 * Handle click. Call the "clickin" callback if click on a feature, 91 * or the "clickout" callback if click outside a feature previously 92 * clicked in. 93 * 94 * Parameters: 95 * evt - {Event} 96 * 97 * Returns: 98 * {Boolean} 58 99 */ 59 100 click: function(evt) { 60 var selected = this.select('click', evt); 61 return !selected; // stop event propagation if selected 62 }, 63 101 return !this.handle('click', evt); 102 }, 103 64 104 /** 65 105 * Method: mousedown 66 * Handle mouse down. Call the "down" callback if down on a feature. 67 * 68 * Parameters: 69 * evt - {Event} 106 * Handle mouse down. Call the "downin" callback if down on a feature, 107 * or the "downout" callback if down outside a feature previously 108 * down'ed in. 109 * 110 * Parameters: 111 * evt - {Event} 112 * 113 * Returns: 114 * {Boolean} 70 115 */ 71 116 mousedown: function(evt) { 72 var selected = this.select('down', evt); 73 return !selected; // stop event propagation if selected 117 return !this.handle('down', evt); 74 118 }, 75 119 76 120 /** 77 121 * Method: mousemove 78 * Handle mouse moves. Call the "move" callback if moving over a feature. 79 * Call the "over" callback if moving over a feature for the first time. 80 * Call the "out" callback if moving off of a feature. 81 * 82 * Parameters: 83 * evt - {Event} 122 * Handle mouse moves. Call the "movein" callback if move on a feature, 123 * or the "moveout" callback if move outside a feature previously 124 * moved in. 125 * 126 * Parameters: 127 * evt - {Event} 128 * 129 * Returns: 130 * {Boolean} 84 131 */ 85 132 mousemove: function(evt) { 86 this. select('move', evt);133 this.handle('move', evt); 87 134 return true; 88 135 }, … … 90 137 /** 91 138 * Method: mouseup 92 * Handle mouse up. Call the "up" callback if up on a feature. 93 * 94 * Parameters: 95 * evt - {Event} 139 * Handle mouse up. Call the "upin" callback if up on a feature, 140 * or the "upout" callback if up outside a feature previously 141 * up'ed in. 142 * 143 * Parameters: 144 * evt - {Event} 145 * 146 * Returns: 147 * {Boolean} 96 148 */ 97 149 mouseup: function(evt) { 98 var selected = this.select('up', evt); 99 return !selected; // stop event propagation if selected 150 return !this.handle('up', evt); 100 151 }, 101 152 102 153 /** 103 154 * Method: dblclick 104 * Capture double-clicks. Let the event continue propagating if the 105 * double-click doesn't hit a feature. Otherwise call the dblclick 106 * callback. 107 * 108 * Parameters: 109 * evt - {Event} 155 * Handle dblclick. Call the "dblclickin" callback if dblclick on a feature, 156 * or the "dblickout" callback if dblclick outside a feature previously 157 * dblclicked in. 158 * 159 * Parameters: 160 * evt - {Event} 161 * 162 * Returns: 163 * {Boolean} 110 164 */ 111 165 dblclick: function(evt) { 112 var selected = this.select('dblclick', evt); 113 return !selected; // stop event propagation if selected 114 }, 115 116 /** 117 * Method: select 118 * Trigger the appropriate callback if a feature is under the mouse. 119 * 120 * Parameters: 121 * type - {String} Callback key 122 * 123 * Returns: 124 * {Boolean} A feature was selected 125 */ 126 select: function(type, evt) { 166 return !this.handle('dblclick', evt); 167 }, 168 169 /** 170 * Method: geometryTypeMatches 171 * Return true if the geometry type of the passed feature matches 172 * one of the geometry types in the geometryTypes array. 173 * 174 * Parameters: 175 * feature - {<OpenLayers.Vector.Feature>} 176 * 177 * Returns: 178 * {Boolean} 179 */ 180 geometryTypeMatches: function(feature) { 181 return this.geometryTypes == null || 182 OpenLayers.Util.indexOf(this.geometryTypes, 183 feature.geometry.CLASS_NAME) > -1; 184 }, 185 186 /** 187 * Method: handle 188 * 189 * Parameters: 190 * type - {String} the low-level event type 191 * evt - {Event} 192 * 193 * Returns: 194 * {Boolean} 195 */ 196 handle: function(type, evt) { 127 197 var feature = this.layer.getFeatureFromEvent(evt); 128 var selected = false; 129 if(feature) { 130 if(this.geometryTypes == null || 131 (OpenLayers.Util.indexOf(this.geometryTypes, 132 feature.geometry.CLASS_NAME) > -1)) { 133 // three cases: 134 // over a new, out of the last and over a new, or still on the last 135 if(!this.feature) { 136 // over a new feature 137 this.callback('over', [feature]); 138 } else if(this.feature != feature) { 139 // out of the last and over a new 140 this.callback('out', [this.feature]); 141 this.callback('over', [feature]); 198 var lastFeature = this[type + 'Feature']; 199 var stopEvtPropag = false; 200 if (feature) { 201 if (this.geometryTypeMatches(feature)) { 202 if (lastFeature && (lastFeature != feature) && !this.multiple) { 203 this.callback(type + 'out', [lastFeature]); 142 204 } 143 this. feature = feature;144 this.callback(type, [feature]);145 s elected= true;205 this.callback(type + 'in', [feature]); 206 lastFeature = feature; 207 stopEvtPropag = true; 146 208 } else { 147 if(this.feature && (this.feature != feature)) { 148 // out of the last and over a new 149 this.callback('out', [this.feature]); 150 this.feature = null; 209 if (lastFeature && (lastFeature != feature)) { 210 this.callback(type + 'out', [lastFeature]); 211 lastFeature = feature; 151 212 } 152 selected = false;153 213 } 154 214 } else { 155 if(this.feature) { 156 // out of the last 157 this.callback('out', [this.feature]); 158 this.feature = null; 215 if (lastFeature) { 216 this.callback(type + 'out', [lastFeature]); 217 lastFeature = null; 159 218 } 160 selected = false;161 219 } 162 return selected; 220 this[type + 'Feature'] = lastFeature; 221 return stopEvtPropag; 163 222 }, 164 223 sandbox/elemoine/playground/tests/Handler/test_Feature.html
r4243 r5335 100 100 101 101 function test_Handler_feature_geometrytype_limit(t) { 102 t.plan( 2);102 t.plan(1); 103 103 var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0)); 104 104 var map = new OpenLayers.Map('map'); … … 113 113 t.eq(featurelist[0].id, feature.id, "Correct feature called back on"); 114 114 } 115 handler. select("foo", {});116 handler. feature = null;115 handler.handle("click", {}); 116 handler.clickFeature = null; 117 117 handler.callback = function(type,featurelist) { 118 118 t.fail("Shouldn't have called back on " + featurelist[0].geometry); 119 119 } 120 120 feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(0,0)); 121 handler. select("foo", {});121 handler.handle("click", {}); 122 122 } 123 123 function test_Handler_Feature_callbacks(t) { 124 t.plan( 75);124 t.plan(50); 125 125 126 126 var map = new OpenLayers.Map('map', {controls: []}); … … 181 181 handler.feature = null; 182 182 183 numEvents[evtShortName] = 0; 184 numEvents["over"] = 0; 185 numEvents["out"] = 0; 183 numEvents[evtShortName + "in"] = 0; 184 numEvents[evtShortName + "out"] = 0; 186 185 oldFeature = null; 187 186 newFeature = new OpenLayers.Feature.Vector(); 188 callbacks[evtShortName] = getCallback(evtShortName, newFeature); 189 callbacks["over"] = getCallback("over", newFeature); 190 callbacks["out"] = getCallback("out", oldFeature); 187 callbacks[evtShortName + "in"] = getCallback(evtShortName + "in", newFeature); 188 callbacks[evtShortName + "out"] = getCallback(evtShortName + "out", oldFeature); 191 189 map.events.triggerEvent(evtLongName, evtPx); 192 t.ok(numEvents[evtShortName] == 1, evtShortName + " triggered click callback"); 193 t.ok(numEvents["over"] == 1, evtShortName + " triggered over callbacks"); 194 t.ok(numEvents["out"] == 0, evtShortName + " did not trigger out callback"); 195 196 numEvents[evtShortName] = 0; 197 numEvents["over"] = 0; 198 numEvents["out"] = 0; 190 t.ok(numEvents[evtShortName + "in"] == 1, evtLongName + " triggered " + evtShortName + "in callback"); 191 t.ok(numEvents[evtShortName + "out"] == 0, evtLongName + " did not trigger " + evtShortName + "out callback"); 192 193 numEvents[evtShortName + "in"] = 0; 194 numEvents[evtShortName + "out"] = 0; 199 195 oldFeature = newFeature; 200 196 newFeature = new OpenLayers.Feature.Vector(); 201 callbacks[evtShortName] = getCallback(evtShortName, newFeature); 202 callbacks["over"] = getCallback("over", newFeature); 203 callbacks["out"] = getCallback("out", oldFeature); 197 callbacks[evtShortName + "in"] = getCallback(evtShortName + "in", newFeature); 198 callbacks[evtShortName + "out"] = getCallback(evtShortName + "out", oldFeature); 204 199 map.events.triggerEvent(evtLongName, evtPx); 205 t.ok(numEvents[evtShortName] == 1, evtShortName + " triggered click callback"); 206 t.ok(numEvents["over"] == 1, evtShortName + " triggered over callbacks"); 207 t.ok(numEvents["out"] == 1, evtShortName + " triggered out callback"); 208 209 numEvents[evtShortName] = 0; 210 numEvents["over"] = 0; 211 numEvents["out"] = 0; 212 oldFeature = newFeature; 213 callbacks[evtShortName] = getCallback(evtShortName, newFeature); 214 callbacks["over"] = getCallback("over", newFeature); 215 callbacks["out"] = getCallback("out", oldFeature); 200 t.ok(numEvents[evtShortName + "in"] == 1, evtLongName + " triggered " + evtShortName + "in callback"); 201 t.ok(numEvents[evtShortName + "out"] == 1, evtLongName + " triggered " + evtShortName + "out callback"); 202 203 numEvents[evtShortName + "in"] = 0; 204 numEvents[evtShortName + "out"] = 0; 205 oldFeature = newFeature; 206 callbacks[evtShortName + "in"] = getCallback(evtShortName + "in", newFeature); 207 callbacks[evtShortName + "out"] = getCallback(evtShortName + "out", oldFeature); 216 208 map.events.triggerEvent(evtLongName, evtPx); 217 t.ok(numEvents[evtShortName] == 1, evtShortName + " triggered click callback"); 218 t.ok(numEvents["over"] == 0, evtShortName + " did not trigger over callbacks"); 219 t.ok(numEvents["out"] == 0, evtShortName + " did not trigger out callback"); 209 t.ok(numEvents[evtShortName + "in"] == 1, evtLongName + " triggered " + evtShortName + "in callback"); 210 t.ok(numEvents[evtShortName + "out"] == 0, evtLongName + " did not trigger " + evtShortName + "out callback"); 220 211 } 221 212 }
