From ad3f7624093e6e467f6978f1c5afde0641b9bcda Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Sat, 23 Jul 2011 21:24:59 -0500 Subject: [PATCH] Touch events and mouse button selectors. First crack at supporting touch screen for devices like Android and iOS tablets. Part of https://github.com/kanaka/noVNC/issues/48. This change detects touch screen support and uses the touchstart, touchmove, touchend events in place of the normal mouse events. In order to support middle and right mouse clicks, if the device is a touch device, then three toggle buttons are added to the UI representing the left, middle and right mouse buttons. These select which mouse button will be sent when the screen is touched. All the buttons can be toggled off, in which case then the touch events only move the mouse cursor rather than sending a mouse down and mouse up for touchstart and touchend events respectively. This allows fairly full control with the mouse on touch screens. --- include/input.js | 45 ++++++++++++++++++++++++----------- include/ui.js | 53 ++++++++++++++++++++++++++++++++++++++++- include/util.js | 1 + tests/input.html | 61 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 136 insertions(+), 24 deletions(-) diff --git a/include/input.js b/include/input.js index 47b6d772..6c7fecf5 100644 --- a/include/input.js +++ b/include/input.js @@ -460,7 +460,8 @@ Util.conf_defaults(conf, that, defaults, [ ['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'], ['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'], - ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'] + ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'], + ['touchButton', 'rw', 'int', 1, 'Button mask (1, 2, 4) for touch devices (0 means ignore clicks)'] ]); @@ -475,7 +476,11 @@ function onMouseButton(e, down) { } evt = (e ? e : window.event); pos = Util.getEventPosition(e, conf.target, conf.scale); - if (evt.which) { + if (e.touches || e.changedTouches) { + // Touch device + bmask = conf.touchButton; + // If bmask is set + } else if (evt.which) { /* everything except IE */ bmask = 1 << evt.button; } else { @@ -486,7 +491,7 @@ function onMouseButton(e, down) { } //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + // " bmask: " + bmask + "(evt.button: " + evt.button + ")"); - if (conf.onMouseButton) { + if (bmask > 0 && conf.onMouseButton) { Util.Debug("onMouseButton " + (down ? "down" : "up") + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); conf.onMouseButton(pos.x, pos.y, down, bmask); @@ -536,6 +541,8 @@ function onMouseMove(e) { if (conf.onMouseMove) { conf.onMouseMove(pos.x, pos.y); } + Util.stopEvent(e); + return false; } function onMouseDisable(e) { @@ -565,11 +572,17 @@ that.grab = function() { //Util.Debug(">> Mouse.grab"); var c = conf.target; - Util.addEvent(c, 'mousedown', onMouseDown); - Util.addEvent(c, 'mouseup', onMouseUp); - Util.addEvent(c, 'mousemove', onMouseMove); - Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - onMouseWheel); + if ('ontouchstart' in document.documentElement) { + Util.addEvent(c, 'touchstart', onMouseDown); + Util.addEvent(c, 'touchend', onMouseUp); + Util.addEvent(c, 'touchmove', onMouseMove); + } else { + Util.addEvent(c, 'mousedown', onMouseDown); + Util.addEvent(c, 'mouseup', onMouseUp); + Util.addEvent(c, 'mousemove', onMouseMove); + Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } /* Work around right and middle click browser behaviors */ Util.addEvent(document, 'click', onMouseDisable); @@ -582,11 +595,17 @@ that.ungrab = function() { //Util.Debug(">> Mouse.ungrab"); var c = conf.target; - Util.removeEvent(c, 'mousedown', onMouseDown); - Util.removeEvent(c, 'mouseup', onMouseUp); - Util.removeEvent(c, 'mousemove', onMouseMove); - Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - onMouseWheel); + if ('ontouchstart' in document.documentElement) { + Util.removeEvent(c, 'touchstart', onMouseDown); + Util.removeEvent(c, 'touchend', onMouseUp); + Util.removeEvent(c, 'touchmove', onMouseMove); + } else { + Util.removeEvent(c, 'mousedown', onMouseDown); + Util.removeEvent(c, 'mouseup', onMouseUp); + Util.removeEvent(c, 'mousemove', onMouseMove); + Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', + onMouseWheel); + } /* Work around right and middle click browser behaviors */ Util.removeEvent(document, 'click', onMouseDisable); diff --git a/include/ui.js b/include/ui.js index df66da82..f3388ebd 100644 --- a/include/ui.js +++ b/include/ui.js @@ -54,6 +54,19 @@ load: function(target) { html += '
'; html += ' '; html += ' '; + + // Mouse button selectors for touch devices + html += '
Loading
'; + html += '