fix(toolbar): allow customizable toolbar for active viewport and allow active tool to be deactivated via a click (#3608)
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
This commit is contained in:
parent
2145b42920
commit
dd6d9768bb
@ -456,13 +456,8 @@ function commandsModule({
|
|||||||
|
|
||||||
const { viewport } = enabledElement;
|
const { viewport } = enabledElement;
|
||||||
|
|
||||||
if (viewport instanceof StackViewport) {
|
viewport.resetProperties?.();
|
||||||
viewport.resetProperties();
|
|
||||||
viewport.resetCamera();
|
viewport.resetCamera();
|
||||||
} else {
|
|
||||||
viewport.resetProperties();
|
|
||||||
viewport.resetCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
viewport.render();
|
viewport.render();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,19 +1,34 @@
|
|||||||
import React, { useEffect, useState, useCallback } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import { useViewportGrid } from '@ohif/ui';
|
||||||
|
|
||||||
export default function Toolbar({ servicesManager }) {
|
export default function Toolbar({
|
||||||
|
servicesManager,
|
||||||
|
}: Types.Extensions.ExtensionParams): React.ReactElement {
|
||||||
const { toolbarService } = servicesManager.services;
|
const { toolbarService } = servicesManager.services;
|
||||||
|
|
||||||
|
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||||
|
|
||||||
const [toolbarButtons, setToolbarButtons] = useState([]);
|
const [toolbarButtons, setToolbarButtons] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { unsubscribe } = toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, () =>
|
const updateToolbar = () => {
|
||||||
setToolbarButtons(toolbarService.getButtonSection('primary'))
|
const toolGroupId =
|
||||||
|
viewportGridService.getActiveViewportOptionByKey('toolGroupId') ?? 'default';
|
||||||
|
setToolbarButtons(toolbarService.getButtonSection(toolGroupId));
|
||||||
|
};
|
||||||
|
|
||||||
|
const { unsubscribe } = toolbarService.subscribe(
|
||||||
|
toolbarService.EVENTS.TOOL_BAR_MODIFIED,
|
||||||
|
updateToolbar
|
||||||
);
|
);
|
||||||
|
|
||||||
|
updateToolbar();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [toolbarService]);
|
}, [toolbarService, viewportGrid]);
|
||||||
|
|
||||||
const onInteraction = useCallback(
|
const onInteraction = useCallback(
|
||||||
args => toolbarService.recordInteraction(args),
|
args => toolbarService.recordInteraction(args),
|
||||||
|
|||||||
@ -65,7 +65,7 @@ ToolbarButtonWithServices.propTypes = {
|
|||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
primaryToolId: PropTypes.string,
|
primaryToolId: PropTypes.string,
|
||||||
toggles: PropTypes.objectOf(PropTypes.bool),
|
toggles: PropTypes.objectOf(PropTypes.bool),
|
||||||
groups: PropTypes.objectOf(PropTypes.object),
|
groups: PropTypes.objectOf(PropTypes.any),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
|||||||
@ -2,11 +2,16 @@ import { hotkeys } from '@ohif/core';
|
|||||||
import toolbarButtons from './toolbarButtons';
|
import toolbarButtons from './toolbarButtons';
|
||||||
import { id } from './id';
|
import { id } from './id';
|
||||||
import initToolGroups from './initToolGroups';
|
import initToolGroups from './initToolGroups';
|
||||||
|
import moreTools from './moreTools';
|
||||||
|
import moreToolsMpr from './moreToolsMpr';
|
||||||
|
|
||||||
// Allow this mode by excluding non-imaging modalities such as SR, SEG
|
// Allow this mode by excluding non-imaging modalities such as SR, SEG
|
||||||
// Also, SM is not a simple imaging modalities, so exclude it.
|
// Also, SM is not a simple imaging modalities, so exclude it.
|
||||||
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG'];
|
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG'];
|
||||||
|
|
||||||
|
const DEFAULT_TOOL_GROUP_ID = 'default';
|
||||||
|
const MPR_TOOL_GROUP_ID = 'mpr';
|
||||||
|
|
||||||
const ohif = {
|
const ohif = {
|
||||||
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
||||||
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
|
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
|
||||||
@ -77,10 +82,9 @@ function modeFactory() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
let unsubscribe;
|
let unsubscribe;
|
||||||
|
toolbarService.setDefaultTool({
|
||||||
const activateTool = () => {
|
|
||||||
toolbarService.recordInteraction({
|
|
||||||
groupId: 'WindowLevel',
|
groupId: 'WindowLevel',
|
||||||
|
itemId: 'WindowLevel',
|
||||||
interactionType: 'tool',
|
interactionType: 'tool',
|
||||||
commands: [
|
commands: [
|
||||||
{
|
{
|
||||||
@ -93,6 +97,9 @@ function modeFactory() {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const activateTool = () => {
|
||||||
|
toolbarService.recordInteraction(toolbarService.getDefaultTool());
|
||||||
|
|
||||||
// We don't need to reset the active tool whenever a viewport is getting
|
// We don't need to reset the active tool whenever a viewport is getting
|
||||||
// added to the toolGroup.
|
// added to the toolGroup.
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
@ -106,8 +113,18 @@ function modeFactory() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
toolbarService.init(extensionManager);
|
toolbarService.init(extensionManager);
|
||||||
toolbarService.addButtons(toolbarButtons);
|
toolbarService.addButtons([...toolbarButtons, ...moreTools, ...moreToolsMpr]);
|
||||||
toolbarService.createButtonSection('primary', [
|
toolbarService.createButtonSection(DEFAULT_TOOL_GROUP_ID, [
|
||||||
|
'MeasurementTools',
|
||||||
|
'Zoom',
|
||||||
|
'WindowLevel',
|
||||||
|
'Pan',
|
||||||
|
'Capture',
|
||||||
|
'Layout',
|
||||||
|
'MPR',
|
||||||
|
'MoreTools',
|
||||||
|
]);
|
||||||
|
toolbarService.createButtonSection(MPR_TOOL_GROUP_ID, [
|
||||||
'MeasurementTools',
|
'MeasurementTools',
|
||||||
'Zoom',
|
'Zoom',
|
||||||
'WindowLevel',
|
'WindowLevel',
|
||||||
@ -116,7 +133,7 @@ function modeFactory() {
|
|||||||
'Layout',
|
'Layout',
|
||||||
'MPR',
|
'MPR',
|
||||||
'Crosshairs',
|
'Crosshairs',
|
||||||
'MoreTools',
|
'MoreToolsMpr',
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
onModeExit: ({ servicesManager }) => {
|
onModeExit: ({ servicesManager }) => {
|
||||||
|
|||||||
231
modes/basic-test-mode/src/moreTools.ts
Normal file
231
modes/basic-test-mode/src/moreTools.ts
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
import type { RunCommand } from '@ohif/core/types';
|
||||||
|
import { EVENTS } from '@cornerstonejs/core';
|
||||||
|
import { ToolbarService } from '@ohif/core';
|
||||||
|
|
||||||
|
const ReferenceLinesCommands: RunCommand = [
|
||||||
|
{
|
||||||
|
commandName: 'setSourceViewportForReferenceLinesTool',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'ReferenceLines',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const moreTools = [
|
||||||
|
{
|
||||||
|
id: 'MoreTools',
|
||||||
|
type: 'ohif.splitButton',
|
||||||
|
props: {
|
||||||
|
isRadio: true, // ?
|
||||||
|
groupId: 'MoreTools',
|
||||||
|
primary: ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
secondary: {
|
||||||
|
icon: 'chevron-down',
|
||||||
|
label: '',
|
||||||
|
isActive: true,
|
||||||
|
tooltip: 'More Tools',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'rotate-right',
|
||||||
|
'tool-rotate-right',
|
||||||
|
'Rotate Right',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'rotateViewportCW',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rotate +90'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'flip-horizontal',
|
||||||
|
'tool-flip-horizontal',
|
||||||
|
'Flip Horizontally',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'flipViewportHorizontal',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Flip Horizontally'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'StackImageSync',
|
||||||
|
'link',
|
||||||
|
'Stack Image Sync',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Enable position synchronization on stack viewports',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: {
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
commandOptions: { toggledState: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'ReferenceLines',
|
||||||
|
'tool-referenceLines', // change this with the new icon
|
||||||
|
'Reference Lines',
|
||||||
|
ReferenceLinesCommands,
|
||||||
|
'Show Reference Lines',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: ReferenceLinesCommands,
|
||||||
|
[EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesCommands,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'StackScroll',
|
||||||
|
'tool-stack-scroll',
|
||||||
|
'Stack Scroll',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'StackScroll',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Stack Scroll'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'invert',
|
||||||
|
'tool-invert',
|
||||||
|
'Invert',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'invertViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Invert Colors'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Probe',
|
||||||
|
'tool-probe',
|
||||||
|
'Probe',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'DragProbe',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Probe'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'cine',
|
||||||
|
'tool-cine',
|
||||||
|
'Cine',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleCine',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Cine'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Angle',
|
||||||
|
'tool-angle',
|
||||||
|
'Angle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Angle',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Angle'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Magnify',
|
||||||
|
'tool-magnify',
|
||||||
|
'Magnify',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Magnify',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Magnify'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Rectangle',
|
||||||
|
'tool-rectangle',
|
||||||
|
'Rectangle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'RectangleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rectangle'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'TagBrowser',
|
||||||
|
'list-bullets',
|
||||||
|
'Dicom Tag Browser',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'openDICOMTagViewer',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'DEFAULT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Dicom Tag Browser'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default moreTools;
|
||||||
142
modes/basic-test-mode/src/moreToolsMpr.ts
Normal file
142
modes/basic-test-mode/src/moreToolsMpr.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import { ToolbarService } from '@ohif/core';
|
||||||
|
|
||||||
|
const moreToolsMpr = [
|
||||||
|
{
|
||||||
|
id: 'MoreToolsMpr',
|
||||||
|
type: 'ohif.splitButton',
|
||||||
|
props: {
|
||||||
|
isRadio: true, // ?
|
||||||
|
groupId: 'MoreTools',
|
||||||
|
primary: ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
secondary: {
|
||||||
|
icon: 'chevron-down',
|
||||||
|
label: '',
|
||||||
|
isActive: true,
|
||||||
|
tooltip: 'More Tools',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'StackScroll',
|
||||||
|
'tool-stack-scroll',
|
||||||
|
'Stack Scroll',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'StackScroll',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Stack Scroll'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'invert',
|
||||||
|
'tool-invert',
|
||||||
|
'Invert',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'invertViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Invert Colors'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Probe',
|
||||||
|
'tool-probe',
|
||||||
|
'Probe',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'DragProbe',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Probe'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'cine',
|
||||||
|
'tool-cine',
|
||||||
|
'Cine',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleCine',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Cine'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Angle',
|
||||||
|
'tool-angle',
|
||||||
|
'Angle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Angle',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Angle'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Rectangle',
|
||||||
|
'tool-rectangle',
|
||||||
|
'Rectangle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'RectangleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rectangle'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'TagBrowser',
|
||||||
|
'list-bullets',
|
||||||
|
'Dicom Tag Browser',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'openDICOMTagViewer',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'DEFAULT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Dicom Tag Browser'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default moreToolsMpr;
|
||||||
@ -5,16 +5,11 @@ import {
|
|||||||
// ListMenu,
|
// ListMenu,
|
||||||
WindowLevelMenuItem,
|
WindowLevelMenuItem,
|
||||||
} from '@ohif/ui';
|
} from '@ohif/ui';
|
||||||
import { defaults, ToolbarService } from '@ohif/core';
|
import { ToolbarService, defaults } from '@ohif/core';
|
||||||
import type { Button, RunCommand } from '@ohif/core/types';
|
import type { Button } from '@ohif/core/types';
|
||||||
import { EVENTS } from '@cornerstonejs/core';
|
|
||||||
|
|
||||||
const { windowLevelPresets } = defaults;
|
const { windowLevelPresets } = defaults;
|
||||||
|
|
||||||
const _createActionButton = ToolbarService._createButton.bind(null, 'action');
|
|
||||||
const _createToggleButton = ToolbarService._createButton.bind(null, 'toggle');
|
|
||||||
const _createToolButton = ToolbarService._createButton.bind(null, 'tool');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {*} preset - preset number (from above import)
|
* @param {*} preset - preset number (from above import)
|
||||||
@ -39,20 +34,6 @@ function _createWwwcPreset(preset, title, subtitle) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReferenceLinesCommands: RunCommand = [
|
|
||||||
{
|
|
||||||
commandName: 'setSourceViewportForReferenceLinesTool',
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'ReferenceLines',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const toolbarButtons: Button[] = [
|
const toolbarButtons: Button[] = [
|
||||||
// Measurement
|
// Measurement
|
||||||
{
|
{
|
||||||
@ -62,7 +43,7 @@ const toolbarButtons: Button[] = [
|
|||||||
groupId: 'MeasurementTools',
|
groupId: 'MeasurementTools',
|
||||||
isRadio: true, // ?
|
isRadio: true, // ?
|
||||||
// Switch?
|
// Switch?
|
||||||
primary: _createToolButton(
|
primary: ToolbarService._createToolButton(
|
||||||
'Length',
|
'Length',
|
||||||
'tool-length',
|
'tool-length',
|
||||||
'Length',
|
'Length',
|
||||||
@ -93,7 +74,7 @@ const toolbarButtons: Button[] = [
|
|||||||
tooltip: 'More Measure Tools',
|
tooltip: 'More Measure Tools',
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'Length',
|
'Length',
|
||||||
'tool-length',
|
'tool-length',
|
||||||
'Length',
|
'Length',
|
||||||
@ -117,7 +98,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Length Tool'
|
'Length Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
'tool-bidirectional',
|
'tool-bidirectional',
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
@ -140,7 +121,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Bidirectional Tool'
|
'Bidirectional Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'ArrowAnnotate',
|
'ArrowAnnotate',
|
||||||
'tool-annotate',
|
'tool-annotate',
|
||||||
'Annotation',
|
'Annotation',
|
||||||
@ -163,7 +144,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Arrow Annotate'
|
'Arrow Annotate'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'EllipticalROI',
|
'EllipticalROI',
|
||||||
'tool-elipse',
|
'tool-elipse',
|
||||||
'Ellipse',
|
'Ellipse',
|
||||||
@ -186,7 +167,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'CircleROI',
|
'CircleROI',
|
||||||
'tool-circle',
|
'tool-circle',
|
||||||
'Circle',
|
'Circle',
|
||||||
@ -237,7 +218,7 @@ const toolbarButtons: Button[] = [
|
|||||||
type: 'ohif.splitButton',
|
type: 'ohif.splitButton',
|
||||||
props: {
|
props: {
|
||||||
groupId: 'WindowLevel',
|
groupId: 'WindowLevel',
|
||||||
primary: _createToolButton(
|
primary: ToolbarService._createToolButton(
|
||||||
'WindowLevel',
|
'WindowLevel',
|
||||||
'tool-window-level',
|
'tool-window-level',
|
||||||
'Window Level',
|
'Window Level',
|
||||||
@ -411,7 +392,6 @@ const toolbarButtons: Button[] = [
|
|||||||
commandOptions: {
|
commandOptions: {
|
||||||
protocolId: 'mpr',
|
protocolId: 'mpr',
|
||||||
},
|
},
|
||||||
context: 'DEFAULT',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -430,225 +410,10 @@ const toolbarButtons: Button[] = [
|
|||||||
toolGroupId: 'mpr',
|
toolGroupId: 'mpr',
|
||||||
toolName: 'Crosshairs',
|
toolName: 'Crosshairs',
|
||||||
},
|
},
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// More...
|
|
||||||
{
|
|
||||||
id: 'MoreTools',
|
|
||||||
type: 'ohif.splitButton',
|
|
||||||
props: {
|
|
||||||
isRadio: true, // ?
|
|
||||||
groupId: 'MoreTools',
|
|
||||||
primary: _createActionButton(
|
|
||||||
'Reset',
|
|
||||||
'tool-reset',
|
|
||||||
'Reset View',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'resetViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Reset'
|
|
||||||
),
|
|
||||||
secondary: {
|
|
||||||
icon: 'chevron-down',
|
|
||||||
label: '',
|
|
||||||
isActive: true,
|
|
||||||
tooltip: 'More Tools',
|
|
||||||
},
|
|
||||||
items: [
|
|
||||||
_createActionButton(
|
|
||||||
'Reset',
|
|
||||||
'tool-reset',
|
|
||||||
'Reset View',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'resetViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Reset'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'rotate-right',
|
|
||||||
'tool-rotate-right',
|
|
||||||
'Rotate Right',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'rotateViewportCW',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Rotate +90'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'flip-horizontal',
|
|
||||||
'tool-flip-horizontal',
|
|
||||||
'Flip Horizontally',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'flipViewportHorizontal',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Flip Horizontally'
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'StackImageSync',
|
|
||||||
'link',
|
|
||||||
'Stack Image Sync',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'toggleStackImageSync',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Enable position synchronization on stack viewports',
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
[EVENTS.STACK_VIEWPORT_NEW_STACK]: {
|
|
||||||
commandName: 'toggleStackImageSync',
|
|
||||||
commandOptions: { toggledState: true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'ReferenceLines',
|
|
||||||
'tool-referenceLines', // change this with the new icon
|
|
||||||
'Reference Lines',
|
|
||||||
ReferenceLinesCommands,
|
|
||||||
'Show Reference Lines',
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
[EVENTS.STACK_VIEWPORT_NEW_STACK]: ReferenceLinesCommands,
|
|
||||||
[EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesCommands,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'StackScroll',
|
|
||||||
'tool-stack-scroll',
|
|
||||||
'Stack Scroll',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'StackScroll',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Stack Scroll'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'invert',
|
|
||||||
'tool-invert',
|
|
||||||
'Invert',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'invertViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Invert Colors'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Probe',
|
|
||||||
'tool-probe',
|
|
||||||
'Probe',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'DragProbe',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Probe'
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'cine',
|
|
||||||
'tool-cine',
|
|
||||||
'Cine',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'toggleCine',
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Cine'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Angle',
|
|
||||||
'tool-angle',
|
|
||||||
'Angle',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'Angle',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Angle'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Magnify',
|
|
||||||
'tool-magnify',
|
|
||||||
'Magnify',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'Magnify',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Magnify'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Rectangle',
|
|
||||||
'tool-rectangle',
|
|
||||||
'Rectangle',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'RectangleROI',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Rectangle'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'TagBrowser',
|
|
||||||
'list-bullets',
|
|
||||||
'Dicom Tag Browser',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'openDICOMTagViewer',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'DEFAULT',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Dicom Tag Browser'
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default toolbarButtons;
|
export default toolbarButtons;
|
||||||
|
|||||||
@ -2,11 +2,16 @@ import { hotkeys } from '@ohif/core';
|
|||||||
import toolbarButtons from './toolbarButtons';
|
import toolbarButtons from './toolbarButtons';
|
||||||
import { id } from './id';
|
import { id } from './id';
|
||||||
import initToolGroups from './initToolGroups';
|
import initToolGroups from './initToolGroups';
|
||||||
|
import moreTools from './moreTools';
|
||||||
|
import moreToolsMpr from './moreToolsMpr';
|
||||||
|
|
||||||
// Allow this mode by excluding non-imaging modalities such as SR, SEG
|
// Allow this mode by excluding non-imaging modalities such as SR, SEG
|
||||||
// Also, SM is not a simple imaging modalities, so exclude it.
|
// Also, SM is not a simple imaging modalities, so exclude it.
|
||||||
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG', 'RTSTRUCT'];
|
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG', 'RTSTRUCT'];
|
||||||
|
|
||||||
|
const DEFAULT_TOOL_GROUP_ID = 'default';
|
||||||
|
const MPR_TOOL_GROUP_ID = 'mpr';
|
||||||
|
|
||||||
const ohif = {
|
const ohif = {
|
||||||
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
|
||||||
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
|
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
|
||||||
@ -83,10 +88,9 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
initToolGroups(extensionManager, toolGroupService, commandsManager);
|
initToolGroups(extensionManager, toolGroupService, commandsManager);
|
||||||
|
|
||||||
let unsubscribe;
|
let unsubscribe;
|
||||||
|
toolbarService.setDefaultTool({
|
||||||
const activateTool = () => {
|
|
||||||
toolbarService.recordInteraction({
|
|
||||||
groupId: 'WindowLevel',
|
groupId: 'WindowLevel',
|
||||||
|
itemId: 'WindowLevel',
|
||||||
interactionType: 'tool',
|
interactionType: 'tool',
|
||||||
commands: [
|
commands: [
|
||||||
{
|
{
|
||||||
@ -99,6 +103,9 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const activateTool = () => {
|
||||||
|
toolbarService.recordInteraction(toolbarService.getDefaultTool());
|
||||||
|
|
||||||
// We don't need to reset the active tool whenever a viewport is getting
|
// We don't need to reset the active tool whenever a viewport is getting
|
||||||
// added to the toolGroup.
|
// added to the toolGroup.
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
@ -112,8 +119,18 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
));
|
));
|
||||||
|
|
||||||
toolbarService.init(extensionManager);
|
toolbarService.init(extensionManager);
|
||||||
toolbarService.addButtons(toolbarButtons);
|
toolbarService.addButtons([...toolbarButtons, ...moreTools, ...moreToolsMpr]);
|
||||||
toolbarService.createButtonSection('primary', [
|
toolbarService.createButtonSection(DEFAULT_TOOL_GROUP_ID, [
|
||||||
|
'MeasurementTools',
|
||||||
|
'Zoom',
|
||||||
|
'WindowLevel',
|
||||||
|
'Pan',
|
||||||
|
'Capture',
|
||||||
|
'Layout',
|
||||||
|
'MPR',
|
||||||
|
'MoreTools',
|
||||||
|
]);
|
||||||
|
toolbarService.createButtonSection(MPR_TOOL_GROUP_ID, [
|
||||||
'MeasurementTools',
|
'MeasurementTools',
|
||||||
'Zoom',
|
'Zoom',
|
||||||
'WindowLevel',
|
'WindowLevel',
|
||||||
@ -122,7 +139,7 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
'Layout',
|
'Layout',
|
||||||
'MPR',
|
'MPR',
|
||||||
'Crosshairs',
|
'Crosshairs',
|
||||||
'MoreTools',
|
'MoreToolsMpr',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
customizationService.addModeCustomizations([
|
customizationService.addModeCustomizations([
|
||||||
|
|||||||
298
modes/longitudinal/src/moreTools.ts
Normal file
298
modes/longitudinal/src/moreTools.ts
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
import type { RunCommand } from '@ohif/core/types';
|
||||||
|
import { EVENTS } from '@cornerstonejs/core';
|
||||||
|
import { ToolbarService } from '@ohif/core';
|
||||||
|
|
||||||
|
const ReferenceLinesCommands: RunCommand = [
|
||||||
|
{
|
||||||
|
commandName: 'setSourceViewportForReferenceLinesTool',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'ReferenceLines',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const moreTools = [
|
||||||
|
{
|
||||||
|
id: 'MoreTools',
|
||||||
|
type: 'ohif.splitButton',
|
||||||
|
props: {
|
||||||
|
isRadio: true, // ?
|
||||||
|
groupId: 'MoreTools',
|
||||||
|
primary: ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
secondary: {
|
||||||
|
icon: 'chevron-down',
|
||||||
|
label: '',
|
||||||
|
isActive: true,
|
||||||
|
tooltip: 'More Tools',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'rotate-right',
|
||||||
|
'tool-rotate-right',
|
||||||
|
'Rotate Right',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'rotateViewportCW',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rotate +90'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'flip-horizontal',
|
||||||
|
'tool-flip-horizontal',
|
||||||
|
'Flip Horizontally',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'flipViewportHorizontal',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Flip Horizontal'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'StackImageSync',
|
||||||
|
'link',
|
||||||
|
'Stack Image Sync',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Enable position synchronization on stack viewports',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: {
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
commandOptions: { toggledState: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'ReferenceLines',
|
||||||
|
'tool-referenceLines', // change this with the new icon
|
||||||
|
'Reference Lines',
|
||||||
|
ReferenceLinesCommands,
|
||||||
|
'Show Reference Lines',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: ReferenceLinesCommands,
|
||||||
|
[EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesCommands,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'ImageOverlayViewer',
|
||||||
|
'toggle-dicom-overlay',
|
||||||
|
'Image Overlay',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'ImageOverlayViewer',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Image Overlay',
|
||||||
|
{ isActive: true }
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'StackScroll',
|
||||||
|
'tool-stack-scroll',
|
||||||
|
'Stack Scroll',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'StackScroll',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Stack Scroll'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'invert',
|
||||||
|
'tool-invert',
|
||||||
|
'Invert',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'invertViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Invert Colors'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Probe',
|
||||||
|
'tool-probe',
|
||||||
|
'Probe',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'DragProbe',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Probe'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'cine',
|
||||||
|
'tool-cine',
|
||||||
|
'Cine',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleCine',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Cine'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Angle',
|
||||||
|
'tool-angle',
|
||||||
|
'Angle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Angle',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Angle'
|
||||||
|
),
|
||||||
|
|
||||||
|
// Next two tools can be added once icons are added
|
||||||
|
// ToolbarService._createToolButton(
|
||||||
|
// 'Cobb Angle',
|
||||||
|
// 'tool-cobb-angle',
|
||||||
|
// 'Cobb Angle',
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// commandName: 'setToolActive',
|
||||||
|
// commandOptions: {
|
||||||
|
// toolName: 'CobbAngle',
|
||||||
|
// },
|
||||||
|
// context: 'CORNERSTONE',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// 'Cobb Angle'
|
||||||
|
// ),
|
||||||
|
// ToolbarService._createToolButton(
|
||||||
|
// 'Planar Freehand ROI',
|
||||||
|
// 'tool-freehand',
|
||||||
|
// 'PlanarFreehandROI',
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// commandName: 'setToolActive',
|
||||||
|
// commandOptions: {
|
||||||
|
// toolName: 'PlanarFreehandROI',
|
||||||
|
// },
|
||||||
|
// context: 'CORNERSTONE',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// 'Planar Freehand ROI'
|
||||||
|
// ),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Magnify',
|
||||||
|
'tool-magnify',
|
||||||
|
'Magnify',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Magnify',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Magnify'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Rectangle',
|
||||||
|
'tool-rectangle',
|
||||||
|
'Rectangle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'RectangleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rectangle'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'CalibrationLine',
|
||||||
|
'tool-calibration',
|
||||||
|
'Calibration',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CalibrationLine',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Calibration Line'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'TagBrowser',
|
||||||
|
'list-bullets',
|
||||||
|
'Dicom Tag Browser',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'openDICOMTagViewer',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'DEFAULT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Dicom Tag Browser'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default moreTools;
|
||||||
242
modes/longitudinal/src/moreToolsMpr.ts
Normal file
242
modes/longitudinal/src/moreToolsMpr.ts
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
import type { RunCommand } from '@ohif/core/types';
|
||||||
|
import { EVENTS } from '@cornerstonejs/core';
|
||||||
|
import { ToolbarService } from '@ohif/core';
|
||||||
|
|
||||||
|
const ReferenceLinesCommands: RunCommand = [
|
||||||
|
{
|
||||||
|
commandName: 'setSourceViewportForReferenceLinesTool',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'ReferenceLines',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const moreToolsMpr = [
|
||||||
|
{
|
||||||
|
id: 'MoreToolsMpr',
|
||||||
|
type: 'ohif.splitButton',
|
||||||
|
props: {
|
||||||
|
isRadio: true, // ?
|
||||||
|
groupId: 'MoreTools',
|
||||||
|
primary: ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
secondary: {
|
||||||
|
icon: 'chevron-down',
|
||||||
|
label: '',
|
||||||
|
isActive: true,
|
||||||
|
tooltip: 'More Tools',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'Reset',
|
||||||
|
'tool-reset',
|
||||||
|
'Reset View',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'resetViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Reset'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'StackImageSync',
|
||||||
|
'link',
|
||||||
|
'Stack Image Sync',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Enable position synchronization on stack viewports',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: {
|
||||||
|
commandName: 'toggleStackImageSync',
|
||||||
|
commandOptions: { toggledState: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'ReferenceLines',
|
||||||
|
'tool-referenceLines', // change this with the new icon
|
||||||
|
'Reference Lines',
|
||||||
|
ReferenceLinesCommands,
|
||||||
|
'Show Reference Lines',
|
||||||
|
{
|
||||||
|
listeners: {
|
||||||
|
[EVENTS.STACK_VIEWPORT_NEW_STACK]: ReferenceLinesCommands,
|
||||||
|
[EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesCommands,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'ImageOverlayViewer',
|
||||||
|
'toggle-dicom-overlay',
|
||||||
|
'Image Overlay',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'ImageOverlayViewer',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Image Overlay',
|
||||||
|
{ isActive: true }
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'StackScroll',
|
||||||
|
'tool-stack-scroll',
|
||||||
|
'Stack Scroll',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'StackScroll',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Stack Scroll'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'invert',
|
||||||
|
'tool-invert',
|
||||||
|
'Invert',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'invertViewport',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Invert Colors'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Probe',
|
||||||
|
'tool-probe',
|
||||||
|
'Probe',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'DragProbe',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Probe'
|
||||||
|
),
|
||||||
|
ToolbarService._createToggleButton(
|
||||||
|
'cine',
|
||||||
|
'tool-cine',
|
||||||
|
'Cine',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'toggleCine',
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Cine'
|
||||||
|
),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Angle',
|
||||||
|
'tool-angle',
|
||||||
|
'Angle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'Angle',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Angle'
|
||||||
|
),
|
||||||
|
|
||||||
|
// Next two tools can be added once icons are added
|
||||||
|
// ToolbarService._createToolButton(
|
||||||
|
// 'Cobb Angle',
|
||||||
|
// 'tool-cobb-angle',
|
||||||
|
// 'Cobb Angle',
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// commandName: 'setToolActive',
|
||||||
|
// commandOptions: {
|
||||||
|
// toolName: 'CobbAngle',
|
||||||
|
// },
|
||||||
|
// context: 'CORNERSTONE',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// 'Cobb Angle'
|
||||||
|
// ),
|
||||||
|
// ToolbarService._createToolButton(
|
||||||
|
// 'Planar Freehand ROI',
|
||||||
|
// 'tool-freehand',
|
||||||
|
// 'PlanarFreehandROI',
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// commandName: 'setToolActive',
|
||||||
|
// commandOptions: {
|
||||||
|
// toolName: 'PlanarFreehandROI',
|
||||||
|
// },
|
||||||
|
// context: 'CORNERSTONE',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// 'Planar Freehand ROI'
|
||||||
|
// ),
|
||||||
|
ToolbarService._createToolButton(
|
||||||
|
'Rectangle',
|
||||||
|
'tool-rectangle',
|
||||||
|
'Rectangle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'RectangleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Rectangle'
|
||||||
|
),
|
||||||
|
ToolbarService._createActionButton(
|
||||||
|
'TagBrowser',
|
||||||
|
'list-bullets',
|
||||||
|
'Dicom Tag Browser',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'openDICOMTagViewer',
|
||||||
|
commandOptions: {},
|
||||||
|
context: 'DEFAULT',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Dicom Tag Browser'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default moreToolsMpr;
|
||||||
@ -6,15 +6,10 @@ import {
|
|||||||
WindowLevelMenuItem,
|
WindowLevelMenuItem,
|
||||||
} from '@ohif/ui';
|
} from '@ohif/ui';
|
||||||
import { defaults, ToolbarService } from '@ohif/core';
|
import { defaults, ToolbarService } from '@ohif/core';
|
||||||
import type { Button, RunCommand } from '@ohif/core/types';
|
import type { Button } from '@ohif/core/types';
|
||||||
import { EVENTS } from '@cornerstonejs/core';
|
|
||||||
|
|
||||||
const { windowLevelPresets } = defaults;
|
const { windowLevelPresets } = defaults;
|
||||||
|
|
||||||
const _createActionButton = ToolbarService._createButton.bind(null, 'action');
|
|
||||||
const _createToggleButton = ToolbarService._createButton.bind(null, 'toggle');
|
|
||||||
const _createToolButton = ToolbarService._createButton.bind(null, 'tool');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {*} preset - preset number (from above import)
|
* @param {*} preset - preset number (from above import)
|
||||||
@ -59,20 +54,6 @@ function _createSetToolActiveCommands(toolName) {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReferenceLinesCommands: RunCommand = [
|
|
||||||
{
|
|
||||||
commandName: 'setSourceViewportForReferenceLinesTool',
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'ReferenceLines',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const toolbarButtons: Button[] = [
|
const toolbarButtons: Button[] = [
|
||||||
// Measurement
|
// Measurement
|
||||||
{
|
{
|
||||||
@ -82,7 +63,7 @@ const toolbarButtons: Button[] = [
|
|||||||
groupId: 'MeasurementTools',
|
groupId: 'MeasurementTools',
|
||||||
isRadio: true, // ?
|
isRadio: true, // ?
|
||||||
// Switch?
|
// Switch?
|
||||||
primary: _createToolButton(
|
primary: ToolbarService._createToolButton(
|
||||||
'Length',
|
'Length',
|
||||||
'tool-length',
|
'tool-length',
|
||||||
'Length',
|
'Length',
|
||||||
@ -113,7 +94,7 @@ const toolbarButtons: Button[] = [
|
|||||||
tooltip: 'More Measure Tools',
|
tooltip: 'More Measure Tools',
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'Length',
|
'Length',
|
||||||
'tool-length',
|
'tool-length',
|
||||||
'Length',
|
'Length',
|
||||||
@ -137,7 +118,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Length Tool'
|
'Length Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
'tool-bidirectional',
|
'tool-bidirectional',
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
@ -160,7 +141,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Bidirectional Tool'
|
'Bidirectional Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'ArrowAnnotate',
|
'ArrowAnnotate',
|
||||||
'tool-annotate',
|
'tool-annotate',
|
||||||
'Annotation',
|
'Annotation',
|
||||||
@ -183,7 +164,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Arrow Annotate'
|
'Arrow Annotate'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'EllipticalROI',
|
'EllipticalROI',
|
||||||
'tool-elipse',
|
'tool-elipse',
|
||||||
'Ellipse',
|
'Ellipse',
|
||||||
@ -206,7 +187,7 @@ const toolbarButtons: Button[] = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
_createToolButton(
|
ToolbarService._createToolButton(
|
||||||
'CircleROI',
|
'CircleROI',
|
||||||
'tool-circle',
|
'tool-circle',
|
||||||
'Circle',
|
'Circle',
|
||||||
@ -249,7 +230,7 @@ const toolbarButtons: Button[] = [
|
|||||||
type: 'ohif.splitButton',
|
type: 'ohif.splitButton',
|
||||||
props: {
|
props: {
|
||||||
groupId: 'WindowLevel',
|
groupId: 'WindowLevel',
|
||||||
primary: _createToolButton(
|
primary: ToolbarService._createToolButton(
|
||||||
'WindowLevel',
|
'WindowLevel',
|
||||||
'tool-window-level',
|
'tool-window-level',
|
||||||
'Window Level',
|
'Window Level',
|
||||||
@ -354,282 +335,6 @@ const toolbarButtons: Button[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
// More...
|
// More...
|
||||||
{
|
|
||||||
id: 'MoreTools',
|
|
||||||
type: 'ohif.splitButton',
|
|
||||||
props: {
|
|
||||||
isRadio: true, // ?
|
|
||||||
groupId: 'MoreTools',
|
|
||||||
primary: _createActionButton(
|
|
||||||
'Reset',
|
|
||||||
'tool-reset',
|
|
||||||
'Reset View',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'resetViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Reset'
|
|
||||||
),
|
|
||||||
secondary: {
|
|
||||||
icon: 'chevron-down',
|
|
||||||
label: '',
|
|
||||||
isActive: true,
|
|
||||||
tooltip: 'More Tools',
|
|
||||||
},
|
|
||||||
items: [
|
|
||||||
_createActionButton(
|
|
||||||
'Reset',
|
|
||||||
'tool-reset',
|
|
||||||
'Reset View',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'resetViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Reset'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'rotate-right',
|
|
||||||
'tool-rotate-right',
|
|
||||||
'Rotate Right',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'rotateViewportCW',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Rotate +90'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'flip-horizontal',
|
|
||||||
'tool-flip-horizontal',
|
|
||||||
'Flip Horizontally',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'flipViewportHorizontal',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Flip Horizontal'
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'StackImageSync',
|
|
||||||
'link',
|
|
||||||
'Stack Image Sync',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'toggleStackImageSync',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Enable position synchronization on stack viewports',
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
[EVENTS.STACK_VIEWPORT_NEW_STACK]: {
|
|
||||||
commandName: 'toggleStackImageSync',
|
|
||||||
commandOptions: { toggledState: true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'ReferenceLines',
|
|
||||||
'tool-referenceLines', // change this with the new icon
|
|
||||||
'Reference Lines',
|
|
||||||
ReferenceLinesCommands,
|
|
||||||
'Show Reference Lines',
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
[EVENTS.STACK_VIEWPORT_NEW_STACK]: ReferenceLinesCommands,
|
|
||||||
[EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesCommands,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'ImageOverlayViewer',
|
|
||||||
'toggle-dicom-overlay',
|
|
||||||
'Image Overlay',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'ImageOverlayViewer',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Image Overlay',
|
|
||||||
{ isActive: true }
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'StackScroll',
|
|
||||||
'tool-stack-scroll',
|
|
||||||
'Stack Scroll',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'StackScroll',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Stack Scroll'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'invert',
|
|
||||||
'tool-invert',
|
|
||||||
'Invert',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'invertViewport',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Invert Colors'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Probe',
|
|
||||||
'tool-probe',
|
|
||||||
'Probe',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'DragProbe',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Probe'
|
|
||||||
),
|
|
||||||
_createToggleButton(
|
|
||||||
'cine',
|
|
||||||
'tool-cine',
|
|
||||||
'Cine',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'toggleCine',
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Cine'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Angle',
|
|
||||||
'tool-angle',
|
|
||||||
'Angle',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'Angle',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Angle'
|
|
||||||
),
|
|
||||||
|
|
||||||
// Next two tools can be added once icons are added
|
|
||||||
// _createToolButton(
|
|
||||||
// 'Cobb Angle',
|
|
||||||
// 'tool-cobb-angle',
|
|
||||||
// 'Cobb Angle',
|
|
||||||
// [
|
|
||||||
// {
|
|
||||||
// commandName: 'setToolActive',
|
|
||||||
// commandOptions: {
|
|
||||||
// toolName: 'CobbAngle',
|
|
||||||
// },
|
|
||||||
// context: 'CORNERSTONE',
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// 'Cobb Angle'
|
|
||||||
// ),
|
|
||||||
// _createToolButton(
|
|
||||||
// 'Planar Freehand ROI',
|
|
||||||
// 'tool-freehand',
|
|
||||||
// 'PlanarFreehandROI',
|
|
||||||
// [
|
|
||||||
// {
|
|
||||||
// commandName: 'setToolActive',
|
|
||||||
// commandOptions: {
|
|
||||||
// toolName: 'PlanarFreehandROI',
|
|
||||||
// },
|
|
||||||
// context: 'CORNERSTONE',
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// 'Planar Freehand ROI'
|
|
||||||
// ),
|
|
||||||
_createToolButton(
|
|
||||||
'Magnify',
|
|
||||||
'tool-magnify',
|
|
||||||
'Magnify',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'Magnify',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Magnify'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'Rectangle',
|
|
||||||
'tool-rectangle',
|
|
||||||
'Rectangle',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'RectangleROI',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Rectangle'
|
|
||||||
),
|
|
||||||
_createToolButton(
|
|
||||||
'CalibrationLine',
|
|
||||||
'tool-calibration',
|
|
||||||
'Calibration',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'setToolActive',
|
|
||||||
commandOptions: {
|
|
||||||
toolName: 'CalibrationLine',
|
|
||||||
},
|
|
||||||
context: 'CORNERSTONE',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Calibration Line'
|
|
||||||
),
|
|
||||||
_createActionButton(
|
|
||||||
'TagBrowser',
|
|
||||||
'list-bullets',
|
|
||||||
'Dicom Tag Browser',
|
|
||||||
[
|
|
||||||
{
|
|
||||||
commandName: 'openDICOMTagViewer',
|
|
||||||
commandOptions: {},
|
|
||||||
context: 'DEFAULT',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'Dicom Tag Browser'
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default toolbarButtons;
|
export default toolbarButtons;
|
||||||
|
|||||||
@ -48,6 +48,7 @@ describe('OHIF Measurement Panel', function () {
|
|||||||
|
|
||||||
cy.scrollToIndex(13);
|
cy.scrollToIndex(13);
|
||||||
|
|
||||||
|
// Reset to default tool so that the new add length works
|
||||||
cy.addLengthMeasurement([100, 100], [200, 200]); //Adding measurement in the viewport
|
cy.addLengthMeasurement([100, 100], [200, 200]); //Adding measurement in the viewport
|
||||||
|
|
||||||
cy.get('@viewportInfoTopRight').should('contains.text', '(14/');
|
cy.get('@viewportInfoTopRight').should('contains.text', '(14/');
|
||||||
|
|||||||
@ -88,19 +88,7 @@ describe('OHIF MPR', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly render Crosshairs for MPR', () => {
|
it('should correctly render Crosshairs for MPR', () => {
|
||||||
cy.wait(250);
|
cy.get('[data-cy="Crosshairs"]').should('not.exist');
|
||||||
|
|
||||||
cy.get('[data-cy="Crosshairs"]').click();
|
|
||||||
cy.window()
|
|
||||||
.its('cornerstoneTools')
|
|
||||||
.then(cornerstoneTools => {
|
|
||||||
const state = cornerstoneTools.annotation.state.getAnnotationManager();
|
|
||||||
|
|
||||||
const fORMap = state.annotations;
|
|
||||||
// it should not have crosshairs yet
|
|
||||||
expect(Object.keys(fORMap)).to.have.length(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick();
|
cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick();
|
||||||
cy.get('[data-cy="MPR"]').click();
|
cy.get('[data-cy="MPR"]').click();
|
||||||
cy.get('[data-cy="Crosshairs"]').click();
|
cy.get('[data-cy="Crosshairs"]').click();
|
||||||
@ -131,4 +119,19 @@ describe('OHIF MPR', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should activate window level when the active Crosshairs tool for MPR is clicked', () => {
|
||||||
|
cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick();
|
||||||
|
cy.get('[data-cy="MPR"]').click();
|
||||||
|
cy.get('[data-cy="Crosshairs"]').click();
|
||||||
|
|
||||||
|
// wait for the crosshairs tool to be active
|
||||||
|
cy.get('[data-cy="Crosshairs"].active');
|
||||||
|
|
||||||
|
// Click the crosshairs button to deactivate it.
|
||||||
|
cy.get('[data-cy="Crosshairs"]').click();
|
||||||
|
|
||||||
|
// wait for the window level button to be active
|
||||||
|
cy.get('[data-cy="WindowLevel-split-button-primary"].active');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -262,7 +262,14 @@ Cypress.Commands.add(
|
|||||||
cy.get('@measurementToolsBtnPrimary').as('lengthButton');
|
cy.get('@measurementToolsBtnPrimary').as('lengthButton');
|
||||||
|
|
||||||
cy.get('@lengthButton').should('have.attr', 'data-tool', 'Length');
|
cy.get('@lengthButton').should('have.attr', 'data-tool', 'Length');
|
||||||
cy.get('@lengthButton').click();
|
|
||||||
|
cy.get('@lengthButton').then(button => {
|
||||||
|
// Only click the length tool if it is not active, in case the length tool is set up to
|
||||||
|
// toggle to inactive.
|
||||||
|
if (!button.is('.active')) {
|
||||||
|
cy.wrap(button).click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
cy.get('@lengthButton').should('have.class', 'active');
|
cy.get('@lengthButton').should('have.class', 'active');
|
||||||
|
|
||||||
|
|||||||
@ -63,12 +63,17 @@ export default class ToolbarService extends PubSubService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static _createActionButton = ToolbarService._createButton.bind(null, 'action');
|
||||||
|
public static _createToggleButton = ToolbarService._createButton.bind(null, 'toggle');
|
||||||
|
public static _createToolButton = ToolbarService._createButton.bind(null, 'tool');
|
||||||
|
|
||||||
buttons: Record<string, Button> = {};
|
buttons: Record<string, Button> = {};
|
||||||
state: {
|
state: {
|
||||||
primaryToolId: string;
|
primaryToolId: string;
|
||||||
toggles: Record<string, boolean>;
|
toggles: Record<string, boolean>;
|
||||||
groups: Record<string, unknown>;
|
groups: Record<string, unknown>;
|
||||||
} = { primaryToolId: 'WindowLevel', toggles: {}, groups: {} };
|
} = { primaryToolId: '', toggles: {}, groups: {} };
|
||||||
|
|
||||||
buttonSections: Record<string, unknown> = {
|
buttonSections: Record<string, unknown> = {
|
||||||
/**
|
/**
|
||||||
* primary: ['Zoom', 'Wwwc'],
|
* primary: ['Zoom', 'Wwwc'],
|
||||||
@ -78,6 +83,8 @@ export default class ToolbarService extends PubSubService {
|
|||||||
_commandsManager: CommandsManager;
|
_commandsManager: CommandsManager;
|
||||||
extensionManager: ExtensionManager;
|
extensionManager: ExtensionManager;
|
||||||
|
|
||||||
|
defaultTool: Record<string, unknown>;
|
||||||
|
|
||||||
constructor(commandsManager: CommandsManager) {
|
constructor(commandsManager: CommandsManager) {
|
||||||
super(EVENTS);
|
super(EVENTS);
|
||||||
this._commandsManager = commandsManager;
|
this._commandsManager = commandsManager;
|
||||||
@ -103,6 +110,19 @@ export default class ToolbarService extends PubSubService {
|
|||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default tool that will be activated whenever the primary tool is
|
||||||
|
* deactivated without activating another/different tool.
|
||||||
|
* @param interaction the interaction command that will set the default tool active
|
||||||
|
*/
|
||||||
|
public setDefaultTool(interaction) {
|
||||||
|
this.defaultTool = interaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDefaultTool() {
|
||||||
|
return this.defaultTool;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {*} interaction - can be undefined to run nothing
|
* @param {*} interaction - can be undefined to run nothing
|
||||||
@ -125,25 +145,20 @@ export default class ToolbarService extends PubSubService {
|
|||||||
|
|
||||||
switch (interactionType) {
|
switch (interactionType) {
|
||||||
case 'action': {
|
case 'action': {
|
||||||
commands.forEach(({ commandName, commandOptions, context }) => {
|
commandsManager.run(commands, options);
|
||||||
if (commandName) {
|
|
||||||
commandsManager.runCommand(
|
|
||||||
commandName,
|
|
||||||
{
|
|
||||||
...commandOptions,
|
|
||||||
...options,
|
|
||||||
},
|
|
||||||
context
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'tool': {
|
case 'tool': {
|
||||||
try {
|
try {
|
||||||
commands.forEach(({ commandName = 'setToolActive', commandOptions, context }) => {
|
const alternateInteraction =
|
||||||
commandsManager.runCommand(commandName, commandOptions, context);
|
this.state.primaryToolId === itemId &&
|
||||||
});
|
this.defaultTool?.itemId !== itemId &&
|
||||||
|
this.getDefaultTool();
|
||||||
|
if (alternateInteraction) {
|
||||||
|
// Allow toggling the mode off
|
||||||
|
return this.recordInteraction(alternateInteraction, options);
|
||||||
|
}
|
||||||
|
commandsManager.run(commands, options);
|
||||||
|
|
||||||
// only set the primary tool if no error was thrown.
|
// only set the primary tool if no error was thrown.
|
||||||
// if the itemId is not undefined use it; otherwise, set the first tool in
|
// if the itemId is not undefined use it; otherwise, set the first tool in
|
||||||
@ -312,21 +327,27 @@ export default class ToolbarService extends PubSubService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Finds a button section by it's name, then maps the list of string name
|
* Finds a button section by it's name/tool group id, then maps the list of string name
|
||||||
* identifiers to schema/values that can be used to render the buttons.
|
* identifiers to schema/values that can be used to render the buttons.
|
||||||
*
|
*
|
||||||
* @param {string} key
|
* @param toolGroupId - the tool group id
|
||||||
* @param {*} props
|
* @param props - optional properties to apply to every button of the section
|
||||||
|
* @param defaultToolGroupId - the fallback section to return if the given toolGroupId section is not available
|
||||||
*/
|
*/
|
||||||
getButtonSection(key, props) {
|
getButtonSection(
|
||||||
const buttonSectionIds = this.buttonSections[key];
|
toolGroupId: string,
|
||||||
|
props?: Record<string, unknown>,
|
||||||
|
defaultToolGroupId = 'primary'
|
||||||
|
) {
|
||||||
|
const buttonSectionIds =
|
||||||
|
this.buttonSections[toolGroupId] || this.buttonSections[defaultToolGroupId];
|
||||||
const buttonsInSection = [];
|
const buttonsInSection = [];
|
||||||
|
|
||||||
if (buttonSectionIds && buttonSectionIds.length !== 0) {
|
if (buttonSectionIds && buttonSectionIds.length !== 0) {
|
||||||
buttonSectionIds.forEach(btnId => {
|
buttonSectionIds.forEach(btnId => {
|
||||||
const btn = this.buttons[btnId];
|
const btn = this.buttons[btnId];
|
||||||
const metadata = {};
|
const metadata = {};
|
||||||
const mappedBtn = this._mapButtonToDisplay(btn, key, metadata, props);
|
const mappedBtn = this._mapButtonToDisplay(btn, toolGroupId, metadata, props);
|
||||||
|
|
||||||
buttonsInSection.push(mappedBtn);
|
buttonsInSection.push(mappedBtn);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -46,6 +46,8 @@ button is clicked by the user.
|
|||||||
|
|
||||||
- `getActiveTools`: returns the active tool + all the toggled-on tools
|
- `getActiveTools`: returns the active tool + all the toggled-on tools
|
||||||
|
|
||||||
|
- `setDefaultTool`: sets the default tool that will be activated whenever the primary tool is deactivated without activating another/different tool
|
||||||
|
|
||||||
## State
|
## State
|
||||||
|
|
||||||
ToolBarService has an internal state that gets updated per tool interaction and
|
ToolBarService has an internal state that gets updated per tool interaction and
|
||||||
|
|||||||
@ -33,6 +33,7 @@ is expected to support, [check out it's interface in `@ohif/core`][interface]
|
|||||||
| `getNumViewportPanes()` | Gets the number of visible viewport panes |
|
| `getNumViewportPanes()` | Gets the number of visible viewport panes |
|
||||||
| `getLayoutOptionsFromState(gridState)` | Utility method that produces a `ViewportLayoutOptions` based on the passed in state|
|
| `getLayoutOptionsFromState(gridState)` | Utility method that produces a `ViewportLayoutOptions` based on the passed in state|
|
||||||
| `getActiveViewportId()` | Returns the viewport Id of the active viewport in the grid|
|
| `getActiveViewportId()` | Returns the viewport Id of the active viewport in the grid|
|
||||||
|
| `getActiveViewportOptionByKey(key)` | Gets the specified viewport option field (key) for the active viewport |
|
||||||
|
|
||||||
## Implementations
|
## Implementations
|
||||||
|
|
||||||
|
|||||||
@ -300,6 +300,11 @@ export function ViewportGridProvider({ children, service }) {
|
|||||||
return viewportGridState;
|
return viewportGridState;
|
||||||
}, [viewportGridState]);
|
}, [viewportGridState]);
|
||||||
|
|
||||||
|
const getActiveViewportOptionByKey = (key: string) => {
|
||||||
|
const { viewports, activeViewportId } = viewportGridState;
|
||||||
|
return viewports.get(activeViewportId)?.viewportOptions?.[key];
|
||||||
|
};
|
||||||
|
|
||||||
const setActiveViewportId = useCallback(
|
const setActiveViewportId = useCallback(
|
||||||
index => dispatch({ type: 'SET_ACTIVE_VIEWPORT_ID', payload: index }),
|
index => dispatch({ type: 'SET_ACTIVE_VIEWPORT_ID', payload: index }),
|
||||||
[dispatch]
|
[dispatch]
|
||||||
@ -400,6 +405,7 @@ export function ViewportGridProvider({ children, service }) {
|
|||||||
reset: () => service.reset(),
|
reset: () => service.reset(),
|
||||||
set: gridLayoutState => service.setState(gridLayoutState), // run it through the service itself since we want to publish events
|
set: gridLayoutState => service.setState(gridLayoutState), // run it through the service itself since we want to publish events
|
||||||
getNumViewportPanes,
|
getNumViewportPanes,
|
||||||
|
getActiveViewportOptionByKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user