diff --git a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts
index fa3c6d47c..ad5898ee9 100644
--- a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts
+++ b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts
@@ -180,7 +180,8 @@ function getUpdatedViewportsForSegmentation({
});
}
});
- return updatedViewports;
+
+ return updatedViewports.filter(v => v.viewportOptions?.viewportType !== 'volume3d');
}
export {
diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts
index b63aee091..1a7401340 100644
--- a/extensions/cornerstone/src/commandsModule.ts
+++ b/extensions/cornerstone/src/commandsModule.ts
@@ -311,6 +311,10 @@ function commandsModule({
return;
}
+ if (!toolGroup.hasTool(toolName)) {
+ return;
+ }
+
const activeToolName = toolGroup.getActivePrimaryMouseButtonTool();
if (activeToolName) {
diff --git a/extensions/cornerstone/src/getToolbarModule.tsx b/extensions/cornerstone/src/getToolbarModule.tsx
index 7c1209836..e6cbbe41b 100644
--- a/extensions/cornerstone/src/getToolbarModule.tsx
+++ b/extensions/cornerstone/src/getToolbarModule.tsx
@@ -166,6 +166,19 @@ export default function getToolbarModule({ commandsManager, servicesManager }) {
};
},
},
+ {
+ name: 'evaluate.not3D',
+ evaluate: ({ viewportId, button }) => {
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
+
+ if (viewport?.type === 'volume3d') {
+ return {
+ disabled: true,
+ className: '!text-common-bright ohif-disabled',
+ };
+ }
+ },
+ },
{
name: 'evaluate.viewportProperties.toggle',
evaluate: ({ viewportId, button }) => {
diff --git a/extensions/cornerstone/src/hps/fourUp.ts b/extensions/cornerstone/src/hps/fourUp.ts
index 776d7a298..ac7435fb8 100644
--- a/extensions/cornerstone/src/hps/fourUp.ts
+++ b/extensions/cornerstone/src/hps/fourUp.ts
@@ -1,7 +1,9 @@
export const fourUp = {
id: 'fourUp',
locked: true,
- name: 'fourUp',
+ name: '3D four up',
+ icon: 'layout-advanced-3d-four-up',
+ isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
diff --git a/extensions/cornerstone/src/hps/main3D.ts b/extensions/cornerstone/src/hps/main3D.ts
index a7b837991..e59437cb3 100644
--- a/extensions/cornerstone/src/hps/main3D.ts
+++ b/extensions/cornerstone/src/hps/main3D.ts
@@ -1,7 +1,9 @@
export const main3D = {
id: 'main3D',
locked: true,
- name: 'main3D',
+ name: '3D main',
+ icon: 'layout-advanced-3d-main',
+ isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
diff --git a/extensions/cornerstone/src/hps/mpr.ts b/extensions/cornerstone/src/hps/mpr.ts
index c9a9eea82..5927af785 100644
--- a/extensions/cornerstone/src/hps/mpr.ts
+++ b/extensions/cornerstone/src/hps/mpr.ts
@@ -2,8 +2,10 @@ import { Types } from '@ohif/core';
export const mpr: Types.HangingProtocol.Protocol = {
id: 'mpr',
- name: 'Multi-Planar Reconstruction',
+ name: 'MPR',
locked: true,
+ icon: 'layout-advanced-mpr',
+ isPreset: true,
createdDate: '2021-02-23',
modifiedDate: '2023-08-15',
availableTo: {},
diff --git a/extensions/cornerstone/src/hps/only3D.ts b/extensions/cornerstone/src/hps/only3D.ts
index d319d1ee4..53c32cf61 100644
--- a/extensions/cornerstone/src/hps/only3D.ts
+++ b/extensions/cornerstone/src/hps/only3D.ts
@@ -1,7 +1,9 @@
export const only3D = {
id: 'only3D',
locked: true,
- name: 'only3D',
+ name: '3D only',
+ icon: 'layout-advanced-3d-only',
+ isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
diff --git a/extensions/cornerstone/src/hps/primary3D.ts b/extensions/cornerstone/src/hps/primary3D.ts
index 126553248..8d92943ae 100644
--- a/extensions/cornerstone/src/hps/primary3D.ts
+++ b/extensions/cornerstone/src/hps/primary3D.ts
@@ -1,7 +1,9 @@
export const primary3D = {
id: 'primary3D',
locked: true,
- name: 'primary3D',
+ name: '3D primary',
+ icon: 'layout-advanced-3d-primary',
+ isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
diff --git a/extensions/cornerstone/src/hps/primaryAxial.ts b/extensions/cornerstone/src/hps/primaryAxial.ts
index 2126920b3..f42b919fa 100644
--- a/extensions/cornerstone/src/hps/primaryAxial.ts
+++ b/extensions/cornerstone/src/hps/primaryAxial.ts
@@ -1,7 +1,9 @@
export const primaryAxial = {
id: 'primaryAxial',
locked: true,
- name: 'primaryAxial',
+ name: 'Axial Primary',
+ icon: 'layout-advanced-axial-primary',
+ isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
diff --git a/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx b/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx
new file mode 100644
index 000000000..341f6686e
--- /dev/null
+++ b/extensions/default/src/Toolbar/LegacyLayoutSelector.tsx
@@ -0,0 +1,88 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import PropTypes from 'prop-types';
+import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
+import { ServicesManager } from '@ohif/core';
+
+function LegacyLayoutSelectorWithServices({ servicesManager, ...props }) {
+ const { toolbarService } = servicesManager.services;
+
+ const onSelection = useCallback(
+ props => {
+ toolbarService.recordInteraction({
+ interactionType: 'action',
+ commands: [
+ {
+ commandName: 'setViewportGridLayout',
+ commandOptions: { ...props },
+ context: 'DEFAULT',
+ },
+ ],
+ });
+ },
+ [toolbarService]
+ );
+
+ return (
+
+ );
+}
+
+function LayoutSelector({ rows, columns, className, onSelection, ...rest }) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const closeOnOutsideClick = () => {
+ if (isOpen) {
+ setIsOpen(false);
+ }
+ };
+
+ useEffect(() => {
+ window.addEventListener('click', closeOnOutsideClick);
+ return () => {
+ window.removeEventListener('click', closeOnOutsideClick);
+ };
+ }, [isOpen]);
+
+ const onInteractionHandler = () => setIsOpen(!isOpen);
+ const DropdownContent = isOpen ? OHIFLayoutSelector : null;
+
+ return (
+
+ )
+ }
+ isActive={isOpen}
+ type="toggle"
+ />
+ );
+}
+
+LayoutSelector.propTypes = {
+ rows: PropTypes.number,
+ columns: PropTypes.number,
+ onLayoutChange: PropTypes.func,
+ servicesManager: PropTypes.instanceOf(ServicesManager),
+};
+
+LayoutSelector.defaultProps = {
+ rows: 3,
+ columns: 3,
+ onLayoutChange: () => {},
+};
+
+export default LegacyLayoutSelectorWithServices;
diff --git a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx
index 27202ed0a..8428472dd 100644
--- a/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx
+++ b/extensions/default/src/Toolbar/ToolbarLayoutSelector.tsx
@@ -1,37 +1,127 @@
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
-import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
+import { LayoutSelector as OHIFLayoutSelector, ToolbarButton, LayoutPreset } from '@ohif/ui';
import { ServicesManager } from '@ohif/core';
-function ToolbarLayoutSelectorWithServices({ servicesManager, commands, ...props }) {
- const { toolbarService, viewportGridService } = servicesManager.services;
+const defaultCommonPresets = [
+ {
+ icon: 'layout-common-1x1',
+ commandOptions: {
+ numRows: 1,
+ numCols: 1,
+ },
+ },
+ {
+ icon: 'layout-common-1x2',
+ commandOptions: {
+ numRows: 1,
+ numCols: 2,
+ },
+ },
+ {
+ icon: 'layout-common-2x2',
+ commandOptions: {
+ numRows: 2,
+ numCols: 2,
+ },
+ },
+ {
+ icon: 'layout-common-2x3',
+ commandOptions: {
+ numRows: 2,
+ numCols: 3,
+ },
+ },
+];
- const onInteraction = useCallback(
- args => {
- const viewportId = viewportGridService.getActiveViewportId();
- const refreshProps = {
- viewportId,
- };
-
- if (props.onLayoutChange) {
- props.onLayoutChange(args);
+const generateAdvancedPresets = hangingProtocolService => {
+ const hangingProtocols = Array.from(hangingProtocolService.protocols.values());
+ return hangingProtocols
+ .map(hp => {
+ if (!hp.isPreset) {
+ return null;
}
- toolbarService.recordInteraction({ commands }, { ...args, refreshProps });
+ return {
+ icon: hp.icon,
+ title: hp.name,
+ commandOptions: {
+ protocolId: hp.id,
+ },
+ };
+ })
+ .filter(preset => preset !== null);
+};
+
+function ToolbarLayoutSelectorWithServices({ servicesManager, ...props }) {
+ const { toolbarService } = servicesManager.services;
+
+ const [isDisabled, setIsDisabled] = useState(false);
+
+ const handleMouseEnter = () => {
+ setIsDisabled(false);
+ };
+
+ const onSelection = useCallback(
+ props => {
+ toolbarService.recordInteraction({
+ interactionType: 'action',
+ commands: [
+ {
+ commandName: 'setViewportGridLayout',
+ commandOptions: { ...props },
+ },
+ ],
+ });
+ setIsDisabled(true);
+ },
+ [toolbarService]
+ );
+ const onSelectionPreset = useCallback(
+ props => {
+ toolbarService.recordInteraction({
+ interactionType: 'action',
+ commands: [
+ {
+ commandName: 'setHangingProtocol',
+ commandOptions: { ...props },
+ },
+ ],
+ });
+ setIsDisabled(true);
},
[toolbarService]
);
return (
-
+
+
+
);
}
-function LayoutSelector({ rows, columns, className, onInteraction, ...rest }) {
+function LayoutSelector({
+ rows,
+ columns,
+ className,
+ onSelection,
+ onSelectionPreset,
+ servicesManager,
+ tooltipDisabled,
+ ...rest
+}) {
const [isOpen, setIsOpen] = useState(false);
+ const { customizationService, hangingProtocolService } = servicesManager.services;
+ const commonPresets = customizationService.get('commonPresets') || defaultCommonPresets;
+ const advancedPresets =
+ customizationService.get('advancedPresets') || generateAdvancedPresets(hangingProtocolService);
+
const closeOnOutsideClick = () => {
if (isOpen) {
setIsOpen(false);
@@ -45,24 +135,68 @@ function LayoutSelector({ rows, columns, className, onInteraction, ...rest }) {
};
}, [isOpen]);
- const onInteractionHandler = () => setIsOpen(!isOpen);
+ const onInteractionHandler = () => {
+ setIsOpen(!isOpen);
+ };
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
return (
+
+
+
Common
+
+
+ {commonPresets.map((preset, index) => (
+
+ ))}
+
+
+
+
+
Advanced
+
+
+ {advancedPresets.map((preset, index) => (
+
+ ))}
+
+
+
+
+
Custom
+
+
+ Hover to select
rows and columns
Click to apply
+
+
+
)
}
isActive={isOpen}
@@ -79,8 +213,8 @@ LayoutSelector.propTypes = {
};
LayoutSelector.defaultProps = {
+ columns: 4,
rows: 3,
- columns: 3,
onLayoutChange: () => {},
};
diff --git a/modes/basic-dev-mode/src/toolbarButtons.js b/modes/basic-dev-mode/src/toolbarButtons.js
index 638e73b72..e11c15a25 100644
--- a/modes/basic-dev-mode/src/toolbarButtons.js
+++ b/modes/basic-dev-mode/src/toolbarButtons.js
@@ -148,7 +148,7 @@ const toolbarButtons: Button[] = [
uiType: 'ohif.layoutSelector',
props: {
rows: 3,
- columns: 3,
+ columns: 4,
evaluate: 'evaluate.action',
commands: [
{
diff --git a/modes/basic-test-mode/src/initToolGroups.ts b/modes/basic-test-mode/src/initToolGroups.ts
index 3187e12e3..97caed87a 100644
--- a/modes/basic-test-mode/src/initToolGroups.ts
+++ b/modes/basic-test-mode/src/initToolGroups.ts
@@ -193,10 +193,38 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
toolGroupService.createToolGroupAndAddTools('mpr', tools);
}
+function initVolume3DToolGroup(extensionManager, toolGroupService) {
+ const utilityModule = extensionManager.getModuleEntry(
+ '@ohif/extension-cornerstone.utilityModule.tools'
+ );
+
+ const { toolNames, Enums } = utilityModule.exports;
+
+ const tools = {
+ active: [
+ {
+ toolName: toolNames.TrackballRotateTool,
+ bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
+ },
+ {
+ toolName: toolNames.Zoom,
+ bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
+ },
+ {
+ toolName: toolNames.Pan,
+ bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
+ },
+ ],
+ };
+
+ toolGroupService.createToolGroupAndAddTools('volume3d', tools);
+}
+
function initToolGroups(extensionManager, toolGroupService, commandsManager) {
initDefaultToolGroup(extensionManager, toolGroupService, commandsManager, 'default');
initSRToolGroup(extensionManager, toolGroupService, commandsManager);
initMPRToolGroup(extensionManager, toolGroupService, commandsManager);
+ initVolume3DToolGroup(extensionManager, toolGroupService);
}
export default initToolGroups;
diff --git a/modes/basic-test-mode/src/toolbarButtons.ts b/modes/basic-test-mode/src/toolbarButtons.ts
index 34b300e22..2e1517676 100644
--- a/modes/basic-test-mode/src/toolbarButtons.ts
+++ b/modes/basic-test-mode/src/toolbarButtons.ts
@@ -155,6 +155,41 @@ const toolbarButtons: Button[] = [
evaluate: 'evaluate.cornerstoneTool',
},
},
+ {
+ id: 'MPR',
+ uiType: 'ohif.radioGroup',
+ props: {
+ icon: 'icon-mpr',
+ label: 'MPR',
+ commands: [
+ {
+ commandName: 'toggleHangingProtocol',
+ commandOptions: {
+ protocolId: 'mpr',
+ },
+ },
+ ],
+ evaluate: 'evaluate.mpr',
+ },
+ },
+ {
+ id: 'TrackBallRotate',
+ type: 'ohif.radioGroup',
+ props: {
+ type: 'tool',
+ icon: 'tool-3d-rotate',
+ label: '3D Rotate',
+ commands: [
+ {
+ commandName: 'setToolActive',
+ commandOptions: {
+ toolName: 'TrackBallRotate',
+ },
+ context: 'CORNERSTONE',
+ },
+ ],
+ },
+ },
{
id: 'Capture',
uiType: 'ohif.radioGroup',
@@ -174,30 +209,9 @@ const toolbarButtons: Button[] = [
uiType: 'ohif.layoutSelector',
props: {
rows: 3,
- columns: 3,
+ columns: 4,
evaluate: 'evaluate.action',
- commands: [
- {
- commandName: 'setViewportGridLayout',
- },
- ],
- },
- },
- {
- id: 'MPR',
- uiType: 'ohif.radioGroup',
- props: {
- icon: 'icon-mpr',
- label: 'MPR',
- commands: [
- {
- commandName: 'toggleHangingProtocol',
- commandOptions: {
- protocolId: 'mpr',
- },
- },
- ],
- evaluate: 'evaluate.mpr',
+ commands: 'setViewportGridLayout',
},
},
{
diff --git a/modes/longitudinal/src/index.js b/modes/longitudinal/src/index.js
index 87fe93251..a04a7d301 100644
--- a/modes/longitudinal/src/index.js
+++ b/modes/longitudinal/src/index.js
@@ -83,11 +83,11 @@ function modeFactory({ modeConfiguration }) {
toolbarService.createButtonSection('primary', [
'MeasurementTools',
'Zoom',
- 'WindowLevel',
'Pan',
+ 'TrackballRotate',
+ 'WindowLevel',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
'MoreTools',
]);
diff --git a/modes/longitudinal/src/moreTools.ts b/modes/longitudinal/src/moreTools.ts
index 2f3d5c247..8b0e0c9e0 100644
--- a/modes/longitudinal/src/moreTools.ts
+++ b/modes/longitudinal/src/moreTools.ts
@@ -54,7 +54,7 @@ const moreTools = [
label: 'Flip Horizontal',
tooltip: 'Flip Horizontally',
commands: 'flipViewportHorizontal',
- evaluate: 'evaluate.viewportProperties.toggle',
+ evaluate: ['evaluate.viewportProperties.toggle', 'evaluate.not3D'],
}),
createButton({
id: 'ImageSliceSync',
@@ -73,7 +73,7 @@ const moreTools = [
commandOptions: { toggledState: true },
},
},
- evaluate: 'evaluate.cornerstone.synchronizer',
+ evaluate: ['evaluate.cornerstone.synchronizer', 'evaluate.not3D'],
}),
createButton({
id: 'ReferenceLines',
@@ -137,7 +137,7 @@ const moreTools = [
label: 'Cine',
tooltip: 'Cine',
commands: 'toggleCine',
- evaluate: 'evaluate.cine',
+ evaluate: ['evaluate.cine', 'evaluate.not3D'],
}),
createButton({
id: 'Angle',
diff --git a/modes/longitudinal/src/toolbarButtons.ts b/modes/longitudinal/src/toolbarButtons.ts
index 34b300e22..76217b29f 100644
--- a/modes/longitudinal/src/toolbarButtons.ts
+++ b/modes/longitudinal/src/toolbarButtons.ts
@@ -1,9 +1,6 @@
// TODO: torn, can either bake this here; or have to create a whole new button type
// Only ways that you can pass in a custom React component for render :l
-import {
- // ListMenu,
- WindowLevelMenuItem,
-} from '@ohif/ui';
+import { WindowLevelMenuItem } from '@ohif/ui';
import { defaults, ToolbarService } from '@ohif/core';
import type { Button } from '@ohif/core/types';
@@ -36,7 +33,7 @@ function _createWwwcPreset(preset, title, subtitle) {
export const setToolActiveToolbar = {
commandName: 'setToolActiveToolbar',
commandOptions: {
- toolGroupIds: ['default', 'mpr', 'SRToolGroup'],
+ toolGroupIds: ['default', 'mpr', 'SRToolGroup', 'volume3d'],
},
};
@@ -155,6 +152,17 @@ const toolbarButtons: Button[] = [
evaluate: 'evaluate.cornerstoneTool',
},
},
+ {
+ id: 'TrackballRotate',
+ uiType: 'ohif.radioGroup',
+ props: {
+ type: 'tool',
+ icon: 'tool-3d-rotate',
+ label: '3D Rotate',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ },
+ },
{
id: 'Capture',
uiType: 'ohif.radioGroup',
@@ -174,7 +182,7 @@ const toolbarButtons: Button[] = [
uiType: 'ohif.layoutSelector',
props: {
rows: 3,
- columns: 3,
+ columns: 4,
evaluate: 'evaluate.action',
commands: [
{
@@ -183,23 +191,6 @@ const toolbarButtons: Button[] = [
],
},
},
- {
- id: 'MPR',
- uiType: 'ohif.radioGroup',
- props: {
- icon: 'icon-mpr',
- label: 'MPR',
- commands: [
- {
- commandName: 'toggleHangingProtocol',
- commandOptions: {
- protocolId: 'mpr',
- },
- },
- ],
- evaluate: 'evaluate.mpr',
- },
- },
{
id: 'Crosshairs',
uiType: 'ohif.radioGroup',
diff --git a/modes/segmentation/package.json b/modes/segmentation/package.json
index b4c4a277e..98d772ad0 100644
--- a/modes/segmentation/package.json
+++ b/modes/segmentation/package.json
@@ -35,7 +35,14 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
- "@ohif/core": "3.8.0-beta.64"
+ "@ohif/core": "3.8.0-beta.64",
+ "@ohif/extension-cornerstone": "3.8.0-beta.64",
+ "@ohif/extension-cornerstone-dicom-rt": "3.8.0-beta.64",
+ "@ohif/extension-cornerstone-dicom-seg": "3.8.0-beta.64",
+ "@ohif/extension-cornerstone-dicom-sr": "3.8.0-beta.64",
+ "@ohif/extension-default": "3.8.0-beta.64",
+ "@ohif/extension-dicom-pdf": "3.8.0-beta.64",
+ "@ohif/extension-dicom-video": "3.8.0-beta.64"
},
"dependencies": {
"@babel/runtime": "^7.20.13",
diff --git a/modes/segmentation/src/index.tsx b/modes/segmentation/src/index.tsx
index e4db1b9e9..85a55a830 100644
--- a/modes/segmentation/src/index.tsx
+++ b/modes/segmentation/src/index.tsx
@@ -4,6 +4,9 @@ import toolbarButtons from './toolbarButtons';
import segmentationButtons from './segmentationButtons';
import initToolGroups from './initToolGroups';
+const DEFAULT_TOOL_GROUP_ID = 'default';
+const VOLUME3D_TOOL_GROUP_ID = 'volume3d';
+
const ohif = {
layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout',
sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack',
@@ -62,12 +65,13 @@ function modeFactory({ modeConfiguration }) {
toolbarService.addButtons(segmentationButtons);
toolbarService.createButtonSection('primary', [
+ 'WindowLevel',
'Pan',
+ 'Zoom',
+ 'TrackballRotate',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
- 'Zoom',
'MoreTools',
]);
toolbarService.createButtonSection('segmentationToolbox', ['BrushTools', 'Shapes']);
@@ -105,9 +109,13 @@ function modeFactory({ modeConfiguration }) {
// that is not supported by the mode
const modalitiesArray = modalities.split('\\');
return {
- valid: modalitiesArray.length === 1 ? !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0]) : true,
- description: 'The mode does not support studies that ONLY include the following modalities: SM, US, MG, OT, DOC, CR',
- }
+ valid:
+ modalitiesArray.length === 1
+ ? !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0])
+ : true,
+ description:
+ 'The mode does not support studies that ONLY include the following modalities: SM, US, MG, OT, DOC, CR',
+ };
},
/**
* Mode Routes are used to define the mode's behavior. A list of Mode Route
diff --git a/modes/segmentation/src/initToolGroups.ts b/modes/segmentation/src/initToolGroups.ts
index 31895daf0..026cecdbf 100644
--- a/modes/segmentation/src/initToolGroups.ts
+++ b/modes/segmentation/src/initToolGroups.ts
@@ -81,6 +81,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
toolName: utilityModule.exports.toolNames.Crosshairs,
configuration: {
viewportIndicators: false,
+ disableOnPassive: true,
autoPan: {
enabled: false,
panSize: 10,
@@ -92,9 +93,37 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
toolGroupService.createToolGroupAndAddTools('mpr', tools);
}
+function initVolume3DToolGroup(extensionManager, toolGroupService) {
+ const utilityModule = extensionManager.getModuleEntry(
+ '@ohif/extension-cornerstone.utilityModule.tools'
+ );
+
+ const { toolNames, Enums } = utilityModule.exports;
+
+ const tools = {
+ active: [
+ {
+ toolName: toolNames.TrackballRotateTool,
+ bindings: [{ mouseButton: Enums.MouseBindings.Primary }],
+ },
+ {
+ toolName: toolNames.Zoom,
+ bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
+ },
+ {
+ toolName: toolNames.Pan,
+ bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }],
+ },
+ ],
+ };
+
+ toolGroupService.createToolGroupAndAddTools('volume3d', tools);
+}
+
function initToolGroups(extensionManager, toolGroupService, commandsManager) {
initDefaultToolGroup(extensionManager, toolGroupService, commandsManager, 'default');
initMPRToolGroup(extensionManager, toolGroupService, commandsManager);
+ initVolume3DToolGroup(extensionManager, toolGroupService);
}
export default initToolGroups;
diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts
index bbff5e2d6..4d2dacd06 100644
--- a/modes/segmentation/src/toolbarButtons.ts
+++ b/modes/segmentation/src/toolbarButtons.ts
@@ -1,8 +1,16 @@
-import { defaults, ToolbarService } from '@ohif/core';
import type { Button } from '@ohif/core/types';
+import { defaults, ToolbarService, ViewportGridService } from '@ohif/core';
import { WindowLevelMenuItem } from '@ohif/ui';
const { windowLevelPresets } = defaults;
+const { createButton } = ToolbarService;
+
+const ReferenceLinesListeners: RunCommand = [
+ {
+ commandName: 'setSourceViewportForReferenceLinesTool',
+ context: 'CORNERSTONE',
+ },
+];
function _createWwwcPreset(preset, title, subtitle) {
return {
@@ -21,16 +29,12 @@ function _createWwwcPreset(preset, title, subtitle) {
};
}
-function _createSetToolActiveCommands(toolName, toolGroupIds = ['default', 'mpr', 'SRToolGroup']) {
- return toolGroupIds.map(toolGroupId => ({
- commandName: 'setToolActive',
- commandOptions: {
- toolGroupId,
- toolName,
- },
- context: 'CORNERSTONE',
- }));
-}
+export const setToolActiveToolbar = {
+ commandName: 'setToolActiveToolbar',
+ commandOptions: {
+ toolGroupIds: ['default', 'mpr', 'SRToolGroup'],
+ },
+};
const toolbarButtons: Button[] = [
{
@@ -39,7 +43,7 @@ const toolbarButtons: Button[] = [
props: {
icon: 'tool-zoom',
label: 'Zoom',
- commands: _createSetToolActiveCommands('Zoom'),
+ commands: setToolActiveToolbar,
evaluate: 'evaluate.cornerstoneTool',
},
},
@@ -48,12 +52,12 @@ const toolbarButtons: Button[] = [
uiType: 'ohif.splitButton',
props: {
groupId: 'WindowLevel',
- primary: ToolbarService.createButton({
+ primary: createButton({
id: 'WindowLevel',
icon: 'tool-window-level',
label: 'Window Level',
tooltip: 'Window Level',
- commands: _createSetToolActiveCommands('WindowLevel'),
+ commands: setToolActiveToolbar,
evaluate: 'evaluate.cornerstoneTool',
}),
secondary: {
@@ -76,7 +80,18 @@ const toolbarButtons: Button[] = [
props: {
icon: 'tool-move',
label: 'Pan',
- commands: _createSetToolActiveCommands('Pan'),
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ },
+ },
+ {
+ id: 'TrackballRotate',
+ uiType: 'ohif.radioGroup',
+ props: {
+ type: 'tool',
+ icon: 'tool-3d-rotate',
+ label: '3D Rotate',
+ commands: setToolActiveToolbar,
evaluate: 'evaluate.cornerstoneTool',
},
},
@@ -86,12 +101,7 @@ const toolbarButtons: Button[] = [
props: {
icon: 'tool-capture',
label: 'Capture',
- commands: [
- {
- commandName: 'showDownloadViewportModal',
- context: 'CORNERSTONE',
- },
- ],
+ commands: 'showDownloadViewportModal',
evaluate: 'evaluate.action',
},
},
@@ -100,31 +110,9 @@ const toolbarButtons: Button[] = [
uiType: 'ohif.layoutSelector',
props: {
rows: 3,
- columns: 3,
+ columns: 4,
evaluate: 'evaluate.action',
- commands: [
- {
- commandName: 'setViewportGridLayout',
- },
- ],
- },
- },
- {
- id: 'MPR',
- uiType: 'ohif.radioGroup',
- props: {
- icon: 'icon-mpr',
- label: 'MPR',
- commands: [
- {
- commandName: 'toggleHangingProtocol',
- commandOptions: {
- protocolId: 'mpr',
- },
- context: 'DEFAULT',
- },
- ],
- evaluate: 'evaluate.mpr',
+ commands: 'setViewportGridLayout',
},
},
{
@@ -133,7 +121,12 @@ const toolbarButtons: Button[] = [
props: {
icon: 'tool-crosshair',
label: 'Crosshairs',
- commands: _createSetToolActiveCommands('Crosshairs', ['mpr']),
+ commands: {
+ commandName: 'setToolActiveToolbar',
+ commandOptions: {
+ toolGroupIds: ['mpr'],
+ },
+ },
evaluate: 'evaluate.cornerstoneTool',
},
},
@@ -143,104 +136,146 @@ const toolbarButtons: Button[] = [
props: {
groupId: 'MoreTools',
evaluate: 'evaluate.group.promoteToPrimaryIfCornerstoneToolNotActiveInTheList',
- primary: ToolbarService.createButton({
+ primary: createButton({
id: 'Reset',
icon: 'tool-reset',
- label: 'Reset View',
- tooltip: 'Reset',
- commands: [
- {
- commandName: 'resetViewport',
- context: 'CORNERSTONE',
- },
- ],
+ tooltip: 'Reset View',
+ label: 'Reset',
+ commands: 'resetViewport',
evaluate: 'evaluate.action',
}),
secondary: {
icon: 'chevron-down',
+ label: '',
tooltip: 'More Tools',
},
items: [
- ToolbarService.createButton({
- id: 'RotateRight',
+ createButton({
+ id: 'Reset',
+ icon: 'tool-reset',
+ label: 'Reset View',
+ tooltip: 'Reset View',
+ commands: 'resetViewport',
+ evaluate: 'evaluate.action',
+ }),
+ createButton({
+ id: 'rotate-right',
icon: 'tool-rotate-right',
label: 'Rotate Right',
tooltip: 'Rotate +90',
- commands: [
- {
- commandName: 'rotateViewportCW',
- context: 'CORNERSTONE',
- },
- ],
+ commands: 'rotateViewportCW',
evaluate: 'evaluate.action',
}),
- ToolbarService.createButton({
- id: 'FlipHorizontal',
+ createButton({
+ id: 'flipHorizontal',
icon: 'tool-flip-horizontal',
- label: 'Flip Horizontally',
- tooltip: 'Flip Horizontal',
- commands: [
- {
- commandName: 'flipViewportHorizontal',
- context: 'CORNERSTONE',
- },
- ],
- evaluate: 'evaluate.action',
+ label: 'Flip Horizontal',
+ tooltip: 'Flip Horizontally',
+ commands: 'flipViewportHorizontal',
+ evaluate: ['evaluate.viewportProperties.toggle', 'evaluate.not3D'],
}),
- ToolbarService.createButton({
+ createButton({
+ id: 'ReferenceLines',
+ icon: 'tool-referenceLines',
+ label: 'Reference Lines',
+ tooltip: 'Show Reference Lines',
+ commands: {
+ commandName: 'setToolEnabled',
+ commandOptions: {
+ toolName: 'ReferenceLines',
+ toggle: true, // Toggle the tool on/off upon click
+ },
+ },
+ listeners: {
+ [ViewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED]: ReferenceLinesListeners,
+ [ViewportGridService.EVENTS.VIEWPORTS_READY]: ReferenceLinesListeners,
+ },
+ evaluate: 'evaluate.cornerstoneTool.toggle',
+ }),
+ createButton({
+ id: 'ImageOverlay',
+ icon: 'toggle-dicom-overlay',
+ label: 'Image Overlay',
+ tooltip: 'Toggle Image Overlay',
+ commands: {
+ commandName: 'setToolEnabled',
+ commandOptions: {
+ toolName: 'ImageOverlayViewer',
+ toggle: true, // Toggle the tool on/off upon click
+ },
+ },
+ evaluate: 'evaluate.cornerstoneTool.toggle',
+ }),
+ createButton({
id: 'StackScroll',
icon: 'tool-stack-scroll',
label: 'Stack Scroll',
tooltip: 'Stack Scroll',
- commands: _createSetToolActiveCommands('StackScroll'),
+ commands: setToolActiveToolbar,
evaluate: 'evaluate.cornerstoneTool',
}),
- ToolbarService.createButton({
- id: 'Magnify',
- icon: 'tool-magnify',
- label: 'Magnify',
- tooltip: 'Magnify',
- commands: _createSetToolActiveCommands('Magnify'),
- evaluate: 'evaluate.cornerstoneTool',
- }),
- ToolbarService.createButton({
- id: 'Invert',
+ createButton({
+ id: 'invert',
icon: 'tool-invert',
label: 'Invert',
tooltip: 'Invert Colors',
- commands: [
- {
- commandName: 'invertViewport',
- context: 'CORNERSTONE',
- },
- ],
- evaluate: 'evaluate.action',
+ commands: 'invertViewport',
+ evaluate: 'evaluate.viewportProperties.toggle',
}),
- ToolbarService.createButton({
+ createButton({
+ id: 'Probe',
+ icon: 'tool-probe',
+ label: 'Probe',
+ tooltip: 'Probe',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ }),
+ createButton({
id: 'Cine',
icon: 'tool-cine',
label: 'Cine',
tooltip: 'Cine',
- commands: [
- {
- commandName: 'toggleCine',
- context: 'CORNERSTONE',
- },
- ],
- evaluate: 'evaluate.action',
+ commands: 'toggleCine',
+ evaluate: ['evaluate.cine', 'evaluate.not3D'],
}),
- ToolbarService.createButton({
- id: 'DicomTagBrowser',
+ createButton({
+ id: 'Angle',
+ icon: 'tool-angle',
+ label: 'Angle',
+ tooltip: 'Angle',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ }),
+ createButton({
+ id: 'Magnify',
+ icon: 'tool-magnify',
+ label: 'Magnify',
+ tooltip: 'Magnify',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ }),
+ createButton({
+ id: 'RectangleROI',
+ icon: 'tool-rectangle',
+ label: 'Rectangle',
+ tooltip: 'Rectangle',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ }),
+ createButton({
+ id: 'CalibrationLine',
+ icon: 'tool-calibration',
+ label: 'Calibration',
+ tooltip: 'Calibration Line',
+ commands: setToolActiveToolbar,
+ evaluate: 'evaluate.cornerstoneTool',
+ }),
+ createButton({
+ id: 'TagBrowser',
icon: 'list-bullets',
label: 'Dicom Tag Browser',
tooltip: 'Dicom Tag Browser',
- commands: [
- {
- commandName: 'openDICOMTagViewer',
- context: 'DEFAULT',
- },
- ],
- evaluate: 'evaluate.action',
+ commands: 'openDICOMTagViewer',
}),
],
},
diff --git a/modes/tmtv/src/toolbarButtons.js b/modes/tmtv/src/toolbarButtons.js
index 35d3f3383..5beaac21f 100644
--- a/modes/tmtv/src/toolbarButtons.js
+++ b/modes/tmtv/src/toolbarButtons.js
@@ -100,22 +100,6 @@ const toolbarButtons = [
evaluate: 'evaluate.cornerstoneTool',
},
},
- {
- id: 'MPR',
- uiType: 'ohif.radioGroup',
- props: {
- icon: 'icon-mpr',
- label: 'MPR',
- commands: [
- {
- commandName: 'toggleHangingProtocol',
- commandOptions: { protocolId: 'mpr' },
- context: 'DEFAULT',
- },
- ],
- evaluate: 'evaluate.mpr',
- },
- },
// Window Level + Presets
{
id: 'WindowLevel',
diff --git a/platform/app/cypress/support/aliases.js b/platform/app/cypress/support/aliases.js
index 1bda29b36..5b28709ca 100644
--- a/platform/app/cypress/support/aliases.js
+++ b/platform/app/cypress/support/aliases.js
@@ -12,7 +12,6 @@ export function initCornerstoneToolsAliases() {
cy.get('[data-cy="MoreTools-split-button-secondary"]').as('moreBtnSecondary');
cy.get('[data-cy="Layout"]').as('layoutBtn');
cy.get('.cornerstone-viewport-element').as('viewport');
- cy.get('[data-cy="MPR"]').as('mprBtn');
}
//Creating aliases for Common page elements
diff --git a/platform/cli/templates/mode/src/index.tsx b/platform/cli/templates/mode/src/index.tsx
index 7ff747bbe..5efbe0a2a 100644
--- a/platform/cli/templates/mode/src/index.tsx
+++ b/platform/cli/templates/mode/src/index.tsx
@@ -56,7 +56,6 @@ function modeFactory({ modeConfiguration }) {
'Pan',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
'MoreTools',
]);
diff --git a/platform/core/src/services/ToolBarService/ToolbarService.ts b/platform/core/src/services/ToolBarService/ToolbarService.ts
index eff3912ab..6fce58d2b 100644
--- a/platform/core/src/services/ToolBarService/ToolbarService.ts
+++ b/platform/core/src/services/ToolBarService/ToolbarService.ts
@@ -420,6 +420,34 @@ export default class ToolbarService extends PubSubService {
return;
}
+ if (Array.isArray(evaluate)) {
+ const evaluators = evaluate.map(evaluatorName => {
+ const evaluateFunction = this._evaluateFunction[evaluatorName];
+
+ if (!evaluateFunction) {
+ throw new Error(
+ `Evaluate function not found for name: ${evaluatorName}, you can register an evaluate function with the getToolbarModule in your extensions`
+ );
+ }
+
+ return evaluateFunction;
+ });
+
+ props.evaluate = args => {
+ const results = evaluators.map(evaluator => evaluator(args));
+ const mergedResult = results.reduce((acc, result) => {
+ return {
+ ...acc,
+ ...result,
+ };
+ }, {});
+
+ return mergedResult;
+ };
+
+ return;
+ }
+
if (typeof evaluate === 'string') {
const evaluateFunction = this._evaluateFunction[evaluate];
@@ -429,7 +457,7 @@ export default class ToolbarService extends PubSubService {
}
throw new Error(
- `Evaluate function not found for name: ${evaluate}, you can register an evaluate function with the getToolbarModule in your extensions`
+ `Evaluate function not found for name: ${evaluate}, you can register an evaluate function with the getToolbarModule in your extensions`
);
}
@@ -443,7 +471,7 @@ export default class ToolbarService extends PubSubService {
}
throw new Error(
- `Evaluate function not found for name: ${name}, you can register an evaluate function with the getToolbarModule in your extensions`
+ `Evaluate function not found for name: ${name}, you can register an evaluate function with the getToolbarModule in your extensions`
);
}
};
diff --git a/platform/core/src/services/ToolBarService/types.ts b/platform/core/src/services/ToolBarService/types.ts
index 9b53e5e3a..1318e90f3 100644
--- a/platform/core/src/services/ToolBarService/types.ts
+++ b/platform/core/src/services/ToolBarService/types.ts
@@ -1,6 +1,6 @@
import type { RunCommand } from '../../types/Command';
-export type EvaluatePublic = string | EvaluateFunction;
+export type EvaluatePublic = string | EvaluateFunction | string[];
export type EvaluateFunction = (props: Record) => {
disabled: boolean;
diff --git a/platform/core/src/types/HangingProtocol.ts b/platform/core/src/types/HangingProtocol.ts
index 0e23b1d2e..0c0efa512 100644
--- a/platform/core/src/types/HangingProtocol.ts
+++ b/platform/core/src/types/HangingProtocol.ts
@@ -304,6 +304,16 @@ export type Protocol = {
*/
minSeriesLoaded: number;
};
+
+ /*
+ * The icon to use for this protocol. This is used to display the protocol
+ * in the advanced layout selector.
+ */
+
+ icon?: string;
+
+ /** Indicates if the protocol is a preset or not. Useful for setting presets for the layout selector */
+ isPreset?: true;
};
/** Used to dynamically generate protocols.
diff --git a/platform/docs/docs/migration-guide.md b/platform/docs/docs/migration-guide.md
index 9ca0cf8a2..9f93828a5 100644
--- a/platform/docs/docs/migration-guide.md
+++ b/platform/docs/docs/migration-guide.md
@@ -657,7 +657,6 @@ onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
'Pan',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
'MoreTools',
]);
diff --git a/platform/docs/docs/platform/extensions/modules/toolbar.md b/platform/docs/docs/platform/extensions/modules/toolbar.md
index 1af8549c7..a735b2daf 100644
--- a/platform/docs/docs/platform/extensions/modules/toolbar.md
+++ b/platform/docs/docs/platform/extensions/modules/toolbar.md
@@ -184,7 +184,6 @@ function modeFactory({ modeConfiguration }) {
'Pan',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
'MoreTools',
]);
diff --git a/platform/docs/docs/platform/services/data/ToolbarService.md b/platform/docs/docs/platform/services/data/ToolbarService.md
index 5a0a15964..3eb03ffd2 100644
--- a/platform/docs/docs/platform/services/data/ToolbarService.md
+++ b/platform/docs/docs/platform/services/data/ToolbarService.md
@@ -243,7 +243,6 @@ toolbarService.createButtonSection('primary', [
'Pan',
'Capture',
'Layout',
- 'MPR',
'Crosshairs',
'MoreTools',
]);
diff --git a/platform/ui/src/assets/icons/layout-advanced-3d-four-up.svg b/platform/ui/src/assets/icons/layout-advanced-3d-four-up.svg
new file mode 100644
index 000000000..f9f445ee1
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-3d-four-up.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-advanced-3d-main.svg b/platform/ui/src/assets/icons/layout-advanced-3d-main.svg
new file mode 100644
index 000000000..15b5d31cc
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-3d-main.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-advanced-3d-only.svg b/platform/ui/src/assets/icons/layout-advanced-3d-only.svg
new file mode 100644
index 000000000..8ee7a7431
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-3d-only.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-advanced-3d-primary.svg b/platform/ui/src/assets/icons/layout-advanced-3d-primary.svg
new file mode 100644
index 000000000..e77ecc9d6
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-3d-primary.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-advanced-axial-primary.svg b/platform/ui/src/assets/icons/layout-advanced-axial-primary.svg
new file mode 100644
index 000000000..79a34077a
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-axial-primary.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-advanced-mpr.svg b/platform/ui/src/assets/icons/layout-advanced-mpr.svg
new file mode 100644
index 000000000..d23b2fbf4
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-advanced-mpr.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-common-1x1.svg b/platform/ui/src/assets/icons/layout-common-1x1.svg
new file mode 100644
index 000000000..537c7a86c
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-common-1x1.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-common-1x2.svg b/platform/ui/src/assets/icons/layout-common-1x2.svg
new file mode 100644
index 000000000..db5aca362
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-common-1x2.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-common-2x2.svg b/platform/ui/src/assets/icons/layout-common-2x2.svg
new file mode 100644
index 000000000..8dfe00701
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-common-2x2.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/layout-common-2x3.svg b/platform/ui/src/assets/icons/layout-common-2x3.svg
new file mode 100644
index 000000000..3cb298eec
--- /dev/null
+++ b/platform/ui/src/assets/icons/layout-common-2x3.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/tool-3d-rotate.svg b/platform/ui/src/assets/icons/tool-3d-rotate.svg
new file mode 100644
index 000000000..20d190cad
--- /dev/null
+++ b/platform/ui/src/assets/icons/tool-3d-rotate.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/platform/ui/src/assets/icons/tool-layout.svg b/platform/ui/src/assets/icons/tool-layout.svg
index f225033dd..7e8bf1494 100644
--- a/platform/ui/src/assets/icons/tool-layout.svg
+++ b/platform/ui/src/assets/icons/tool-layout.svg
@@ -1,6 +1,21 @@
-
\ No newline at end of file
diff --git a/platform/ui/src/components/Icon/getIcon.js b/platform/ui/src/components/Icon/getIcon.js
index 47336987c..4940fb771 100644
--- a/platform/ui/src/components/Icon/getIcon.js
+++ b/platform/ui/src/components/Icon/getIcon.js
@@ -145,6 +145,20 @@ import oldTrash from './../../assets/icons/old-trash.svg';
import oldPlay from './../../assets/icons/old-play.svg';
import oldStop from './../../assets/icons/old-stop.svg';
+/** LAYOUT */
+
+import layoutAdvanced3DFourUp from './../../assets/icons/layout-advanced-3d-four-up.svg';
+import layoutAdvanced3DMain from './../../assets/icons/layout-advanced-3d-main.svg';
+import layoutAdvanced3DOnly from './../../assets/icons/layout-advanced-3d-only.svg';
+import layoutAdvanced3DPrimary from './../../assets/icons/layout-advanced-3d-primary.svg';
+import layoutAdvancedAxialPrimary from './../../assets/icons/layout-advanced-axial-primary.svg';
+import layoutAdvancedMPR from './../../assets/icons/layout-advanced-mpr.svg';
+import layoutCommon1x1 from './../../assets/icons/layout-common-1x1.svg';
+import layoutCommon1x2 from './../../assets/icons/layout-common-1x2.svg';
+import layoutCommon2x2 from './../../assets/icons/layout-common-2x2.svg';
+import layoutCommon2x3 from './../../assets/icons/layout-common-2x3.svg';
+import iconToolRotate from './../../assets/icons/tool-3d-rotate.svg';
+
/** New investigational use */
import investigationalUse from './../../assets/icons/illustration-investigational-use.svg';
@@ -256,6 +270,7 @@ const ICONS = {
'tool-freehand-line': toolFreehand,
'tool-freehand-polygon': toolFreehandPolygon,
'tool-polygon': toolPolygon,
+ 'tool-3d-rotate': iconToolRotate,
'edit-patient': editPatient,
'icon-mpr': iconMPR,
'icon-next-inactive': iconNextInactive,
@@ -295,6 +310,18 @@ const ICONS = {
'old-play': oldPlay,
'old-stop': oldStop,
+ /** LAYOUT */
+ 'layout-advanced-3d-four-up': layoutAdvanced3DFourUp,
+ 'layout-advanced-3d-main': layoutAdvanced3DMain,
+ 'layout-advanced-3d-only': layoutAdvanced3DOnly,
+ 'layout-advanced-3d-primary': layoutAdvanced3DPrimary,
+ 'layout-advanced-axial-primary': layoutAdvancedAxialPrimary,
+ 'layout-advanced-mpr': layoutAdvancedMPR,
+ 'layout-common-1x1': layoutCommon1x1,
+ 'layout-common-1x2': layoutCommon1x2,
+ 'layout-common-2x2': layoutCommon2x2,
+ 'layout-common-2x3': layoutCommon2x3,
+
/** New investigational use */
'illustration-investigational-use': investigationalUse,
};
diff --git a/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx b/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx
new file mode 100644
index 000000000..79ba6be15
--- /dev/null
+++ b/platform/ui/src/components/LayoutPreset/LayoutPreset.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Icon from '../Icon/Icon';
+
+function LayoutPreset({ onSelection, title, icon, commandOptions, classNames }) {
+ return (
+ {
+ onSelection(commandOptions);
+ }}
+ >
+
+ {title &&
{title}
}
+
+ );
+}
+
+LayoutPreset.defaultProps = {
+ onSelection: () => {},
+};
+
+LayoutPreset.propTypes = {
+ onSelection: PropTypes.func.isRequired,
+ title: PropTypes.string,
+ icon: PropTypes.string.isRequired,
+ commandOptions: PropTypes.object.isRequired,
+ classNames: PropTypes.string,
+};
+
+export default LayoutPreset;
diff --git a/platform/ui/src/components/LayoutPreset/index.js b/platform/ui/src/components/LayoutPreset/index.js
new file mode 100644
index 000000000..c7d10c306
--- /dev/null
+++ b/platform/ui/src/components/LayoutPreset/index.js
@@ -0,0 +1,2 @@
+import LayoutPreset from './LayoutPreset';
+export default LayoutPreset;
diff --git a/platform/ui/src/components/LayoutSelector/LayoutSelector.tsx b/platform/ui/src/components/LayoutSelector/LayoutSelector.tsx
index be90880d6..2271069ed 100644
--- a/platform/ui/src/components/LayoutSelector/LayoutSelector.tsx
+++ b/platform/ui/src/components/LayoutSelector/LayoutSelector.tsx
@@ -21,7 +21,6 @@ function LayoutSelector({ onSelection, rows, columns }) {
gridTemplateRows: gridSize.repeat(rows),
backgroundColor: '#090c29', // primary-dark
}}
- className="p-2"
>
{Array.apply(null, Array(rows * columns))
.map(function (_, i) {
@@ -30,12 +29,8 @@ function LayoutSelector({ onSelection, rows, columns }) {
.map(index => (
{
const x = index % columns;
const y = Math.floor(index / columns);
@@ -55,7 +50,7 @@ function LayoutSelector({ onSelection, rows, columns }) {
LayoutSelector.defaultProps = {
onSelection: () => {},
- columns: 3,
+ columns: 4,
rows: 3,
};
diff --git a/platform/ui/src/components/ToolbarButton/ToolbarButton.tsx b/platform/ui/src/components/ToolbarButton/ToolbarButton.tsx
index 9665a8573..804f2df34 100644
--- a/platform/ui/src/components/ToolbarButton/ToolbarButton.tsx
+++ b/platform/ui/src/components/ToolbarButton/ToolbarButton.tsx
@@ -16,6 +16,7 @@ const ToolbarButton = ({
className,
size,
toolTipClassName,
+ disableToolTip = false,
...rest
//
}) => {
@@ -37,6 +38,7 @@ const ToolbarButton = ({
content={shouldShowDropdown ? dropdownContent : label}
tight={shouldShowDropdown}
className={toolTipClassNameToUse}
+ isDisabled={disableToolTip}
>