feat(extension-cornerstone): Add additional tools: Magnify, ROI Window, Probe, Ellipse, Rectangle, Invert, Rotate Right, Flip H, Flip V, Clear

This commit is contained in:
Evren Ozkan 2019-06-24 18:04:26 -04:00 committed by Erik Ziegler
parent 5ac9048ef0
commit dd6acb2d03
8 changed files with 166 additions and 26 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@ohif/extension-cornerstone", "name": "@ohif/extension-cornerstone",
"version": "0.0.38", "version": "0.0.39",
"description": "OHIF extension for Cornerstone", "description": "OHIF extension for Cornerstone",
"author": "OHIF", "author": "OHIF",
"license": "MIT", "license": "MIT",

View File

@ -1,5 +1,6 @@
import cornerstone from 'cornerstone-core'; import cornerstone from 'cornerstone-core';
import cornerstoneTools from 'cornerstone-tools'; import cornerstoneTools from 'cornerstone-tools';
import OHIF from 'ohif-core';
const actions = { const actions = {
rotateViewport: ({ viewports, rotation }) => { rotateViewport: ({ viewports, rotation }) => {
@ -89,15 +90,60 @@ const actions = {
// TODO // TODO
console.warn('updateDisplaySet: ', direction); console.warn('updateDisplaySet: ', direction);
}, },
clearAnnotations: () => { clearAnnotations: ({ viewports }) => {
console.warn('clearAnnotations: not yet implemented'); const element = _getActiveViewportEnabledElement(
// const toolState = viewports.viewportSpecificData,
// cornerstoneTools.globalImageIdSpecificToolStateManager.toolState; viewports.activeViewportIndex
// if (!toolState) return; );
// Object.keys(toolState).forEach(imageId => { if (!element) {
// if (!cornerstoneImageId || cornerstoneImageId === imageId) return;
// delete toolState[imageId]; }
// });
const enabledElement = cornerstone.getEnabledElement(element);
if (!enabledElement || !enabledElement.image) {
return;
}
const {
toolState,
} = cornerstoneTools.globalImageIdSpecificToolStateManager;
if (
!toolState ||
toolState.hasOwnProperty(enabledElement.image.imageId) === false
) {
return;
}
const imageIdToolState = toolState[enabledElement.image.imageId];
const measurementsToRemove = [];
Object.keys(imageIdToolState).forEach(toolType => {
const { data } = imageIdToolState[toolType];
data.forEach(measurementData => {
const { _id, lesionNamingNumber, measurementNumber } = measurementData;
if (!_id) {
return;
}
measurementsToRemove.push({
toolType,
_id,
lesionNamingNumber,
measurementNumber,
});
});
});
measurementsToRemove.forEach(measurementData => {
OHIF.measurements.MeasurementHandlers.onRemoved({
detail: {
toolType: measurementData.toolType,
measurementData,
},
});
});
}, },
}; };
@ -147,7 +193,11 @@ const definitions = {
storeContexts: ['viewports'], storeContexts: ['viewports'],
options: {}, options: {},
}, },
// TODO: Clear Annotations clearAnnotations: {
commandFn: actions.clearAnnotations,
storeContexts: ['viewports'],
options: {},
},
// TODO: Next/Previous image // TODO: Next/Previous image
// TODO: First/Last image // TODO: First/Last image
// Next/Previous series/DisplaySet // Next/Previous series/DisplaySet

View File

