Skip to content

Commit

Permalink
fix: Double click and multi-key bindings (#571)
Browse files Browse the repository at this point in the history
* fix: Double click handling, and related issues

* PR comments
  • Loading branch information
wayfarer3130 authored Apr 24, 2023
1 parent 21a8ad7 commit ebc0cf8
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 22 deletions.
95 changes: 80 additions & 15 deletions packages/tools/examples/modifierKeys/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const {
LengthTool,
RectangleROITool,
BidirectionalTool,
ZoomTool,
PanTool,
StackScrollTool,
ToolGroupManager,
Enums: csToolsEnums,
} = cornerstoneTools;
Expand Down Expand Up @@ -45,10 +48,14 @@ content.appendChild(element);

const instructions = document.createElement('p');
instructions.innerText = `
- Left click to use the Window/Level tool.
- Shift + Left click to use the Length tool.
- Ctrl + Left click to use the Bidirectional tool.
- Alt/Option + Left click to use the RectangleROI tool.
- Single touch is equivalent to left click.
- Left or Meta+Left for stack scroll.
- Right or Option to use the Window/Level tool.
- Center or Ctrl to Pan.
- Shift to Zoom.
- Shift/Ctrl click to use the Length tool.
- Ctrl/Alt click to use the Bidirectional tool.
- Shift/Alt + Left click to use the RectangleROI tool.
`;

content.append(instructions);
Expand All @@ -68,6 +75,9 @@ async function run() {
cornerstoneTools.addTool(LengthTool);
cornerstoneTools.addTool(RectangleROITool);
cornerstoneTools.addTool(BidirectionalTool);
cornerstoneTools.addTool(StackScrollTool);
cornerstoneTools.addTool(PanTool);
cornerstoneTools.addTool(ZoomTool);

// Define a tool group, which defines how mouse events map to tool commands for
// Any viewport using the group
Expand All @@ -78,39 +88,97 @@ async function run() {
toolGroup.addTool(LengthTool.toolName);
toolGroup.addTool(RectangleROITool.toolName);
toolGroup.addTool(BidirectionalTool.toolName);

// TODO Why doesn't this work?
toolGroup.addTool(StackScrollTool.toolName);
toolGroup.addTool(PanTool.toolName);
toolGroup.addTool(ZoomTool.toolName);

// Set the initial state of the tools, here we set one tool active on left click.
// This means left click will draw that tool.
toolGroup.setToolActive(StackScrollTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Left Click
},
{
mouseButton: MouseBindings.Primary, // Left Click
modifierKey: KeyboardBindings.Meta,
},
{
numTouchPoints: 1,
modifierKey: KeyboardBindings.Meta,
},
],
});
toolGroup.setToolActive(WindowLevelTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Secondary, // Right Click
},
{
mouseButton: MouseBindings.Primary, // Left Click
modifierKey: KeyboardBindings.Alt,
},
{
numTouchPoints: 1,
modifierKey: KeyboardBindings.Alt,
},
],
});
toolGroup.setToolActive(PanTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary_And_Secondary,
},
{
mouseButton: MouseBindings.Auxiliary, // Right Click
},
{
mouseButton: MouseBindings.Primary, // Left Click
modifierKey: KeyboardBindings.Ctrl,
},
{
numTouchPoints: 1,
modifierKey: KeyboardBindings.Ctrl,
},
],
});
toolGroup.setToolActive(ZoomTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Left Click
modifierKey: KeyboardBindings.Shift,
},
{
numTouchPoints: 1,
modifierKey: KeyboardBindings.Shift,
},
],
});
toolGroup.setToolActive(LengthTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Shift + Left Click
modifierKey: KeyboardBindings.Shift,
modifierKey: KeyboardBindings.ShiftCtrl,
},
{
numTouchPoints: 1,
modifierKey: KeyboardBindings.ShiftCtrl,
},
],
});
toolGroup.setToolActive(RectangleROITool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Ctrl + Left Click
modifierKey: KeyboardBindings.Ctrl,
mouseButton: MouseBindings.Primary, // Shift/Alt + Left Click
modifierKey: KeyboardBindings.ShiftAlt,
},
],
});
toolGroup.setToolActive(BidirectionalTool.toolName, {
bindings: [
{
mouseButton: MouseBindings.Primary, // Alt/Meta + Left Click
modifierKey: KeyboardBindings.Alt,
mouseButton: MouseBindings.Primary, // Ctrl/Alt + Left Click
modifierKey: KeyboardBindings.CtrlAlt,
},
],
});
Expand Down Expand Up @@ -149,11 +217,8 @@ async function run() {
renderingEngine.getViewport(viewportId)
);

// Define a stack containing a single image
const stack = [imageIds[0]];

// Set the stack on the viewport
viewport.setStack(stack);
viewport.setStack(imageIds);

// Render the image
viewport.render();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ export default function getActiveToolForMouseEvent(
const { renderingEngineId, viewportId } = evt.detail;
const mouseEvent = evt.detail.event;

// If any keyboard modifier key is also pressed
// Use the actual key if set, otherwise get the key from the mouse event.
// If any keyboard modifier key is also pressed - get the mouse version
// first since it handles combinations, while the key event handles non-modifier
// keys.
const modifierKey =
keyEventListener.getModifierKey() || getMouseModifier(mouseEvent);
getMouseModifier(mouseEvent) || keyEventListener.getModifierKey();

const toolGroup = ToolGroupManager.getToolGroupForViewport(
viewportId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ToolGroupManager } from '../../store';
import { MouseBindings, ToolModes } from '../../enums';
import { EventTypes } from '../../types';
import getMouseModifier from './getMouseModifier';
import { keyEventListener } from '../../eventListeners';

const { Active } = ToolModes;

Expand Down Expand Up @@ -35,7 +36,8 @@ export default function getActiveToolForTouchEvent(
const numTouchPoints = Object.keys(touchEvent.touches).length;

// If any keyboard modifier key is also pressed
const modifierKey = getMouseModifier(touchEvent);
const modifierKey =
getMouseModifier(touchEvent) || keyEventListener.getModifierKey();

for (let j = 0; j < toolGroupToolNames.length; j++) {
const toolName = toolGroupToolNames[j];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const getMouseModifierKey = (evt) => {
return (evt.metaKey && kb.AltMeta) || kb.Alt;
}
if (evt.metaKey) {
kb.Meta;
return kb.Meta;
}
return undefined;
};
Expand Down
4 changes: 2 additions & 2 deletions packages/tools/src/eventListeners/mouse/mouseDownListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function mouseDownListener(evt: MouseEvent) {
// on anything except left double click.
doubleClickState.doubleClickTimeout = setTimeout(
_doStateMouseDownAndUp,
evt.button === 1 ? DOUBLE_CLICK_TOLERANCE_MS : 0
evt.buttons === 1 ? DOUBLE_CLICK_TOLERANCE_MS : 0
);

// First mouse down of a potential double click. So save it and start
Expand All @@ -144,7 +144,7 @@ function mouseDownListener(evt: MouseEvent) {

state.element = <HTMLDivElement>evt.currentTarget;

state.mouseButton = evt.button;
state.mouseButton = evt.buttons;

const enabledElement = getEnabledElement(state.element);
const { renderingEngineId, viewportId } = enabledElement;
Expand Down

0 comments on commit ebc0cf8

Please sign in to comment.