feat(DoubleClick): double click a viewport to one up and back (#3285)
* feat(DoubleClick): double click a viewport to one up and back Added a toggleOneUp command that puts the active viewport into a 1x1 grid layout and it toggles out of 'one-up' by restoring its saved 'toggleOneUpViewportGridStore' from the StateSyncService. Added double click customization for the Cornerstone extension with the default double click handling being the toggleOneUp command. Added a cypress test for the double click functionality. * PR feedback: - tracked viewport measurements no longer show as dashed when toggling one up - disallowed double clicking near a measurement - updated cornerstone3D dependencies to fix double click of TMTV and volume viewport 3D - created ViewportGridService.getLayoutOptionsFromState * Updated the ViewportGridService docs. * Switched to using 'cornerstoneViewportClickCommands' and consistency with the context menu clicks.
This commit is contained in:
1 parent
4734b3bac6
commit
d5ff590dfc
14 files changed
+402
-40
No files matched your search
@@ -25,6 +25,7 @@ import interleaveCenterLoader from './utils/interleaveCenterLoader';
|
||||
import nthLoader from './utils/nthLoader';
|
||||
import interleaveTopToBottom from './utils/interleaveTopToBottom';
|
||||
import initContextMenu from './initContextMenu';
|
||||
import initDoubleClick from './initDoubleClick';
|
||||
|
||||
// TODO: Cypress tests are currently grabbing this from the window?
|
||||
window.cornerstone = cornerstone;
|
||||
@@ -104,6 +105,12 @@ export default async function init({
|
||||
clearOnModeExit: true,
|
||||
});
|
||||
|
||||
// Stores the entire ViewportGridService getState when toggling to one up
|
||||
// (e.g. via a double click) so that it can be restored when toggling back.
|
||||
stateSyncService.register('toggleOneUpViewportGridStore', {
|
||||
clearOnModeExit: true,
|
||||
});
|
||||
|
||||
const labelmapRepresentation =
|
||||
cornerstoneTools.Enums.SegmentationRepresentations.Labelmap;
|
||||
|
||||
@@ -198,6 +205,11 @@ export default async function init({
|
||||
commandsManager,
|
||||
});
|
||||
|
||||
initDoubleClick({
|
||||
customizationService,
|
||||
commandsManager,
|
||||
});
|
||||
|
||||
const newStackCallback = evt => {
|
||||
const { element } = evt.detail;
|
||||
utilities.stackPrefetch.enable(element);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { eventTarget, EVENTS } from '@cornerstonejs/core';
|
||||
import { Enums } from '@cornerstonejs/tools';
|
||||
import { setEnabledElement } from './state';
|
||||
import { findNearbyToolData } from './utils/findNearbyToolData';
|
||||
|
||||
const cs3DToolsEvents = Enums.Events;
|
||||
|
||||
@@ -47,28 +48,6 @@ function initContextMenu({
|
||||
customizationService,
|
||||
commandsManager,
|
||||
}): void {
|
||||
/**
|
||||
* Finds tool nearby event position triggered.
|
||||
*
|
||||
* @param {Object} commandsManager mannager of commands
|
||||
* @param {Object} event that has being triggered
|
||||
* @returns cs toolData or undefined if not found.
|
||||
*/
|
||||
const findNearbyToolData = evt => {
|
||||
if (!evt?.detail) {
|
||||
return;
|
||||
}
|
||||
const { element, currentPoints } = evt.detail;
|
||||
return commandsManager.runCommand(
|
||||
'getNearbyToolData',
|
||||
{
|
||||
element,
|
||||
canvasCoordinates: currentPoints?.canvas,
|
||||
},
|
||||
'CORNERSTONE'
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
* Run the commands associated with the given button press,
|
||||
* defaults on button1 and button2
|
||||
@@ -80,7 +59,7 @@ function initContextMenu({
|
||||
const toRun = customizations[name];
|
||||
console.log('initContextMenu::cornerstoneViewportHandleEvent', name, toRun);
|
||||
const options = {
|
||||
nearbyToolData: findNearbyToolData(evt),
|
||||
nearbyToolData: findNearbyToolData(commandsManager, evt),
|
||||
event: evt,
|
||||
};
|
||||
commandsManager.run(toRun, options);
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { eventTarget, EVENTS } from '@cornerstonejs/core';
|
||||
import { Enums } from '@cornerstonejs/tools';
|
||||
import { CommandsManager, CustomizationService, Types } from '@ohif/core';
|
||||
import { findNearbyToolData } from './utils/findNearbyToolData';
|
||||
|
||||
const cs3DToolsEvents = Enums.Events;
|
||||
|
||||
const DEFAULT_DOUBLE_CLICK = {
|
||||
doubleClick: {
|
||||
commandName: 'toggleOneUp',
|
||||
commandOptions: {},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a double click event name, consisting of:
|
||||
* * alt when the alt key is down
|
||||
* * ctrl when the cctrl key is down
|
||||
* * shift when the shift key is down
|
||||
* * 'doubleClick'
|
||||
*/
|
||||
function getDoubleClickEventName(evt: CustomEvent) {
|
||||
const nameArr = [];
|
||||
if (evt.detail.event.altKey) nameArr.push('alt');
|
||||
if (evt.detail.event.ctrlKey) nameArr.push('ctrl');
|
||||
if (evt.detail.event.shiftKey) nameArr.push('shift');
|
||||
nameArr.push('doubleClick');
|
||||
return nameArr.join('');
|
||||
}
|
||||
|
||||
export type initDoubleClickArgs = {
|
||||
customizationService: CustomizationService;
|
||||
commandsManager: CommandsManager;
|
||||
};
|
||||
|
||||
function initDoubleClick({
|
||||
customizationService,
|
||||
commandsManager,
|
||||
}: initDoubleClickArgs): void {
|
||||
const cornerstoneViewportHandleDoubleClick = (evt: CustomEvent) => {
|
||||
// Do not allow double click on a tool.
|
||||
const nearbyToolData = findNearbyToolData(commandsManager, evt);
|
||||
if (nearbyToolData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventName = getDoubleClickEventName(evt);
|
||||
|
||||
// Allows for the customization of the double click on a viewport.
|
||||
const customizations =
|
||||
customizationService.get('cornerstoneViewportClickCommands') ||
|
||||
DEFAULT_DOUBLE_CLICK;
|
||||
|
||||
const toRun = customizations[eventName];
|
||||
|
||||
if (!toRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
commandsManager.run(toRun);
|
||||
};
|
||||
|
||||
function elementEnabledHandler(evt: CustomEvent) {
|
||||
const { element } = evt.detail;
|
||||
|
||||
element.addEventListener(
|
||||
cs3DToolsEvents.MOUSE_DOUBLE_CLICK,
|
||||
cornerstoneViewportHandleDoubleClick
|
||||
);
|
||||
}
|
||||
|
||||
function elementDisabledHandler(evt: CustomEvent) {
|
||||
const { element } = evt.detail;
|
||||
|
||||
element.removeEventListener(
|
||||
cs3DToolsEvents.MOUSE_DOUBLE_CLICK,
|
||||
cornerstoneViewportHandleDoubleClick
|
||||
);
|
||||
}
|
||||
|
||||
eventTarget.addEventListener(
|
||||
EVENTS.ELEMENT_ENABLED,
|
||||
elementEnabledHandler.bind(null)
|
||||
);
|
||||
|
||||
eventTarget.addEventListener(
|
||||
EVENTS.ELEMENT_DISABLED,
|
||||
elementDisabledHandler.bind(null)
|
||||
);
|
||||
}
|
||||
|
||||
export default initDoubleClick;
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Finds tool nearby event position triggered.
|
||||
*
|
||||
* @param {Object} commandsManager mannager of commands
|
||||
* @param {Object} event that has being triggered
|
||||
* @returns cs toolData or undefined if not found.
|
||||
*/
|
||||
export const findNearbyToolData = (commandsManager, evt) => {
|
||||
if (!evt?.detail) {
|
||||
return;
|
||||
}
|
||||
const { element, currentPoints } = evt.detail;
|
||||
return commandsManager.runCommand(
|
||||
'getNearbyToolData',
|
||||
{
|
||||
element,
|
||||
canvasCoordinates: currentPoints?.canvas,
|
||||
},
|
||||
'CORNERSTONE'
|
||||
);
|
||||
};
|
||||
Reference in new issue
Block a user