making drawing handler work on touch devices. p=sbrunner, r=me (closes #3072)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11563 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
ahocevar
2011-02-27 15:00:38 +00:00
parent ba8aed56ef
commit 33eef42075
7 changed files with 535 additions and 48 deletions

View File

@@ -223,12 +223,12 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
* Returns:
* {Boolean} Allow event propagation
*/
mousedown: function(evt) {
down: function(evt) {
var stopDown = this.stopDown;
if(this.freehandMode(evt)) {
stopDown = true;
}
if(!this.lastDown || !this.lastDown.equals(evt.xy)) {
if (!this.touch && (!this.lastDown || !this.passesTolerance(this.lastDown, evt.xy, this.pixelTolerance))) {
this.modifyFeature(evt.xy, !!this.lastUp);
}
this.mouseDown = true;
@@ -248,7 +248,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
* Returns:
* {Boolean} Allow event propagation
*/
mousemove: function (evt) {
move: function (evt) {
if(this.stoppedDown && this.freehandMode(evt)) {
if(this.persist) {
this.destroyPersistedFeature();
@@ -256,7 +256,7 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
this.addPoint(evt.xy);
return false;
}
if(!this.mouseDown || this.stoppedDown) {
if (!this.touch && (!this.mouseDown || this.stoppedDown)) {
this.modifyFeature(evt.xy, !!this.lastUp);
}
return true;
@@ -273,13 +273,17 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
* Returns:
* {Boolean} Allow event propagation
*/
mouseup: function (evt) {
if(this.mouseDown && (!this.lastUp || !this.lastUp.equals(evt.xy))) {
up: function (evt) {
if (this.mouseDown && (!this.lastUp || !this.passesTolerance(
this.lastUp, evt.xy, this.dblclickTolerance))) {
if(this.stoppedDown && this.freehandMode(evt)) {
this.removePoint();
this.finalize();
} else {
if(this.lastDown.equals(evt.xy)) {
if (this.passesTolerance(this.lastDown, evt.xy, this.pixelTolerance)) {
if (this.touch) {
this.modifyFeature(evt.xy);
}
if(this.lastUp == null && this.persist) {
this.destroyPersistedFeature();
}
@@ -290,7 +294,15 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
}
this.stoppedDown = this.stopDown;
this.mouseDown = false;
return !this.stopUp;
return !this.stopUp && !this.isDblclick;
},
/**
* Method: finishTouchGeometry
* Finish the geometry and send it back to the control.
*/
finishTouchGeometry: function() {
this.finishGeometry();
},
/**

View File

@@ -95,7 +95,50 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
* {Object} Any optional properties to be set on the sketch layer.
*/
layerOptions: null,
/**
* APIProperty: pixelTolerance
* {Number} Maximum number of pixels between mouseup and mousedown for an
* event to be considered a click. Default is 5. If set to an
* integer value, clicks with a drag greater than the value will be
* ignored. This property can only be set when the handler is
* constructed.
*/
pixelTolerance: 5,
/**
* APIProperty: dblclickTolerance
* {Number} Maximum number of pixels between two touchend for an
* event to be considered a dblclick. Default is 20.
*/
dblclickTolerance: 20,
/**
* Property: touch
* {Boolean} Indcates the support of touch events.
*/
touch: false,
/**
* Property: timerId
* {Integer} The timer used to test the double touch.
*/
timerId: null,
/**
* Property: last
* {<OpenLayers.Pixel>} The last pixel used to know the distance between
* two touches (for double touch).
*/
last: null,
/**
* Property: dblclick
* {Boolean} The current event is a dblclick.
*/
isDblclick: false,
/**
* Constructor: OpenLayers.Handler.Point
* Create a new point handler.
@@ -213,6 +256,14 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
}
},
/**
* Method: finishTouchGeometry
* Finish the geometry and send it back to the control.
*/
finishTouchGeometry: function() {
this.finalize();
},
/**
* Method: finalize
* Finish the geometry and call the "done" callback.
@@ -333,6 +384,127 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
var geom = this.getGeometry();
return geom && geom.clone();
},
/**
* Method: mousedown
* Handle mousedown.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
mousedown: function(evt) {
if (this.touch) {
return;
}
return this.down(evt);
},
/**
* Method: touchstart
* Handle touchstart.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
touchstart: function(evt) {
this.touch = true;
var last = this.last;
this.last = evt.xy;
if (this.timerId &&
this.passesTolerance(last, evt.xy, this.dblclickTolerance)) {
this.isDblclick = true;
// a valid touch immediately adds a component and leaves us with a
// complete geometry
this.finishTouchGeometry();
window.clearTimeout(this.timerId);
this.timerId = null;
return false;
}
else {
if (this.timerId) {
window.clearTimeout(this.timerId);
this.timerId = null;
}
this.isDblclick = false;
this.timerId = window.setTimeout(
OpenLayers.Function.bind(function() {
this.timerId = null;
}, this), 300);
return this.down(evt);
}
},
/**
* Method: mousemove
* Handle mousemove.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
mousemove: function(evt) {
if (this.touch) {
return;
}
return this.move(evt);
},
/**
* Method: touchmove
* Handle touchmove.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
touchmove: function(evt) {
this.last = evt.xy;
return this.move(evt);
},
/**
* Method: mouseup
* Handle mouseup.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
mouseup: function(evt) {
if (this.touch) {
return;
}
return this.up(evt);
},
/**
* Method: touchend
* Handle touchend.
*
* Parameters:
* evt - {Event} The browser event
*
* Returns:
* {Boolean} Allow event propagation
*/
touchend: function(evt) {
evt.xy = this.last;
return this.up(evt);
},
/**
* Method: mousedown
@@ -345,10 +517,12 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
* Returns:
* {Boolean} Allow event propagation
*/
mousedown: function(evt) {
down: function(evt) {
this.mouseDown = true;
this.lastDown = evt.xy;
this.modifyFeature(evt.xy);
if (!this.touch) {
this.modifyFeature(evt.xy);
}
this.stoppedDown = this.stopDown;
return !this.stopDown;
},
@@ -364,8 +538,8 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
* Returns:
* {Boolean} Allow event propagation
*/
mousemove: function (evt) {
if(!this.mouseDown || this.stoppedDown) {
move: function (evt) {
if(!this.touch && (!this.mouseDown || this.stoppedDown)) {
this.modifyFeature(evt.xy);
}
return true;
@@ -382,18 +556,24 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
* Returns:
* {Boolean} Allow event propagation
*/
mouseup: function (evt) {
up: function (evt) {
this.mouseDown = false;
this.stoppedDown = this.stopDown;
// check keyboard modifiers
if(!this.checkModifiers(evt)) {
return true;
}
// ignore double-clicks
if(this.lastUp && this.lastUp.equals(evt.xy)) {
if (this.lastUp && this.passesTolerance(this.lastUp, evt.xy,
this.dblclickTolerance)) {
return true;
}
if(this.lastDown && this.lastDown.equals(evt.xy)) {
if (this.lastDown && this.passesTolerance(this.lastDown, evt.xy,
this.pixelTolerance)) {
if (this.touch) {
this.modifyFeature(evt.xy);
}
if(this.persist) {
this.destroyPersistedFeature();
}
@@ -420,5 +600,28 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
}
},
/**
* Method: passesTolerance
* Determine whether the event is within the optional pixel tolerance.
* Note that the pixel tolerance check only works if mousedown events get
* to the listeners registered here. If they are stopped by other
* elements, <pixelTolerance> and <dblclickTolerance> will have no effect
* here (this method will always return true).
*
* Returns:
* {Boolean} The click is within the pixel tolerance (if specified).
*/
passesTolerance: function(pixel1, pixel2, tolerance) {
var passes = true;
if (tolerance != null && pixel1 && pixel2) {
var dist = pixel1.distanceTo(pixel2);
if (dist > tolerance) {
passes = false;
}
}
return passes;
},
CLASS_NAME: "OpenLayers.Handler.Point"
});

View File

@@ -148,7 +148,18 @@ OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, {
point.y = last.y;
}
},
/**
* Method: finishTouchGeometry
* Finish the geometry and send it back to the control.
*/
finishTouchGeometry: function() {
var index = this.line.geometry.components.length - 2;
this.line.geometry.removeComponent(this.line.geometry.components[index]);
this.removePoint();
this.finalize();
},
/**
* Method: finalizeInteriorRing
* Enforces that new ring has some area and doesn't contain vertices of any