diff --git a/changelog.txt b/changelog.txt
index 9da3552e..94780504 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -48,6 +48,8 @@ OPENSEADRAGON CHANGELOG
* Added a GestureSettings class for per-device gesture options. Currently has settings to enable/disable zoom-on-scroll, zoom-on-pinch, zoom-on-click, and flick gesture settings.
* Added GestureSettings objects for mouse, touch, and pen devices to the Viewer options giving users the ability to customize gesture handling in the viewer
* Added velocity (speed and direction) properties to the "canvas-drag" event
+* Added double-click gesture detection to MouseTracker with corresponding dblClickHandler event callback (#392)
+* Added zoom on double-click feature to Viewer, with corresponding dblClickToZoom option added to the GestureSettings class (#392)
* Made it possible to run OpenSeadragon from local filesystem on some browsers (#379)
1.0.0:
diff --git a/src/mousetracker.js b/src/mousetracker.js
index ddca3dfb..957d9124 100644
--- a/src/mousetracker.js
+++ b/src/mousetracker.js
@@ -40,10 +40,8 @@
/**
* @class MouseTracker
- * @classdesc Provides simplified handling of common pointer device (mouse, touch, pen, etc.) and keyboard
- * events on a specific element, like 'enter', 'exit', 'press', 'release',
- * 'scroll', 'click', and 'drag'.
- *
+ * @classdesc Provides simplified handling of common pointer device (mouse, touch, pen, etc.) gestures
+ * and keyboard events on a specified element.
* @memberof OpenSeadragon
* @param {Object} options
* Allows configurable properties to be entirely specified by passing
@@ -54,11 +52,17 @@
* A reference to an element or an element id for which the pointer/key
* events will be monitored.
* @param {Number} options.clickTimeThreshold
- * The number of milliseconds within which multiple pointer clicks
- * will be treated as a single event.
+ * The number of milliseconds within which a pointer down-up event combination
+ * will be treated as a click gesture.
* @param {Number} options.clickDistThreshold
- * The distance between pointer click within multiple pointer clicks
- * will be treated as a single event.
+ * The maximum distance allowed between a pointer down event and a pointer up event
+ * to be treated as a click gesture.
+ * @param {Number} options.dblClickTimeThreshold
+ * The number of milliseconds within which two pointer down-up event combinations
+ * will be treated as a double-click gesture.
+ * @param {Number} options.dblClickDistThreshold
+ * The maximum distance allowed between two pointer click events
+ * to be treated as a click gesture.
* @param {Number} [options.stopDelay=50]
* The number of milliseconds without pointer move before the stop
* event is fired.
@@ -76,6 +80,8 @@
* An optional handler for mouse wheel scroll.
* @param {OpenSeadragon.EventHandler} [options.clickHandler=null]
* An optional handler for pointer click.
+ * @param {OpenSeadragon.EventHandler} [options.dblClickHandler=null]
+ * An optional handler for pointer double-click.
* @param {OpenSeadragon.EventHandler} [options.dragHandler=null]
* An optional handler for the drag gesture.
* @param {OpenSeadragon.EventHandler} [options.dragEndHandler=null]
@@ -111,34 +117,51 @@
*/
this.element = $.getElement( options.element );
/**
- * The number of milliseconds within which mutliple pointer clicks will be treated as a single event.
+ * The number of milliseconds within which a pointer down-up event combination
+ * will be treated as a click gesture.
* @member {Number} clickTimeThreshold
* @memberof OpenSeadragon.MouseTracker#
*/
this.clickTimeThreshold = options.clickTimeThreshold;
/**
- * The distance between pointer click within multiple pointer clicks will be treated as a single event.
+ * The maximum distance allowed between a pointer down event and a pointer up event
+ * to be treated as a click gesture.
* @member {Number} clickDistThreshold
* @memberof OpenSeadragon.MouseTracker#
*/
this.clickDistThreshold = options.clickDistThreshold;
- this.userData = options.userData || null;
- this.stopDelay = options.stopDelay || 50;
+ /**
+ * The number of milliseconds within which two pointer down-up event combinations
+ * will be treated as a double-click gesture.
+ * @member {Number} dblClickTimeThreshold
+ * @memberof OpenSeadragon.MouseTracker#
+ */
+ this.dblClickTimeThreshold = options.dblClickTimeThreshold;
+ /**
+ * The maximum distance allowed between two pointer click events
+ * to be treated as a click gesture.
+ * @member {Number} clickDistThreshold
+ * @memberof OpenSeadragon.MouseTracker#
+ */
+ this.dblClickDistThreshold = options.dblClickDistThreshold;
+ this.userData = options.userData || null;
+ this.stopDelay = options.stopDelay || 50;
- this.enterHandler = options.enterHandler || null;
- this.exitHandler = options.exitHandler || null;
- this.pressHandler = options.pressHandler || null;
- this.releaseHandler = options.releaseHandler || null;
- this.moveHandler = options.moveHandler || null;
- this.scrollHandler = options.scrollHandler || null;
- this.clickHandler = options.clickHandler || null;
- this.dragHandler = options.dragHandler || null;
- this.dragEndHandler = options.dragEndHandler || null;
- this.pinchHandler = options.pinchHandler || null;
- this.stopHandler = options.stopHandler || null;
- this.keyHandler = options.keyHandler || null;
- this.focusHandler = options.focusHandler || null;
- this.blurHandler = options.blurHandler || null;
+ this.enterHandler = options.enterHandler || null;
+ this.exitHandler = options.exitHandler || null;
+ this.pressHandler = options.pressHandler || null;
+ this.releaseHandler = options.releaseHandler || null;
+ this.moveHandler = options.moveHandler || null;
+ this.scrollHandler = options.scrollHandler || null;
+ this.clickHandler = options.clickHandler || null;
+ this.dblClickHandler = options.dblClickHandler || null;
+ this.dragHandler = options.dragHandler || null;
+ this.dragEndHandler = options.dragEndHandler || null;
+ this.pinchHandler = options.pinchHandler || null;
+ this.stopHandler = options.stopHandler || null;
+ this.keyHandler = options.keyHandler || null;
+ this.focusHandler = options.focusHandler || null;
+ this.blurHandler = options.blurHandler || null;
//Store private properties in a scope sealed hash map
var _this = this;
@@ -154,6 +177,7 @@
setCaptureCapable: !!this.element.setCapture && !!this.element.releaseCapture,
click: function ( event ) { onClick( _this, event ); },
+ dblclick: function ( event ) { onDblClick( _this, event ); },
keypress: function ( event ) { onKeyPress( _this, event ); },
focus: function ( event ) { onFocus( _this, event ); },
blur: function ( event ) { onBlur( _this, event ); },
@@ -207,6 +231,10 @@
// Legacy mouse event tracking
capturing: false,
+ // Tracking for double-click gesture
+ lastClickPos: null,
+ dblClickTimeOut: null,
+
// Tracking for pinch gesture
pinchGPoints: [],
lastPinchDist: 0,
@@ -456,7 +484,7 @@
* @param {OpenSeadragon.Point} event.position
* The position of the event relative to the tracked element.
* @param {Boolean} event.quick
- * True only if the clickDistThreshold and clickDeltaThreshold are both passed. Useful for ignoring events.
+ * True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for ignoring drag events.
* @param {Boolean} event.shift
* True if the shift key was pressed during this event.
* @param {Boolean} event.isTouchEvent
@@ -470,6 +498,30 @@
*/
clickHandler: function () { },
+ /**
+ * Implement or assign implementation to these handlers during or after
+ * calling the constructor.
+ * @function
+ * @param {Object} event
+ * @param {OpenSeadragon.MouseTracker} event.eventSource
+ * A reference to the tracker instance.
+ * @param {String} event.pointerType
+ * "mouse", "touch", "pen", etc.
+ * @param {OpenSeadragon.Point} event.position
+ * The position of the event relative to the tracked element.
+ * @param {Boolean} event.shift
+ * True if the shift key was pressed during this event.
+ * @param {Boolean} event.isTouchEvent
+ * True if the original event is a touch event, otherwise false. Deprecated. Use pointerType and/or originalEvent instead.
+ * @param {Object} event.originalEvent
+ * The original event object.
+ * @param {Boolean} event.preventDefaultAction
+ * Set to true to prevent the tracker subscriber from performing its default action (subscriber implementation dependent). Default: false.
+ * @param {Object} event.userData
+ * Arbitrary user-defined object.
+ */
+ dblClickHandler: function () { },
+
/**
* Implement or assign implementation to these handlers during or after
* calling the constructor.
@@ -746,7 +798,7 @@
/**
* Detect browser pointer device event model(s) and build appropriate list of events to subscribe to.
*/
- $.MouseTracker.subscribeEvents = [ "click", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
+ $.MouseTracker.subscribeEvents = [ "click", "dblclick", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {
// Older Firefox
@@ -877,6 +929,12 @@
* @memberof OpenSeadragon.MouseTracker.GesturePointList#
*/
this.contacts = 0;
+ /**
+ * Current number of clicks for the device. Used for multiple click gesture tracking.
+ * @member {Number} clicks
+ * @memberof OpenSeadragon.MouseTracker.GesturePointList#
+ */
+ this.clicks = 0;
};
$.MouseTracker.GesturePointList.prototype = /** @lends OpenSeadragon.MouseTracker.GesturePointList.prototype */{
/**
@@ -1164,6 +1222,17 @@
}
+ /**
+ * @private
+ * @inner
+ */
+ function onDblClick( tracker, event ) {
+ if ( tracker.dblClickHandler ) {
+ $.cancelEvent( event );
+ }
+ }
+
+
/**
* @private
* @inner
@@ -1453,7 +1522,7 @@
captureMouse( tracker );
}
- if ( tracker.clickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) {
+ if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) {
$.cancelEvent( event );
}
}
@@ -1795,7 +1864,7 @@
$.stopEvent( event );
}
- if ( tracker.clickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
+ if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
$.cancelEvent( event );
}
}
@@ -2210,7 +2279,8 @@
curGPoint,
updateGPoint,
releaseCapture = false,
- wasCaptured = false;
+ wasCaptured = false,
+ quick;
if ( typeof event.buttons !== 'undefined' ) {
pointsList.buttons = event.buttons;
@@ -2317,28 +2387,63 @@
}
}
- // Click
- if ( tracker.clickHandler && updateGPoint.insideElementPressed && updateGPoint.insideElement ) {
- var time = releaseTime - updateGPoint.contactTime,
- distance = updateGPoint.contactPos.distanceTo( releasePoint ),
- quick = time <= tracker.clickTimeThreshold &&
- distance <= tracker.clickDistThreshold;
+ // Click / Double-Click
+ if ( ( tracker.clickHandler || tracker.dblClickHandler ) && updateGPoint.insideElement ) {
+ quick = releaseTime - updateGPoint.contactTime <= tracker.clickTimeThreshold &&
+ updateGPoint.contactPos.distanceTo( releasePoint ) <= tracker.clickDistThreshold;
- propagate = tracker.clickHandler(
- {
- eventSource: tracker,
- pointerType: updateGPoint.type,
- position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),
- quick: quick,
- shift: event.shiftKey,
- isTouchEvent: updateGPoint.type === 'touch',
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
+ // Click
+ if ( tracker.clickHandler ) {
+ propagate = tracker.clickHandler(
+ {
+ eventSource: tracker,
+ pointerType: updateGPoint.type,
+ position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),
+ quick: quick,
+ shift: event.shiftKey,
+ isTouchEvent: updateGPoint.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+
+ // Double-Click
+ if ( tracker.dblClickHandler && quick ) {
+ pointsList.clicks++;
+ if ( pointsList.clicks === 1 ) {
+ delegate.lastClickPos = releasePoint;
+ /*jshint loopfunc:true*/
+ delegate.dblClickTimeOut = setTimeout( function() {
+ pointsList.clicks = 0;
+ }, tracker.dblClickTimeThreshold );
+ /*jshint loopfunc:false*/
+ } else if ( pointsList.clicks === 2 ) {
+ clearTimeout( delegate.dblClickTimeOut );
+ pointsList.clicks = 0;
+ if ( delegate.lastClickPos.distanceTo( releasePoint ) <= tracker.dblClickDistThreshold ) {
+ propagate = tracker.dblClickHandler(
+ {
+ eventSource: tracker,
+ pointerType: updateGPoint.type,
+ position: getPointRelativeToAbsolute( updateGPoint.currentPos, tracker.element ),
+ shift: event.shiftKey,
+ isTouchEvent: updateGPoint.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+ delegate.lastClickPos = null;
}
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
}
}
} else if ( pointsList.contacts === 2 ) {
diff --git a/src/openseadragon.js b/src/openseadragon.js
index 15932cfb..14ddd3d5 100644
--- a/src/openseadragon.js
+++ b/src/openseadragon.js
@@ -267,12 +267,20 @@
* image requests in parallel as allowed by the browsers policy.
*
* @property {Number} [clickTimeThreshold=300]
- * If multiple mouse clicks occurs within less than this number of
- * milliseconds, treat them as a single click.
+ * The number of milliseconds within which a pointer down-up event combination
+ * will be treated as a click gesture.
*
* @property {Number} [clickDistThreshold=5]
- * If a mouse or touch drag occurs and the distance to the starting drag
- * point is less than this many pixels, ignore the drag event.
+ * The maximum distance allowed between a pointer down event and a pointer up event
+ * to be treated as a click gesture.
+ *
+ * @property {Number} [dblClickTimeThreshold=300]
+ * The number of milliseconds within which two pointer down-up event combinations
+ * will be treated as a double-click gesture.
+ *
+ * @property {Number} [dblClickDistThreshold=20]
+ * The maximum distance allowed between two pointer click events
+ * to be treated as a double-click gesture.
*
* @property {Number} [springStiffness=6.5]
*
@@ -284,6 +292,8 @@
* Settings for gestures generated by a mouse pointer device. (See {@link OpenSeadragon.GestureSettings})
* @property {Boolean} [gestureSettingsMouse.scrollToZoom=true] - Zoom on scroll gesture
* @property {Boolean} [gestureSettingsMouse.clickToZoom=true] - Zoom on click gesture
+ * @property {Boolean} [gestureSettingsMouse.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to true
+ * then clickToZoom should be set to false to prevent multiple zooms.
* @property {Boolean} [gestureSettingsMouse.pinchToZoom=false] - Zoom on pinch gesture
* @property {Boolean} [gestureSettingsMouse.flickEnabled=false] - Enable flick gesture
* @property {Number} [gestureSettingsMouse.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
@@ -293,6 +303,8 @@
* Settings for gestures generated by a touch pointer device. (See {@link OpenSeadragon.GestureSettings})
* @property {Boolean} [gestureSettingsTouch.scrollToZoom=false] - Zoom on scroll gesture
* @property {Boolean} [gestureSettingsTouch.clickToZoom=false] - Zoom on click gesture
+ * @property {Boolean} [gestureSettingsTouch.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
+ * then clickToZoom should be set to false to prevent multiple zooms.
* @property {Boolean} [gestureSettingsTouch.pinchToZoom=true] - Zoom on pinch gesture
* @property {Boolean} [gestureSettingsTouch.flickEnabled=true] - Enable flick gesture
* @property {Number} [gestureSettingsTouch.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
@@ -302,6 +314,8 @@
* Settings for gestures generated by a pen pointer device. (See {@link OpenSeadragon.GestureSettings})
* @property {Boolean} [gestureSettingsPen.scrollToZoom=false] - Zoom on scroll gesture
* @property {Boolean} [gestureSettingsPen.clickToZoom=true] - Zoom on click gesture
+ * @property {Boolean} [gestureSettingsPen.dblClickToZoom=false] - Zoom on double-click gesture. Note: If set to true
+ * then clickToZoom should be set to false to prevent multiple zooms.
* @property {Boolean} [gestureSettingsPen.pinchToZoom=false] - Zoom on pinch gesture
* @property {Boolean} [gestureSettingsPen.flickEnabled=false] - Enable flick gesture
* @property {Number} [gestureSettingsPen.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
@@ -311,13 +325,15 @@
* Settings for gestures generated by unknown pointer devices. (See {@link OpenSeadragon.GestureSettings})
* @property {Boolean} [gestureSettingsUnknown.scrollToZoom=true] - Zoom on scroll gesture
* @property {Boolean} [gestureSettingsUnknown.clickToZoom=false] - Zoom on click gesture
+ * @property {Boolean} [gestureSettingsUnknown.dblClickToZoom=true] - Zoom on double-click gesture. Note: If set to true
+ * then clickToZoom should be set to false to prevent multiple zooms.
* @property {Boolean} [gestureSettingsUnknown.pinchToZoom=true] - Zoom on pinch gesture
* @property {Boolean} [gestureSettingsUnknown.flickEnabled=true] - Enable flick gesture
* @property {Number} [gestureSettingsUnknown.flickMinSpeed=120] - If flickEnabled is true, the minimum speed to initiate a flick gesture (pixels-per-second)
* @property {Number} [gestureSettingsUnknown.flickMomentum=0.25] - If flickEnabled is true, the momentum factor for the flick gesture
*
* @property {Number} [zoomPerClick=2.0]
- * The "zoom distance" per mouse click or touch tap. Note: Setting this to 1.0 effectively disables the click-to-zoom feature (also see gestureSettings[Mouse|Touch|Pen].clickToZoom).
+ * The "zoom distance" per mouse click or touch tap. Note: Setting this to 1.0 effectively disables the click-to-zoom feature (also see gestureSettings[Mouse|Touch|Pen].clickToZoom/dblClickToZoom).
*
* @property {Number} [zoomPerScroll=1.2]
* The "zoom distance" per mouse scroll or touch pinch. Note: Setting this to 1.0 effectively disables the mouse-wheel zoom feature (also see gestureSettings[Mouse|Touch|Pen].scrollToZoom}).
@@ -534,6 +550,10 @@
* @property {Boolean} clickToZoom
* Set to false to disable zooming on click gestures.
*
+ * @property {Boolean} dblClickToZoom
+ * Set to false to disable zooming on double-click gestures. Note: If set to true
+ * then clickToZoom should be set to false to prevent multiple zooms.
+ *
* @property {Boolean} pinchToZoom
* Set to false to disable zooming on pinch gestures.
*
@@ -891,12 +911,14 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
//UI RESPONSIVENESS AND FEEL
clickTimeThreshold: 300,
clickDistThreshold: 5,
+ dblClickTimeThreshold: 300,
+ dblClickDistThreshold: 20,
springStiffness: 6.5,
animationTime: 1.2,
- gestureSettingsMouse: { scrollToZoom: true, clickToZoom: true, pinchToZoom: false, flickEnabled: false, flickMinSpeed: 120, flickMomentum: 0.25 },
- gestureSettingsTouch: { scrollToZoom: false, clickToZoom: false, pinchToZoom: true, flickEnabled: true, flickMinSpeed: 120, flickMomentum: 0.25 },
- gestureSettingsPen: { scrollToZoom: false, clickToZoom: true, pinchToZoom: false, flickEnabled: false, flickMinSpeed: 120, flickMomentum: 0.25 },
- gestureSettingsUnknown: { scrollToZoom: false, clickToZoom: false, pinchToZoom: true, flickEnabled: true, flickMinSpeed: 120, flickMomentum: 0.25 },
+ gestureSettingsMouse: { scrollToZoom: true, clickToZoom: true, dblClickToZoom: false, pinchToZoom: false, flickEnabled: false, flickMinSpeed: 120, flickMomentum: 0.25 },
+ gestureSettingsTouch: { scrollToZoom: false, clickToZoom: false, dblClickToZoom: true, pinchToZoom: true, flickEnabled: true, flickMinSpeed: 120, flickMomentum: 0.25 },
+ gestureSettingsPen: { scrollToZoom: false, clickToZoom: true, dblClickToZoom: false, pinchToZoom: false, flickEnabled: false, flickMinSpeed: 120, flickMomentum: 0.25 },
+ gestureSettingsUnknown: { scrollToZoom: false, clickToZoom: false, dblClickToZoom: true, pinchToZoom: true, flickEnabled: true, flickMinSpeed: 120, flickMomentum: 0.25 },
zoomPerClick: 2,
zoomPerScroll: 1.2,
zoomPerSecond: 1.0,
diff --git a/src/viewer.js b/src/viewer.js
index 6bd8dad3..8d6ec37a 100644
--- a/src/viewer.js
+++ b/src/viewer.js
@@ -385,25 +385,30 @@ $.Viewer = function( options ) {
this.innerTracker = new $.MouseTracker({
- element: this.canvas,
- clickTimeThreshold: this.clickTimeThreshold,
- clickDistThreshold: this.clickDistThreshold,
- clickHandler: $.delegate( this, onCanvasClick ),
- dragHandler: $.delegate( this, onCanvasDrag ),
- dragEndHandler: $.delegate( this, onCanvasDragEnd ),
- releaseHandler: $.delegate( this, onCanvasRelease ),
- scrollHandler: $.delegate( this, onCanvasScroll ),
- pinchHandler: $.delegate( this, onCanvasPinch )
+ element: this.canvas,
+ clickTimeThreshold: this.clickTimeThreshold,
+ clickDistThreshold: this.clickDistThreshold,
+ dblClickTimeThreshold: this.dblClickTimeThreshold,
+ dblClickDistThreshold: this.dblClickDistThreshold,
+ clickHandler: $.delegate( this, onCanvasClick ),
+ dblClickHandler: $.delegate( this, onCanvasDblClick ),
+ dragHandler: $.delegate( this, onCanvasDrag ),
+ dragEndHandler: $.delegate( this, onCanvasDragEnd ),
+ releaseHandler: $.delegate( this, onCanvasRelease ),
+ scrollHandler: $.delegate( this, onCanvasScroll ),
+ pinchHandler: $.delegate( this, onCanvasPinch )
}).setTracking( this.mouseNavEnabled ? true : false ); // default state
this.outerTracker = new $.MouseTracker({
- element: this.container,
- clickTimeThreshold: this.clickTimeThreshold,
- clickDistThreshold: this.clickDistThreshold,
- enterHandler: $.delegate( this, onContainerEnter ),
- exitHandler: $.delegate( this, onContainerExit ),
- pressHandler: $.delegate( this, onContainerPress ),
- releaseHandler: $.delegate( this, onContainerRelease )
+ element: this.container,
+ clickTimeThreshold: this.clickTimeThreshold,
+ clickDistThreshold: this.clickDistThreshold,
+ dblClickTimeThreshold: this.dblClickTimeThreshold,
+ dblClickDistThreshold: this.dblClickDistThreshold,
+ enterHandler: $.delegate( this, onContainerEnter ),
+ exitHandler: $.delegate( this, onContainerExit ),
+ pressHandler: $.delegate( this, onContainerPress ),
+ releaseHandler: $.delegate( this, onContainerRelease )
}).setTracking( this.mouseNavEnabled ? true : false ); // always tracking
if( this.toolbar ){
@@ -2254,7 +2259,7 @@ function onCanvasClick( event ) {
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
* @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
* @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.
- * @property {Boolean} quick - True only if the clickDistThreshold and clickDeltaThreshold are both passed. Useful for differentiating between clicks and drags.
+ * @property {Boolean} quick - True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for differentiating between clicks and drags.
* @property {Boolean} shift - True if the shift key was pressed during this event.
* @property {Object} originalEvent - The original DOM event.
* @property {?Object} userData - Arbitrary subscriber-defined object.
@@ -2268,6 +2273,40 @@ function onCanvasClick( event ) {
});
}
+function onCanvasDblClick( event ) {
+ var gestureSettings;
+
+ if ( !event.preventDefaultAction && this.viewport ) {
+ gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );
+ if ( gestureSettings.dblClickToZoom ) {
+ this.viewport.zoomBy(
+ event.shift ? 1.0 / this.zoomPerClick : this.zoomPerClick,
+ this.viewport.pointFromPixel( event.position, true )
+ );
+ this.viewport.applyConstraints();
+ }
+ }
+ /**
+ * Raised when a double mouse press/release or touch/remove occurs on the {@link OpenSeadragon.Viewer#canvas} element.
+ *
+ * @event canvas-double-click
+ * @memberof OpenSeadragon.Viewer
+ * @type {object}
+ * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
+ * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
+ * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.
+ * @property {Boolean} shift - True if the shift key was pressed during this event.
+ * @property {Object} originalEvent - The original DOM event.
+ * @property {?Object} userData - Arbitrary subscriber-defined object.
+ */
+ this.raiseEvent( 'canvas-double-click', {
+ tracker: event.eventSource,
+ position: event.position,
+ shift: event.shift,
+ originalEvent: event.originalEvent
+ });
+}
+
function onCanvasDrag( event ) {
var gestureSettings;
diff --git a/test/events.js b/test/events.js
index 61137046..36a49b17 100644
--- a/test/events.js
+++ b/test/events.js
@@ -37,6 +37,7 @@
origReleaseHandler,
origMoveHandler,
origClickHandler,
+ origDblClickHandler,
origDragHandler,
origDragEndHandler,
enterCount,
@@ -45,6 +46,7 @@
releaseCount,
moveCount,
clickCount,
+ dblClickCount,
dragCount,
dragEndCount,
insideElementPressed,
@@ -111,6 +113,15 @@
return true;
}
};
+ origDblClickHandler = tracker.dblClickHandler;
+ tracker.dblClickHandler = function ( event ) {
+ dblClickCount++;
+ if (origDblClickHandler) {
+ return origDblClickHandler( event );
+ } else {
+ return true;
+ }
+ };
origDragHandler = tracker.dragHandler;
tracker.dragHandler = function ( event ) {
dragCount++;
@@ -140,6 +151,7 @@
tracker.releaseHandler = origReleaseHandler;
tracker.moveHandler = origMoveHandler;
tracker.clickHandler = origClickHandler;
+ tracker.dblClickHandler = origDblClickHandler;
tracker.dragHandler = origDragHandler;
tracker.dragEndHandler = origDragEndHandler;
};
@@ -188,6 +200,7 @@
releaseCount = 0;
moveCount = 0;
clickCount = 0;
+ dblClickCount = 0;
dragCount = 0;
dragEndCount = 0;
insideElementPressed = false;
@@ -217,6 +230,9 @@
if ('clickCount' in expected) {
equal( clickCount, expected.clickCount, expected.description + 'clickHandler event count matches expected (' + expected.clickCount + ')' );
}
+ if ('dblClickCount' in expected) {
+ equal( dblClickCount, expected.dblClickCount, expected.description + 'dblClickHandler event count matches expected (' + expected.dblClickCount + ')' );
+ }
if ('dragCount' in expected) {
equal( dragCount, expected.dragCount, expected.description + 'dragHandler event count matches expected (' + expected.dragCount + ')' );
}
@@ -269,6 +285,7 @@
releaseCount: 1,
moveCount: 20,
clickCount: 0,
+ dblClickCount: 0,
dragCount: 0,
dragEndCount: 0,
insideElementPressed: false,
@@ -293,6 +310,7 @@
releaseCount: 0,
moveCount: 20,
clickCount: 0,
+ dblClickCount: 0,
dragCount: 0,
dragEndCount: 0,
//insideElementPressed: false,
@@ -315,6 +333,7 @@
releaseCount: 0,
moveCount: 20,
clickCount: 0,
+ dblClickCount: 0,
dragCount: 0,
dragEndCount: 0,
//insideElementPressed: false,
@@ -324,7 +343,33 @@
//quickClick: false
});
- // enter-press-release-exit
+ // enter-press-release-press-release-exit (double click)
+ resetForAssessment();
+ simulateEnter(0, 0);
+ simulateDown(0, 0);
+ simulateUp(0, 0);
+ simulateDown(0, 0);
+ simulateUp(0, 0);
+ simulateLeave(-1, -1);
+ assessGestureExpectations({
+ description: 'enter-press-release-press-release-exit (double click): ',
+ enterCount: 1,
+ exitCount: 1,
+ pressCount: 2,
+ releaseCount: 2,
+ moveCount: 0,
+ clickCount: 2,
+ dblClickCount: 1,
+ dragCount: 0,
+ dragEndCount: 0,
+ insideElementPressed: true,
+ insideElementReleased: true,
+ contacts: 0,
+ trackedPointers: 0
+ //quickClick: true
+ });
+
+ // enter-press-release-exit (click)
resetForAssessment();
simulateEnter(0, 0);
simulateDown(0, 0);
@@ -338,6 +383,7 @@
releaseCount: 1,
moveCount: 0,
clickCount: 1,
+ dblClickCount: 0,
dragCount: 0,
dragEndCount: 0,
insideElementPressed: true,
@@ -363,6 +409,7 @@
releaseCount: 1,
moveCount: 200,
clickCount: 1,
+ dblClickCount: 0,
dragCount: 100,
dragEndCount: 1,
insideElementPressed: true,
@@ -389,6 +436,7 @@
releaseCount: 1,
moveCount: 15,
clickCount: 0,
+ dblClickCount: 0,
dragCount: 15,
dragEndCount: 1,
insideElementPressed: true,
@@ -509,6 +557,8 @@
userData: userData,
clickTimeThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickTimeThreshold,
clickDistThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickDistThreshold,
+ dblClickTimeThreshold: OpenSeadragon.DEFAULT_SETTINGS.dblClickTimeThreshold,
+ dblClickDistThreshold: OpenSeadragon.DEFAULT_SETTINGS.dblClickDistThreshold,
focusHandler: onMouseTrackerFocus,
blurHandler: onMouseTrackerBlur,
enterHandler: onMouseTrackerEnter,
diff --git a/test/legacy.mouse.shim.js b/test/legacy.mouse.shim.js
index 9643d610..460a8dfe 100644
--- a/test/legacy.mouse.shim.js
+++ b/test/legacy.mouse.shim.js
@@ -4,7 +4,7 @@
* Plugin to force OpenSeadragon to use the legacy mouse pointer event model
*/
- $.MouseTracker.subscribeEvents = [ "click", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
+ $.MouseTracker.subscribeEvents = [ "click", "dblclick", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {
// Older Firefox