Integrate Cornerstone Tools v3 (#235) - WIP
fix(mouse-buttons): Support for assigning tools to mouse buttons (left, right, middle) fix(tool-naming): Fix tool naming issues
This commit is contained in:
parent
7bf059ad05
commit
3f2968b05f
@ -288,28 +288,29 @@ Template.toolbarSection.onCreated( function() {
|
||||
});
|
||||
|
||||
Template.toolbarSection.onRendered(function() {
|
||||
// Set disabled/enabled tool buttons that are set in toolManager
|
||||
const states = Viewerbase.toolManager.getToolDefaultStates();
|
||||
const disabledToolButtons = states.disabledToolButtons;
|
||||
const allToolbarButtons = $('.toolbarSection').find('.toolbarSectionButton:not(.nonAutoDisableState)');
|
||||
|
||||
// Additional toolbar buttons whose classes are not toolbarSectionButton
|
||||
allToolbarButtons.push($('#toolbarSectionEntry')[0]);
|
||||
allToolbarButtons.push($('#toggleMeasurements')[0]);
|
||||
|
||||
if (disabledToolButtons && disabledToolButtons.length > 0) {
|
||||
for (let i = 0; i < allToolbarButtons.length; i++) {
|
||||
const toolbarButton = allToolbarButtons[i];
|
||||
const index = disabledToolButtons.indexOf($(toolbarButton).attr('id'));
|
||||
if (index !== -1) {
|
||||
$(toolbarButton).addClass('disabled');
|
||||
$(toolbarButton).find('*').addClass('disabled');
|
||||
} else {
|
||||
$(toolbarButton).removeClass('disabled');
|
||||
$(toolbarButton).find('*').removeClass('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Figure out a way to disable/enable the buttons with each status from New API
|
||||
// // Set disabled/enabled tool buttons that are set in toolManager
|
||||
// const states = Viewerbase.toolManager.getToolDefaultStates();
|
||||
// const disabledToolButtons = states.disabledToolButtons;
|
||||
// const allToolbarButtons = $('.toolbarSection').find('.toolbarSectionButton:not(.nonAutoDisableState)');
|
||||
//
|
||||
// // Additional toolbar buttons whose classes are not toolbarSectionButton
|
||||
// allToolbarButtons.push($('#toolbarSectionEntry')[0]);
|
||||
// allToolbarButtons.push($('#toggleMeasurements')[0]);
|
||||
//
|
||||
// if (disabledToolButtons && disabledToolButtons.length > 0) {
|
||||
// for (let i = 0; i < allToolbarButtons.length; i++) {
|
||||
// const toolbarButton = allToolbarButtons[i];
|
||||
// const index = disabledToolButtons.indexOf($(toolbarButton).attr('id'));
|
||||
// if (index !== -1) {
|
||||
// $(toolbarButton).addClass('disabled');
|
||||
// $(toolbarButton).find('*').addClass('disabled');
|
||||
// } else {
|
||||
// $(toolbarButton).removeClass('disabled');
|
||||
// $(toolbarButton).find('*').removeClass('disabled');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
});
|
||||
|
||||
Template.caseProgress.onDestroyed(() => {
|
||||
|
||||
@ -303,20 +303,20 @@ Template.toolbarSection.onRendered(function() {
|
||||
OHIF.viewerbase.viewportUtils.toggleCineDialog();
|
||||
}
|
||||
|
||||
// Set disabled/enabled tool buttons that are set in toolManager
|
||||
|
||||
const states = OHIF.viewerbase.toolManager.getToolDefaultStates();
|
||||
const disabledToolButtons = states.disabledToolButtons;
|
||||
const allToolbarButtons = $('#toolbar').find('button');
|
||||
if (disabledToolButtons && disabledToolButtons.length > 0) {
|
||||
for (let i = 0; i < allToolbarButtons.length; i++) {
|
||||
const toolbarButton = allToolbarButtons[i];
|
||||
$(toolbarButton).prop('disabled', false);
|
||||
|
||||
const index = disabledToolButtons.indexOf($(toolbarButton).attr('id'));
|
||||
if (index !== -1) {
|
||||
$(toolbarButton).prop('disabled', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Figure out a way to disable/enable the buttons with each status from New API
|
||||
// // Set disabled/enabled tool buttons that are set in toolManager
|
||||
// const states = OHIF.viewerbase.toolManager.getToolDefaultStates();
|
||||
// const disabledToolButtons = states.disabledToolButtons;
|
||||
// const allToolbarButtons = $('#toolbar').find('button');
|
||||
// if (disabledToolButtons && disabledToolButtons.length > 0) {
|
||||
// for (let i = 0; i < allToolbarButtons.length; i++) {
|
||||
// const toolbarButton = allToolbarButtons[i];
|
||||
// $(toolbarButton).prop('disabled', false);
|
||||
//
|
||||
// const index = disabledToolButtons.indexOf($(toolbarButton).attr('id'));
|
||||
// if (index !== -1) {
|
||||
// $(toolbarButton).prop('disabled', true);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
});
|
||||
|
||||
@ -48,7 +48,12 @@ Meteor.startup(() => {
|
||||
Session.setDefault('leftSidebar', false);
|
||||
Session.setDefault('rightSidebar', false);
|
||||
|
||||
OHIF.viewer.defaultTool = 'wwwc';
|
||||
OHIF.viewer.defaultTool = {
|
||||
left: 'wwwc',
|
||||
right: 'zoom',
|
||||
middle: 'pan'
|
||||
};
|
||||
|
||||
OHIF.viewer.refLinesEnabled = true;
|
||||
OHIF.viewer.cine = {
|
||||
framesPerSecond: 24,
|
||||
|
||||
@ -6,8 +6,8 @@ Package.describe({
|
||||
|
||||
Npm.depends({
|
||||
hammerjs: '2.0.8',
|
||||
'cornerstone-core': '2.2.6',
|
||||
'cornerstone-tools': '3.0.0-b.969',
|
||||
'cornerstone-core': '2.2.7',
|
||||
'cornerstone-tools': '3.0.0-b.1020',
|
||||
'cornerstone-math': '0.1.6',
|
||||
'dicom-parser': '1.8.0',
|
||||
'cornerstone-wado-image-loader': '2.1.4',
|
||||
|
||||
@ -272,8 +272,7 @@ const loadDisplaySetIntoViewport = (data, templateData) => {
|
||||
|
||||
// Use the tool manager to enable the currently active tool for this
|
||||
// newly rendered element
|
||||
const activeTool = toolManager.getActiveTool();
|
||||
toolManager.setActiveTool(activeTool);
|
||||
toolManager.setActiveTool();
|
||||
|
||||
// Define a function to run whenever the Cornerstone viewport is rendered
|
||||
// (e.g. following a change of window or zoom)
|
||||
@ -453,6 +452,7 @@ const loadDisplaySetIntoViewport = (data, templateData) => {
|
||||
// that is used for its synchronized viewport updating.
|
||||
// This is necessary if this new image shares a frame of reference
|
||||
// with currently displayed images
|
||||
const activeTool = toolManager.getActiveTool();
|
||||
if (activeTool === 'crosshairs') {
|
||||
updateCrosshairsSynchronizer(imagePlane.frameOfReferenceUID);
|
||||
}
|
||||
|
||||
@ -50,10 +50,10 @@ Template.textMarkerDialogs.events({
|
||||
cornerstone.updateImage(element);
|
||||
},
|
||||
'click .closeTextMarkerDialogs'() {
|
||||
const defaultTool = toolManager.getDefaultTool();
|
||||
toolManager.setActiveTool(defaultTool);
|
||||
toolManager.setActiveTool();
|
||||
document.getElementById('textMarkerOptionsDialog').close();
|
||||
$('#spine').removeClass('active');
|
||||
const defaultTool = toolManager.getDefaultTool();
|
||||
$('#' + defaultTool).addClass('active');
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,13 @@ import { WLPresets } from './WLPresets';
|
||||
// TODO: add this to namespace definitions
|
||||
Meteor.startup(function() {
|
||||
OHIF.viewer.loadIndicatorDelay = 200;
|
||||
OHIF.viewer.defaultTool = 'Wwwc';
|
||||
|
||||
OHIF.viewer.defaultTool = {
|
||||
left: 'wwwc',
|
||||
right: 'zoom',
|
||||
middle: 'pan'
|
||||
};
|
||||
|
||||
OHIF.viewer.refLinesEnabled = true;
|
||||
OHIF.viewer.isPlaying = {};
|
||||
OHIF.viewer.cine = {
|
||||
@ -24,17 +30,17 @@ Meteor.startup(function() {
|
||||
OHIF.viewer.defaultHotkeys = {
|
||||
// Tool hotkeys
|
||||
defaultTool: 'ESC',
|
||||
Zoom: 'Z',
|
||||
Wwwc: 'W',
|
||||
Pan: 'P',
|
||||
Angle: 'A',
|
||||
StackScroll: 'S',
|
||||
Magnify: 'M',
|
||||
Length: '',
|
||||
Annotate: '',
|
||||
DragProbe: '',
|
||||
EllipticalRoi: '',
|
||||
RectangleRoi: '',
|
||||
zoom: 'Z',
|
||||
wwwc: 'W',
|
||||
pan: 'P',
|
||||
angle: 'A',
|
||||
stackScroll: 'S',
|
||||
magnify: 'M',
|
||||
length: '',
|
||||
annotate: '',
|
||||
dragProbe: '',
|
||||
ellipticalRoi: '',
|
||||
rectangleRoi: '',
|
||||
|
||||
// Viewport hotkeys
|
||||
flipH: 'H',
|
||||
@ -102,25 +108,24 @@ Meteor.startup(function() {
|
||||
// Register the default tool command
|
||||
OHIF.commands.register(contextName, 'defaultTool', {
|
||||
name: 'Default Tool',
|
||||
action: () => toolManager.setActiveTool(toolManager.getDefaultTool())
|
||||
action: () => toolManager.setActiveTool()
|
||||
});
|
||||
|
||||
// Register the tool switching commands
|
||||
registerToolCommands({
|
||||
Wwwc: 'W/L',
|
||||
Zoom: 'Zoom',
|
||||
Angle: 'Angle Measurement',
|
||||
DragProbe: 'Pixel Probe',
|
||||
StackScroll: 'Stack Scroll',
|
||||
EllipticalRoi: 'Elliptical ROI',
|
||||
RectangleRoi: 'Rectangle ROI',
|
||||
Magnify: 'Magnify',
|
||||
ArrowAnnotate: 'Annotate',
|
||||
stackScrollMouseWheel: 'Scroll Stack Mouse Wheel',
|
||||
Pan: 'Pan',
|
||||
Length: 'Length Measurement',
|
||||
WwwcRegion: 'W/L by Region',
|
||||
Crosshairs: 'Crosshairs'
|
||||
wwwc: 'W/L',
|
||||
zoom: 'Zoom',
|
||||
angle: 'Angle Measurement',
|
||||
dragProbe: 'Pixel Probe',
|
||||
ellipticalRoi: 'Elliptical ROI',
|
||||
rectangleRoi: 'Rectangle ROI',
|
||||
magnify: 'Magnify',
|
||||
annotate: 'Annotate',
|
||||
stackScroll: 'Scroll Stack',
|
||||
pan: 'Pan',
|
||||
length: 'Length Measurement',
|
||||
wwwcRegion: 'W/L by Region',
|
||||
crosshairs: 'Crosshairs'
|
||||
});
|
||||
|
||||
// Functions to register the viewport commands
|
||||
|
||||
@ -4,17 +4,17 @@ import { OHIF } from 'meteor/ohif:core';
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
|
||||
let activeTool;
|
||||
let tools = [];
|
||||
let tools = {};
|
||||
let initialized = false;
|
||||
let defaultTool = {
|
||||
left: 'Wwwc',
|
||||
right: 'Zoom',
|
||||
middle: 'Pan'
|
||||
left: 'wwwc',
|
||||
right: 'zoom',
|
||||
middle: 'pan'
|
||||
};
|
||||
const buttonNum = {
|
||||
'left': 1,
|
||||
'right': 4,
|
||||
'middle': 2
|
||||
'right': 2,
|
||||
'middle': 4
|
||||
};
|
||||
|
||||
/**
|
||||
@ -24,29 +24,30 @@ export const toolManager = {
|
||||
init() {
|
||||
// if a default tool is globally defined, make it the default tool...
|
||||
if (OHIF.viewer.defaultTool) {
|
||||
toolManager.setDefaultTool(OHIF.viewer.defaultTool);
|
||||
toolManager.setDefaultTool(OHIF.viewer.defaultTool.left);
|
||||
toolManager.setDefaultTool(OHIF.viewer.defaultTool.right, 'right');
|
||||
toolManager.setDefaultTool(OHIF.viewer.defaultTool.middle, 'middle');
|
||||
}
|
||||
|
||||
cornerstoneTools.init();
|
||||
|
||||
tools = [
|
||||
'Length',
|
||||
'Angle',
|
||||
'ArrowAnnotate',
|
||||
'Wwwc',
|
||||
'Zoom',
|
||||
'Pan',
|
||||
'DragProbe',
|
||||
'Magnify',
|
||||
'Crosshairs',
|
||||
'StackScroll',
|
||||
'StackScrollMouseWheel',
|
||||
'ZoomTouchPinch',
|
||||
'ZoomMouseWheel',
|
||||
'EllipticalRoi',
|
||||
'RectangleRoi',
|
||||
'WwwcRegion'
|
||||
];
|
||||
tools = {
|
||||
length: 'LengthTool',
|
||||
angle: 'AngleTool',
|
||||
annotate: 'ArrowAnnotateTool',
|
||||
wwwc: 'WwwcTool',
|
||||
zoom: 'ZoomTool',
|
||||
pan: 'PanTool',
|
||||
dragProbe: 'DragProbeTool',
|
||||
magnify: 'MagnifyTool',
|
||||
crosshairs: 'CrosshairsTool',
|
||||
stackScroll: 'StackScrollTool',
|
||||
zoomTouchPinch: 'ZoomTouchPinchTool',
|
||||
zoomMouseWheel: 'ZoomMouseWheelTool',
|
||||
ellipticalRoi: 'EllipticalRoiTool',
|
||||
rectangleRoi: 'RectangleRoiTool',
|
||||
wwwcRegion: 'WwwcRegionTool'
|
||||
};
|
||||
|
||||
initialized = true;
|
||||
},
|
||||
@ -88,10 +89,18 @@ export const toolManager = {
|
||||
},
|
||||
|
||||
getTools() {
|
||||
return tools;
|
||||
return Object.keys(tools);
|
||||
},
|
||||
|
||||
setActiveTool(toolName, button = 'left') {
|
||||
// Using setActiveTool with no arguments activates the default tools for all buttons
|
||||
if (!toolName) {
|
||||
toolManager.setActiveTool(toolManager.getDefaultTool());
|
||||
toolManager.setActiveTool(toolManager.getDefaultTool('right'), 'right');
|
||||
toolManager.setActiveTool(toolManager.getDefaultTool('middle'), 'middle');
|
||||
return;
|
||||
}
|
||||
|
||||
let options = {};
|
||||
const mouseButtonMask = toolManager.getMouseButtonMask(button);
|
||||
if (mouseButtonMask) {
|
||||
@ -101,9 +110,36 @@ export const toolManager = {
|
||||
}
|
||||
|
||||
toolManager.setAllToolsPassive();
|
||||
cornerstoneTools.setToolActive(toolName, options);
|
||||
|
||||
// TODO: add the active tool with the correct button
|
||||
// Set active tools for the other buttons than this one
|
||||
switch(button) {
|
||||
case 'left':
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('right'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('right')
|
||||
});
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('middle'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('middle')
|
||||
});
|
||||
break;
|
||||
case 'right':
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('left'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('left')
|
||||
});
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('middle'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('middle')
|
||||
});
|
||||
break;
|
||||
case 'middle':
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('left'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('left')
|
||||
});
|
||||
cornerstoneTools.setToolActive(toolManager.getActiveTool('right'), {
|
||||
mouseButtonMask: toolManager.getMouseButtonMask('right')
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
cornerstoneTools.setToolActive(toolName, options);
|
||||
activeTool[button] = toolName;
|
||||
|
||||
// Enable reactivity
|
||||
@ -111,22 +147,24 @@ export const toolManager = {
|
||||
},
|
||||
|
||||
setAllToolsPassive() {
|
||||
cornerstoneTools.store.state.tools.forEach((tool) => {
|
||||
cornerstoneTools.setToolPassive(tool.name)
|
||||
});
|
||||
cornerstoneTools.store.state.tools.forEach((tool) => {
|
||||
cornerstoneTools.setToolPassive(tool.name)
|
||||
});
|
||||
},
|
||||
|
||||
instantiateTools() {
|
||||
Array.from(tools).forEach(toolName => {
|
||||
const apiTool = cornerstoneTools[`${toolName}Tool`];
|
||||
Object.keys(tools).forEach(toolName => {
|
||||
const apiTool = cornerstoneTools[tools[toolName]];
|
||||
if (apiTool) {
|
||||
cornerstoneTools.addTool(apiTool);
|
||||
cornerstoneTools.addTool(apiTool, { name: toolName });
|
||||
}
|
||||
});
|
||||
toolManager.setAllToolsPassive();
|
||||
},
|
||||
|
||||
getNearbyToolData() {
|
||||
// TODO: Implement this and let the others (e.g. deleteLesionKeyboardTool) use this function
|
||||
// if it does not exist in cornerstoneTools
|
||||
return undefined;
|
||||
},
|
||||
|
||||
@ -152,11 +190,11 @@ export const toolManager = {
|
||||
},
|
||||
|
||||
activateCommandButton(button) {
|
||||
//
|
||||
// TODO: Do we need this?
|
||||
},
|
||||
|
||||
deactivateCommandButton(button) {
|
||||
//
|
||||
// TODO: Do we need this?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -47,42 +47,42 @@ Template.toolbarSection.helpers({
|
||||
const extraTools = [];
|
||||
|
||||
extraTools.push({
|
||||
id: 'Crosshairs',
|
||||
id: 'crosshairs',
|
||||
title: 'Crosshairs',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-crosshairs'
|
||||
});
|
||||
|
||||
extraTools.push({
|
||||
id: 'Magnify',
|
||||
id: 'magnify',
|
||||
title: 'Magnify',
|
||||
classes: 'imageViewerTool toolbarSectionButton',
|
||||
iconClasses: 'fa fa-circle'
|
||||
});
|
||||
|
||||
extraTools.push({
|
||||
id: 'WwwcRegion',
|
||||
id: 'wwwcRegion',
|
||||
title: 'ROI Window',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-square'
|
||||
});
|
||||
|
||||
extraTools.push({
|
||||
id: 'DragProbe',
|
||||
id: 'dragProbe',
|
||||
title: 'Probe',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-dot-circle-o'
|
||||
});
|
||||
|
||||
extraTools.push({
|
||||
id: 'EllipticalRoi',
|
||||
id: 'ellipticalRoi',
|
||||
title: 'Ellipse',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-circle-o'
|
||||
});
|
||||
|
||||
extraTools.push({
|
||||
id: 'RectangleRoi',
|
||||
id: 'rectangleRoi',
|
||||
title: 'Rectangle',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-square-o'
|
||||
@ -126,49 +126,49 @@ Template.toolbarSection.helpers({
|
||||
const buttonData = [];
|
||||
|
||||
buttonData.push({
|
||||
id: 'StackScroll',
|
||||
id: 'stackScroll',
|
||||
title: 'Stack Scroll',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-bars'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'Zoom',
|
||||
id: 'zoom',
|
||||
title: 'Zoom',
|
||||
classes: 'imageViewerTool',
|
||||
svgLink: 'packages/ohif_viewerbase/assets/icons.svg#icon-tools-zoom'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'Wwwc',
|
||||
id: 'wwwc',
|
||||
title: 'Levels',
|
||||
classes: 'imageViewerTool',
|
||||
svgLink: 'packages/ohif_viewerbase/assets/icons.svg#icon-tools-levels'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'Pan',
|
||||
id: 'pan',
|
||||
title: 'Pan',
|
||||
classes: 'imageViewerTool',
|
||||
svgLink: 'packages/ohif_viewerbase/assets/icons.svg#icon-tools-pan'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'Length',
|
||||
id: 'length',
|
||||
title: 'Length',
|
||||
classes: 'imageViewerTool toolbarSectionButton',
|
||||
svgLink: 'packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-temp'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'ArrowAnnotate',
|
||||
id: 'annotate',
|
||||
title: 'Annotate',
|
||||
classes: 'imageViewerTool',
|
||||
svgLink: 'packages/ohif_viewerbase/assets/icons.svg#icon-tools-measure-non-target'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'Angle',
|
||||
id: 'angle',
|
||||
title: 'Angle',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-angle-left'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user