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:
Bill WallaceandJoe Boccanfuso authored and GitHub committed 2023-10-25 13:08:12 -04:00
1 parent 2145b42920
commit dd6d9768bb
18 files changed
+1096 -628

No files matched your search

+33 -16
View File
@@ -2,11 +2,16 @@ import { hotkeys } from '@ohif/core';
import toolbarButtons from './toolbarButtons';
import { id } from './id';
import initToolGroups from './initToolGroups';
import moreTools from './moreTools';
import moreToolsMpr from './moreToolsMpr';
// Allow this mode by excluding non-imaging modalities such as SR, SEG
// Also, SM is not a simple imaging modalities, so exclude it.
const NON_IMAGE_MODALITIES = ['SM', 'ECG', 'SR', 'SEG'];
const DEFAULT_TOOL_GROUP_ID = 'default';
const MPR_TOOL_GROUP_ID = 'mpr';
const ohif = {
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
@@ -77,21 +82,23 @@ function modeFactory() {
]);
let unsubscribe;
toolbarService.setDefaultTool({
groupId: 'WindowLevel',
itemId: 'WindowLevel',
interactionType: 'tool',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
});
const activateTool = () => {
toolbarService.recordInteraction({
groupId: 'WindowLevel',
interactionType: 'tool',
commands: [
{
commandName: 'setToolActive',
commandOptions: {
toolName: 'WindowLevel',
},
context: 'CORNERSTONE',
},
],
});
toolbarService.recordInteraction(toolbarService.getDefaultTool());
// We don't need to reset the active tool whenever a viewport is getting
// added to the toolGroup.
@@ -106,8 +113,18 @@ function modeFactory() {
));
toolbarService.init(extensionManager);
toolbarService.addButtons(toolbarButtons);
toolbarService.createButtonSection('primary', [
toolbarService.addButtons([...toolbarButtons, ...moreTools, ...moreToolsMpr]);
toolbarService.createButtonSection(DEFAULT_TOOL_GROUP_ID, [
'MeasurementTools',
'Zoom',
'WindowLevel',
'Pan',
'Capture',
'Layout',
'MPR',
'MoreTools',
]);
toolbarService.createButtonSection(MPR_TOOL_GROUP_ID, [
'MeasurementTools',
'Zoom',
'WindowLevel',
@@ -116,7 +133,7 @@ function modeFactory() {
'Layout',
'MPR',
'Crosshairs',
'MoreTools',
'MoreToolsMpr',
]);
},
onModeExit: ({ servicesManager }) => {
+231
View 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
View 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;
+9 -244
View File
@@ -5,16 +5,11 @@ import {
// ListMenu,
WindowLevelMenuItem,
} from '@ohif/ui';
import { defaults, ToolbarService } from '@ohif/core';
import type { Button, RunCommand } from '@ohif/core/types';
import { EVENTS } from '@cornerstonejs/core';
import { ToolbarService, defaults } from '@ohif/core';
import type { Button } from '@ohif/core/types';
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)
@@ -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[] = [
// Measurement
{
@@ -62,7 +43,7 @@ const toolbarButtons: Button[] = [
groupId: 'MeasurementTools',
isRadio: true, // ?
// Switch?
primary: _createToolButton(
primary: ToolbarService._createToolButton(
'Length',
'tool-length',
'Length',
@@ -93,7 +74,7 @@ const toolbarButtons: Button[] = [
tooltip: 'More Measure Tools',
},
items: [
_createToolButton(
ToolbarService._createToolButton(
'Length',
'tool-length',
'Length',
@@ -117,7 +98,7 @@ const toolbarButtons: Button[] = [
],
'Length Tool'
),
_createToolButton(
ToolbarService._createToolButton(
'Bidirectional',
'tool-bidirectional',
'Bidirectional',
@@ -140,7 +121,7 @@ const toolbarButtons: Button[] = [
],
'Bidirectional Tool'
),
_createToolButton(
ToolbarService._createToolButton(
'ArrowAnnotate',
'tool-annotate',
'Annotation',
@@ -163,7 +144,7 @@ const toolbarButtons: Button[] = [
],
'Arrow Annotate'
),
_createToolButton(
ToolbarService._createToolButton(
'EllipticalROI',
'tool-elipse',
'Ellipse',
@@ -186,7 +167,7 @@ const toolbarButtons: Button[] = [
],
'Ellipse Tool'
),
_createToolButton(
ToolbarService._createToolButton(
'CircleROI',
'tool-circle',
'Circle',
@@ -237,7 +218,7 @@ const toolbarButtons: Button[] = [
type: 'ohif.splitButton',
props: {
groupId: 'WindowLevel',
primary: _createToolButton(
primary: ToolbarService._createToolButton(
'WindowLevel',
'tool-window-level',
'Window Level',
@@ -411,7 +392,6 @@ const toolbarButtons: Button[] = [
commandOptions: {
protocolId: 'mpr',
},
context: 'DEFAULT',
},
],
},
@@ -430,225 +410,10 @@ const toolbarButtons: Button[] = [
toolGroupId: 'mpr',
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;