@ -17,12 +17,12 @@
// -- ACTIVE_ROUTE::VIEWER // -- ACTIVE_ROUTE::VIEWER
// -- ACTIVE_VIEWPORT::CORNERSTONE // -- ACTIVE_VIEWPORT::CORNERSTONE
// setToolActive commands should receive the button event that triggered // setToolActive commands should receive the button event that triggered
// so we can do the "bind to this butyon" magic // so we can do the "bind to this button" magic
const TOOLBAR_BUTTON_TYPES = { const TOOLBAR_BUTTON_TYPES = {
COMMAND: 'command', COMMAND: 'command',
SET_TOOL_ACTIVE: 'setToolActive', SET_TOOL_ACTIVE: 'setToolActive',
BUILT_IN: 'builtIn', BUILT_IN: 'builtIn'
}; };
const definitions = [ const definitions = [
@ -98,6 +98,98 @@ const definitions = [
behavior: 'CINE', behavior: 'CINE',
}, },
}, },
{
id: 'More',
label: 'More',
icon: 'ellipse-circle',
buttons: [
{
id: 'Magnify',
label: 'Magnify',
icon: 'circle',
//
type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,
commandName: 'setToolActive',
commandOptions: { toolName: 'Magnify' },
},
{
id: 'WwwcRegion',
label: 'ROI Window',
icon: 'stop',
//
type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,
commandName: 'setToolActive',
commandOptions: { toolName: 'WwwcRegion' },
},
{
id: 'DragProbe',
label: 'Probe',
icon: 'dot-circle',
//
type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,
commandName: 'setToolActive',
commandOptions: { toolName: 'DragProbe' },
},
{
id: 'EllipticalRoi',
label: 'Ellipse',
icon: 'circle-o',
//
type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,
commandName: 'setToolActive',
commandOptions: { toolName: 'EllipticalRoi' },
},
{
id: 'RectangleRoi',
label: 'Rectangle',
icon: 'square-o',
//
type: TOOLBAR_BUTTON_TYPES.SET_TOOL_ACTIVE,
commandName: 'setToolActive',
commandOptions: { toolName: 'RectangleRoi' },
},
{
id: 'Invert',
label: 'Invert',
icon: 'adjust',
//
type: TOOLBAR_BUTTON_TYPES.COMMAND,
commandName: 'invertViewport',
},
{
id: 'RotateRight',
label: 'Rotate Right',
icon: 'rotate-right',
//
type: TOOLBAR_BUTTON_TYPES.COMMAND,
commandName: 'rotateViewportCW',
},
{
id: 'FlipH',
label: 'Flip H',
icon: 'ellipse-h',
//
type: TOOLBAR_BUTTON_TYPES.COMMAND,
commandName: 'flipViewportHorizontal',
},
{
id: 'FlipV',
label: 'Flip V',
icon: 'ellipse-v',
//
type: TOOLBAR_BUTTON_TYPES.COMMAND,
commandName: 'flipViewportVertical',
},
{
id: 'Clear',
label: 'Clear',
icon: 'trash',
//
type: TOOLBAR_BUTTON_TYPES.COMMAND,
commandName: 'clearAnnotations',
},
],
},
]; ];
export default { export default {

View File

@ -76,7 +76,7 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.4.5", "@babel/runtime": "^7.4.5",
"@ohif/extension-cornerstone": "0.0.38", "@ohif/extension-cornerstone": "0.0.39",
"@ohif/extension-dicom-html": "0.0.3", "@ohif/extension-dicom-html": "0.0.3",
"@ohif/extension-dicom-microscopy": "0.0.8", "@ohif/extension-dicom-microscopy": "0.0.8",
"@ohif/extension-dicom-pdf": "0.0.7", "@ohif/extension-dicom-pdf": "0.0.7",

View File

@ -13,7 +13,7 @@ class PluginSwitch extends Component {
render() { render() {
return ( return (
<div className="PluginSwitch"> <div className="PluginSwitch">
<ExpandableToolMenu buttons={this.props.buttons} /> <ExpandableToolMenu buttons={this.props.buttons} text={'View'} />
</div> </div>
); );
} }

View File

@ -1,11 +1,7 @@
import './ToolbarRow.css'; import './ToolbarRow.css';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { import { ExpandableToolMenu, RoundedButtonGroup, ToolbarButton } from 'react-viewerbase';
RoundedButtonGroup,
ToolbarButton,
ExpandableToolMenu,
} from 'react-viewerbase';
import { commandsManager, extensionManager } from './../App.js'; import { commandsManager, extensionManager } from './../App.js';
import ConnectedCineDialog from './ConnectedCineDialog'; import ConnectedCineDialog from './ConnectedCineDialog';
@ -155,7 +151,7 @@ class ToolbarRow extends Component {
*/ */
function _getButtonComponents(toolbarButtons, activeButtons) { function _getButtonComponents(toolbarButtons, activeButtons) {
return toolbarButtons.map((button, index) => { return toolbarButtons.map((button, index) => {
if (button.buttons) { if (button.buttons && button.buttons.length) {
// Iterate over button definitions and update `onClick` behavior // Iterate over button definitions and update `onClick` behavior
const childButtons = button.buttons.map(childButton => { const childButtons = button.buttons.map(childButton => {
childButton.onClick = _handleToolbarButtonClick.bind(this, childButton); childButton.onClick = _handleToolbarButtonClick.bind(this, childButton);
@ -171,7 +167,6 @@ function _getButtonComponents(toolbarButtons, activeButtons) {
/> />
); );
} }
return ( return (
<ToolbarButton <ToolbarButton
key={button.id} key={button.id}

View File

@ -145,6 +145,8 @@ export default function setupTools(store) {
{ name: 'Pan', mouseButtonMasks: [1, 4] }, { name: 'Pan', mouseButtonMasks: [1, 4] },
{ name: 'Zoom', mouseButtonMasks: [1, 2] }, { name: 'Zoom', mouseButtonMasks: [1, 2] },
{ name: 'Wwwc', mouseButtonMasks: [1] }, { name: 'Wwwc', mouseButtonMasks: [1] },
{ name: 'Magnify', mouseButtonMasks: [1] },
{ name: 'WwwcRegion', mouseButtonMasks: [1] },
{ {
name: 'Bidirectional', name: 'Bidirectional',
props: { props: {
@ -210,6 +212,7 @@ export default function setupTools(store) {
}, },
mouseButtonMasks: [1], mouseButtonMasks: [1],
}, },
{ name: 'DragProbe', mouseButtonMasks: [1] },
{ name: 'PanMultiTouch' }, { name: 'PanMultiTouch' },
{ name: 'ZoomTouchPinch' }, { name: 'ZoomTouchPinch' },
{ name: 'StackScrollMouseWheel' }, { name: 'StackScrollMouseWheel' },

View File

@ -1214,10 +1214,10 @@
universal-user-agent "^2.0.0" universal-user-agent "^2.0.0"
url-template "^2.0.8" url-template "^2.0.8"
"@ohif/extension-cornerstone@0.0.38": "@ohif/extension-cornerstone@0.0.39":
version "0.0.38" version "0.0.39"
resolved "https://registry.yarnpkg.com/@ohif/extension-cornerstone/-/extension-cornerstone-0.0.38.tgz#c1cdf2796bef441a293bcc045f9748c7b2c1395f" resolved "https://registry.yarnpkg.com/@ohif/extension-cornerstone/-/extension-cornerstone-0.0.39.tgz#aa70e3181cd1aa24101e815161fd9688722d26d6"
integrity sha512-xWvK04s2xwjNlIvz4BpJ5pWP8wNmW9kpud1zkywR+TFYgthH2X64Tr01VZTOh8Mi+0Xkwe5IElb4Sw2aVA4SBg== integrity sha512-HVu+tUYgdY7J9SxfA1R5YGuninMe+eOtGAX4Rx5YgunsH8QQmC+uhSjcclJt8Z+W7ac/iQ+k6Hx9smnPBqiObw==
dependencies: dependencies:
"@babel/runtime" "^7.2.0" "@babel/runtime" "^7.2.0"
classnames "^2.2.6" classnames "^2.2.6"