make click handler work with touch events (closes #2996)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@11201 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -22,7 +22,6 @@
|
|||||||
* - <OpenLayers.Handler>
|
* - <OpenLayers.Handler>
|
||||||
*/
|
*/
|
||||||
OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIProperty: delay
|
* APIProperty: delay
|
||||||
* {Number} Number of milliseconds between clicks before the event is
|
* {Number} Number of milliseconds between clicks before the event is
|
||||||
@@ -89,7 +88,14 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
* {<OpenLayers.Pixel>} The pixel location of the last mousedown.
|
* {<OpenLayers.Pixel>} The pixel location of the last mousedown.
|
||||||
*/
|
*/
|
||||||
down: null,
|
down: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: last
|
||||||
|
* {<OpenLayers.Pixel>} The pixel for the last touchmove. This is
|
||||||
|
* used to
|
||||||
|
*/
|
||||||
|
last: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property: rightclickTimerId
|
* Property: rightclickTimerId
|
||||||
* {Number} The id of the right mouse timeout waiting to clear the
|
* {Number} The id of the right mouse timeout waiting to clear the
|
||||||
@@ -118,7 +124,7 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
// optionally register for mouseup and mousedown
|
// optionally register for mouseup and mousedown
|
||||||
if(this.pixelTolerance != null) {
|
if(this.pixelTolerance != null) {
|
||||||
this.mousedown = function(evt) {
|
this.mousedown = function(evt) {
|
||||||
this.down = evt.xy;
|
this.down = evt;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -134,6 +140,19 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
*/
|
*/
|
||||||
mousedown: null,
|
mousedown: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: touchstart
|
||||||
|
* Handle touchstart.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {Boolean} Continue propagating this event.
|
||||||
|
*/
|
||||||
|
touchstart: function(evt) {
|
||||||
|
this.down = evt;
|
||||||
|
this.last = null;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: mouseup
|
* Method: mouseup
|
||||||
* Handle mouseup. Installed to support collection of right mouse events.
|
* Handle mouseup. Installed to support collection of right mouse events.
|
||||||
@@ -141,16 +160,16 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* {Boolean} Continue propagating this event.
|
* {Boolean} Continue propagating this event.
|
||||||
*/
|
*/
|
||||||
mouseup: function (evt) {
|
mouseup: function (evt) {
|
||||||
var propagate = true;
|
var propagate = true;
|
||||||
|
|
||||||
// Collect right mouse clicks from the mouseup
|
// Collect right mouse clicks from the mouseup
|
||||||
// IE - ignores the second right click in mousedown so using
|
// IE - ignores the second right click in mousedown so using
|
||||||
// mouseup instead
|
// mouseup instead
|
||||||
if (this.checkModifiers(evt) &&
|
if(this.checkModifiers(evt) &&
|
||||||
this.control.handleRightClicks &&
|
this.control.handleRightClicks &&
|
||||||
OpenLayers.Event.isRightClick(evt)) {
|
OpenLayers.Event.isRightClick(evt)) {
|
||||||
propagate = this.rightclick(evt);
|
propagate = this.rightclick(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return propagate;
|
return propagate;
|
||||||
@@ -216,7 +235,10 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
* {Boolean} Continue propagating this event.
|
* {Boolean} Continue propagating this event.
|
||||||
*/
|
*/
|
||||||
dblclick: function(evt) {
|
dblclick: function(evt) {
|
||||||
if(this.passesTolerance(evt)) {
|
// for touch devices trigger dblclick only for
|
||||||
|
// "one finger" touch
|
||||||
|
if(this.passesTolerance(evt) &&
|
||||||
|
(!evt.lastTouches || evt.lastTouches.length == 1)) {
|
||||||
if(this["double"]) {
|
if(this["double"]) {
|
||||||
this.callback('dblclick', [evt]);
|
this.callback('dblclick', [evt]);
|
||||||
}
|
}
|
||||||
@@ -225,6 +247,30 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
return !this.stopDouble;
|
return !this.stopDouble;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: touchmove
|
||||||
|
* Store position of last move, because touchend event can have
|
||||||
|
* an empty "touches" property.
|
||||||
|
*/
|
||||||
|
touchmove: function(evt) {
|
||||||
|
this.last = evt;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: touchend
|
||||||
|
* Correctly set event xy property, and add lastTouches to have
|
||||||
|
* touches property from last touchstart or touchmove
|
||||||
|
*/
|
||||||
|
touchend: function(evt) {
|
||||||
|
if(!evt) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var last = this.last || this.down;
|
||||||
|
evt.xy = last.xy;
|
||||||
|
evt.lastTouches = last.touches;
|
||||||
|
return evt.xy ? this.click(evt) : false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: click
|
* Method: click
|
||||||
* Handle click.
|
* Handle click.
|
||||||
@@ -236,7 +282,12 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
if(this.passesTolerance(evt)) {
|
if(this.passesTolerance(evt)) {
|
||||||
if(this.timerId != null) {
|
if(this.timerId != null) {
|
||||||
// already received a click
|
// already received a click
|
||||||
this.clearTimer();
|
if(evt.lastTouches) {
|
||||||
|
// touch device - we may trigger dblclick
|
||||||
|
this.dblclick(evt);
|
||||||
|
} else {
|
||||||
|
this.clearTimer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// set the timer, send evt only if single is true
|
// set the timer, send evt only if single is true
|
||||||
//use a clone of the event object because it will no longer
|
//use a clone of the event object because it will no longer
|
||||||
@@ -246,7 +297,7 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
this.timerId = window.setTimeout(
|
this.timerId = window.setTimeout(
|
||||||
OpenLayers.Function.bind(this.delayedCall, this, clickEvent),
|
OpenLayers.Function.bind(this.delayedCall, this, clickEvent),
|
||||||
this.delay
|
this.delay
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !this.stopSingle;
|
return !this.stopSingle;
|
||||||
@@ -265,10 +316,10 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
*/
|
*/
|
||||||
passesTolerance: function(evt) {
|
passesTolerance: function(evt) {
|
||||||
var passes = true;
|
var passes = true;
|
||||||
if(this.pixelTolerance != null && this.down) {
|
if(this.pixelTolerance != null && this.down && this.down.xy) {
|
||||||
var dpx = Math.sqrt(
|
var dpx = Math.sqrt(
|
||||||
Math.pow(this.down.x - evt.xy.x, 2) +
|
Math.pow(this.down.xy.x - evt.xy.x, 2) +
|
||||||
Math.pow(this.down.y - evt.xy.y, 2)
|
Math.pow(this.down.xy.y - evt.xy.y, 2)
|
||||||
);
|
);
|
||||||
if(dpx > this.pixelTolerance) {
|
if(dpx > this.pixelTolerance) {
|
||||||
passes = false;
|
passes = false;
|
||||||
@@ -316,6 +367,7 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
|
|||||||
if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
|
if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
|
||||||
this.clearTimer();
|
this.clearTimer();
|
||||||
this.down = null;
|
this.down = null;
|
||||||
|
this.last = null;
|
||||||
deactivated = true;
|
deactivated = true;
|
||||||
}
|
}
|
||||||
return deactivated;
|
return deactivated;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_Handler_Click_events(t) {
|
function test_Handler_Click_events(t) {
|
||||||
t.plan(50);
|
t.plan(80);
|
||||||
|
|
||||||
var map = new OpenLayers.Map('map');
|
var map = new OpenLayers.Map('map');
|
||||||
var control = {
|
var control = {
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
// list below events that should be handled (events) and those
|
// list below events that should be handled (events) and those
|
||||||
// that should not be handled (nonevents) by the handler
|
// that should not be handled (nonevents) by the handler
|
||||||
var events = ["click", "dblclick", "mousedown", "mouseup", "rightclick"];
|
var events = ["click", "dblclick", "mousedown", "mouseup", "rightclick", "touchstart", "touchmove", "touchend"];
|
||||||
var nonevents = ["mousemove", "resize", "focus", "blur"];
|
var nonevents = ["mousemove", "resize", "focus", "blur"];
|
||||||
var handler = new OpenLayers.Handler.Click(control);
|
var handler = new OpenLayers.Handler.Click(control);
|
||||||
// set browser event like properties on the handler
|
// set browser event like properties on the handler
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
handler.activate();
|
handler.activate();
|
||||||
|
|
||||||
// different listeners registered for pixelTolerance option
|
// different listeners registered for pixelTolerance option
|
||||||
var events = ["click", "dblclick", "mousedown", "mouseup", "rightclick"];
|
var events = ["click", "dblclick", "mousedown", "mouseup", "rightclick", "touchstart", "touchmove", "touchend"];
|
||||||
var nonevents = ["mousemove", "resize", "focus", "blur"];
|
var nonevents = ["mousemove", "resize", "focus", "blur"];
|
||||||
var handler = new OpenLayers.Handler.Click(control, {}, {
|
var handler = new OpenLayers.Handler.Click(control, {}, {
|
||||||
pixelTolerance: 2
|
pixelTolerance: 2
|
||||||
@@ -290,6 +290,89 @@
|
|||||||
OpenLayers.Event.isRightClick = temp;
|
OpenLayers.Event.isRightClick = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_touch_click(t) {
|
||||||
|
t.plan(4);
|
||||||
|
|
||||||
|
// set up
|
||||||
|
|
||||||
|
var log;
|
||||||
|
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
var control = {map: map};
|
||||||
|
|
||||||
|
var callbacks = {
|
||||||
|
'click': function(e) {
|
||||||
|
log = {x: e.xy.x, y: e.xy.y,
|
||||||
|
lastTouches: e.lastTouches};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var handler = new OpenLayers.Handler.Click(
|
||||||
|
control, callbacks,
|
||||||
|
{'single': true, pixelTolerance: null});
|
||||||
|
|
||||||
|
// test
|
||||||
|
|
||||||
|
log = null;
|
||||||
|
handler.touchstart({xy: {x: 1, y: 1}, touches: ["foo"]});
|
||||||
|
handler.touchend({});
|
||||||
|
|
||||||
|
t.delay_call(1, function() {
|
||||||
|
t.ok(log != null, "click callback called");
|
||||||
|
if(log != null) {
|
||||||
|
t.eq(log.x, 1, "evt.xy.x as expected");
|
||||||
|
t.eq(log.y, 1, "evt.xy.y as expected");
|
||||||
|
t.eq(log.lastTouches, ["foo"], "evt.lastTouches as expected");
|
||||||
|
}
|
||||||
|
// tear down
|
||||||
|
map.destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_touch_dblclick(t) {
|
||||||
|
t.plan(5);
|
||||||
|
|
||||||
|
// set up
|
||||||
|
|
||||||
|
var log;
|
||||||
|
|
||||||
|
var map = new OpenLayers.Map('map');
|
||||||
|
var control = {map: map};
|
||||||
|
|
||||||
|
var callbacks = {
|
||||||
|
'click': function(e) {
|
||||||
|
log.click = {x: e.xy.x, y: e.xy.y,
|
||||||
|
lastTouches: e.lastTouches};
|
||||||
|
},
|
||||||
|
'dblclick': function(e) {
|
||||||
|
log.dblclick = {x: e.xy.x, y: e.xy.y,
|
||||||
|
lastTouches: e.lastTouches};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var handler = new OpenLayers.Handler.Click(
|
||||||
|
control, callbacks,
|
||||||
|
{'double': true, pixelTolerance: null});
|
||||||
|
|
||||||
|
// test
|
||||||
|
|
||||||
|
log = {};
|
||||||
|
handler.touchstart({xy: {x: 1, y: 1}, touches: ["foo"]});
|
||||||
|
handler.touchend({});
|
||||||
|
handler.touchstart({xy: {x: 1, y: 1}, touches: ["foo"]});
|
||||||
|
handler.touchend({});
|
||||||
|
|
||||||
|
t.eq(log.click, undefined, "click callback not called");
|
||||||
|
t.ok(log.dblclick != undefined, "dblclick callback called");
|
||||||
|
if(log.dblclick != undefined) {
|
||||||
|
t.eq(log.dblclick.x, 1, "evt.xy.x as expected");
|
||||||
|
t.eq(log.dblclick.y, 1, "evt.xy.y as expected");
|
||||||
|
t.eq(log.dblclick.lastTouches, ["foo"], "evt.lastTouches as expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// tear down
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
Reference in New Issue
Block a user