From 17160f49e0747668dd82b351a9bd3f6e1ed1e211 Mon Sep 17 00:00:00 2001 From: euzuro Date: Tue, 26 Aug 2008 23:27:04 +0000 Subject: [PATCH] Add support in OL for right-click capturing, including dbl-right-clicks (for zooming out in navigation control). Thanks to David Martin for this nice patch and the great 8 foot austrian for his review (Closes #1359) git-svn-id: http://svn.openlayers.org/trunk/openlayers@7872 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- lib/OpenLayers/Control/Navigation.js | 39 +++++++++++--- lib/OpenLayers/Events.js | 17 +++++- lib/OpenLayers/Handler/Click.js | 79 ++++++++++++++++++++++++++++ tests/Handler/Click.html | 8 +-- 4 files changed, 132 insertions(+), 11 deletions(-) diff --git a/lib/OpenLayers/Control/Navigation.js b/lib/OpenLayers/Control/Navigation.js index 38ae14036b..6d7be80d44 100644 --- a/lib/OpenLayers/Control/Navigation.js +++ b/lib/OpenLayers/Control/Navigation.js @@ -47,6 +47,12 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, { * {Boolean} Whether the mousewheel should zoom the map */ zoomWheelEnabled: true, + + /** + * APIProperty: handleRightClicks + * {Boolean} Whether or not to handle right clicks. Default is false. + */ + handleRightClicks: true, /** * Constructor: OpenLayers.Control.Navigation @@ -110,12 +116,22 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, { * Method: draw */ draw: function() { - this.handlers.click = new OpenLayers.Handler.Click(this, - { 'dblclick': this.defaultDblClick }, - { - 'double': true, - 'stopDouble': true - }); + // disable right mouse context menu for support of right click events + if (this.handleRightClicks) { + this.map.div.oncontextmenu = function () { return false;}; + } + + var clickCallbacks = { + 'dblclick': this.defaultDblClick, + 'dblrightclick': this.defaultDblRightClick + }; + var clickOptions = { + 'double': true, + 'stopDouble': true + }; + this.handlers.click = new OpenLayers.Handler.Click( + this, clickCallbacks, clickOptions + ); this.dragPan = new OpenLayers.Control.DragPan( OpenLayers.Util.extend({map: this.map}, this.dragPanOptions) ); @@ -140,6 +156,17 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, { this.map.setCenter(newCenter, this.map.zoom + 1); }, + /** + * Method: defaultRightDblClick + * + * Parameters: + * evt - {Event} + */ + defaultDblRightClick: function (evt) { + var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); + this.map.setCenter(newCenter, this.map.zoom - 1); + }, + /** * Method: wheelChange * diff --git a/lib/OpenLayers/Events.js b/lib/OpenLayers/Events.js index 98d3091c1a..2515f11d77 100644 --- a/lib/OpenLayers/Events.js +++ b/lib/OpenLayers/Events.js @@ -104,6 +104,21 @@ OpenLayers.Event = { ((event.button) && (event.button == 1))); }, + /** + * Method: isRightClick + * Determine whether event was caused by a right mouse click. + * + * Parameters: + * event - {Event} + * + * Returns: + * {Boolean} + */ + isRightClick: function(event) { + return (((event.which) && (event.which == 3)) || + ((event.button) && (event.button == 2))); + }, + /** * Method: stop * Stops an event from propagating. @@ -352,7 +367,7 @@ OpenLayers.Events = OpenLayers.Class({ BROWSER_EVENTS: [ "mouseover", "mouseout", "mousedown", "mouseup", "mousemove", - "click", "dblclick", + "click", "dblclick", "rightclick", "dblrightclick", "resize", "focus", "blur" ], diff --git a/lib/OpenLayers/Handler/Click.js b/lib/OpenLayers/Handler/Click.js index 42737e868d..392ad80121 100644 --- a/lib/OpenLayers/Handler/Click.js +++ b/lib/OpenLayers/Handler/Click.js @@ -89,6 +89,13 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, { */ down: null, + /** + * Property: rightclickTimerId + * {Number} The id of the right mouse timeout waiting to clear the + * . + */ + rightclickTimerId: null, + /** * Constructor: OpenLayers.Handler.Click * Create a new click handler. @@ -125,6 +132,78 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, { * {Boolean} Continue propagating this event. */ mousedown: null, + + /** + * Method: mouseup + * Handle mouseup. Installed to support collection of right mouse events. + * + * Returns: + * {Boolean} Continue propagating this event. + */ + mouseup: function (evt) { + var propagate = true; + + // Collect right mouse clicks from the mouseup + // IE - ignores the second right click in mousedown so using + // mouseup instead + if (this.checkModifiers(evt) && + this.control.handleRightClicks && + OpenLayers.Event.isRightClick(evt)) { + propogate = this.rightclick(evt); + } + + return propagate; + }, + + /** + * Method: rightclick + * Handle rightclick. For a dblrightclick, we get two clicks so we need + * to always register for dblrightclick to properly handle single + * clicks. + * + * Returns: + * {Boolean} Continue propagating this event. + */ + rightclick: function(evt) { + if(this.passesTolerance(evt)) { + if(this.rightclickTimerId != null) { + //Second click received before timeout this must be + // a double click + this.clearTimer(); + this.callback('dblrightclick', [evt]); + return !this.stopDouble; + } else { + //Set the rightclickTimerId, send evt only if double is + // true else trigger single + var clickEvent = this['double'] ? + OpenLayers.Util.extend({}, evt) : + this.callback('rightclick', [evt]); + + var delayedRightCall = OpenLayers.Function.bind( + this.delayedRightCall, + this, + clickEvent + ); + this.rightclickTimerId = window.setTimeout( + delayedRightCall, this.delay + ); + } + } + return !this.stopSingle; + }, + + /** + * Method: delayedRightCall + * Sets to null. And optionally triggers the + * rightclick callback if evt is set. + */ + delayedRightCall: function(evt) { + this.rightclickTimerId = null; + if (evt) { + this.callback('rightclick', [evt]); + } + return !this.stopSingle; + }, /** * Method: dblclick diff --git a/tests/Handler/Click.html b/tests/Handler/Click.html index 65197dff1f..44d30cae2d 100644 --- a/tests/Handler/Click.html +++ b/tests/Handler/Click.html @@ -43,7 +43,7 @@ } function test_Handler_Click_events(t) { - t.plan(35); + t.plan(50); var map = new OpenLayers.Map('map'); var control = { @@ -72,8 +72,8 @@ // list below events that should be handled (events) and those // that should not be handled (nonevents) by the handler - var events = ["click", "dblclick", "mousedown"]; - var nonevents = ["mousemove", "mouseup", "resize", "focus", "blur"]; + var events = ["click", "dblclick", "mousedown", "mouseup", "rightclick"]; + var nonevents = ["mousemove", "resize", "focus", "blur"]; var handler = new OpenLayers.Handler.Click(control); // set browser event like properties on the handler for(var i=0; i