Skip to content

Commit

Permalink
Adding and removing the ignore double click listener in the tools init
Browse files Browse the repository at this point in the history
and destroy functions (respectively).
Double click drag tolerance is now a projected distance.
  • Loading branch information
jbocce committed Jan 26, 2023
1 parent fa2f2d7 commit 2af6f67
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
16 changes: 1 addition & 15 deletions packages/tools/src/eventListeners/mouse/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import mouseDoubleClickListener from './mouseDoubleClickListener';
import mouseDownListener, {
mouseDoubleClickIgnoreListener,
} from './mouseDownListener';
import mouseDownListener from './mouseDownListener';
import mouseMoveListener from './mouseMoveListener';

/**
Expand All @@ -14,14 +12,6 @@ import mouseMoveListener from './mouseMoveListener';
*/
function disable(element: HTMLDivElement): void {
element.removeEventListener('dblclick', mouseDoubleClickListener);

// A separate double click listener for the element. Separate because...
// - it listens on the capture phase (and not the typical bubble phase)
// - the data used to ignore the double click is private to mouseDoubleClickIgnoreListener
element.removeEventListener('dblclick', mouseDoubleClickIgnoreListener, {
capture: true, // capture phase is the best way to ignore double clicks
});

element.removeEventListener('mousedown', mouseDownListener);
element.removeEventListener('mousemove', mouseMoveListener);
}
Expand All @@ -39,10 +29,6 @@ function enable(element: HTMLDivElement): void {
disable(element);

element.addEventListener('dblclick', mouseDoubleClickListener);
element.addEventListener('dblclick', mouseDoubleClickIgnoreListener, {
capture: true,
});

element.addEventListener('mousedown', mouseDownListener);
element.addEventListener('mousemove', mouseMoveListener);
}
Expand Down
34 changes: 25 additions & 9 deletions packages/tools/src/eventListeners/mouse/mouseDownListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const { MOUSE_DOWN, MOUSE_DOWN_ACTIVATE, MOUSE_CLICK, MOUSE_UP, MOUSE_DRAG } =
//
const DOUBLE_CLICK_TOLERANCE_MS = 400;

// A drag (distance) during the double click timeout that is greater than this
// A drag (projected distance) during the double click timeout that is greater than this
// value will cancel the timeout and suppress any double click that might occur.
// This tolerance is particularly important on touch devices where some movement
// might occur between the two clicks.
Expand Down Expand Up @@ -368,17 +368,13 @@ function _onMouseMove(evt: MouseEvent) {
}

/**
* Determines if the given delta is past the double click, drag distance tolerance.
* This is a bit of an expensive calculation, so it is best to only be called within
* the double click timeout.
* Determines if the given delta is past the double click, (projected) drag distance
* tolerance.
* @param delta the delta
* @returns true iff the delta is past the tolerance
*/
function _isDragPastDoubleClickTolerance(delta: Types.Point2): boolean {
return (
Math.sqrt(Math.pow(delta[0], 2) + Math.pow(delta[1], 2)) >
DOUBLE_CLICK_DRAG_TOLERANCE
);
return Math.abs(delta[0]) + Math.abs(delta[1]) > DOUBLE_CLICK_DRAG_TOLERANCE;
}

function _preventClickHandler() {
Expand Down Expand Up @@ -506,13 +502,33 @@ export function getMouseButton(): number {
return state.mouseButton;
}

/**
* Adds a capture phase double click listener to the document that ignores double
* click events as determined by this module.
*/
export function addIgnoreDoubleClickCaptureListener() {
document.addEventListener('dblclick', _mouseDoubleClickIgnoreListener, {
capture: true,
});
}

/**
* Removes a capture phase double click listener from the document that ignores double
* click events as determined by this module.
*/
export function removeIgnoreDoubleClickCaptureListener() {
document.removeEventListener('dblclick', _mouseDoubleClickIgnoreListener, {
capture: true,
});
}

/**
* Handles a dblclick event to determine if it should be ignored based on the
* double click state's ignoreDoubleClick flag. stopImmediatePropagation and
* preventDefault are used to ingore the event.
* @param evt browser dblclick event
*/
export function mouseDoubleClickIgnoreListener(evt: MouseEvent) {
function _mouseDoubleClickIgnoreListener(evt: MouseEvent) {
if (doubleClickState.ignoreDoubleClick) {
doubleClickState.ignoreDoubleClick = false;

Expand Down
12 changes: 12 additions & 0 deletions packages/tools/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import {
} from './eventListeners';

import * as ToolGroupManager from './store/ToolGroupManager';
import {
addIgnoreDoubleClickCaptureListener,
removeIgnoreDoubleClickCaptureListener,
} from './eventListeners/mouse/mouseDownListener';

let csToolsInitialized = false;

Expand All @@ -31,6 +35,12 @@ export function init(defaultConfiguration = {}): void {
_addCornerstoneEventListeners();
_addCornerstoneToolsEventListeners();

// A separate double click listener at the document root. Separate
// from the {@link mouseDoubleClickListener} because...
// - it listens on the capture phase (and not the typical bubble phase)
// - the data used to ignore the double click is private to the mouseDownListener module
addIgnoreDoubleClickCaptureListener();

csToolsInitialized = true;
}

Expand All @@ -43,6 +53,8 @@ export function destroy(): void {
_removeCornerstoneEventListeners();
_removeCornerstoneToolsEventListeners();

removeIgnoreDoubleClickCaptureListener();

// Important: destroy ToolGroups first, in order for cleanup to work correctly for the
// added tools.
ToolGroupManager.destroy();
Expand Down

0 comments on commit 2af6f67

Please sign in to comment.