import { hotkeys } from '@ohif/core'; import { id } from './id'; import toolbarButtons from './toolbarButtons'; import initToolGroups from './initToolGroups'; const ohif = { layout: '@ohif/extension-default.layoutTemplateModule.viewerLayout', sopClassHandler: '@ohif/extension-default.sopClassHandlerModule.stack', hangingProtocol: '@ohif/extension-default.hangingProtocolModule.default', leftPanel: '@ohif/extension-default.panelModule.seriesList', rightPanel: '@ohif/extension-default.panelModule.measure', }; const cornerstone = { viewport: '@ohif/extension-cornerstone.viewportModule.cornerstone', }; const segmentation = { panel: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentation', panelTool: '@ohif/extension-cornerstone-dicom-seg.panelModule.panelSegmentationWithTools', sopClassHandler: '@ohif/extension-cornerstone-dicom-seg.sopClassHandlerModule.dicom-seg', viewport: '@ohif/extension-cornerstone-dicom-seg.viewportModule.dicom-seg', }; /** * Just two dependencies to be able to render a viewport with panels in order * to make sure that the mode is working. */ const extensionDependencies = { '@ohif/extension-default': '^3.0.0', '@ohif/extension-cornerstone': '^3.0.0', '@ohif/extension-cornerstone-dicom-seg': '^3.0.0', }; function modeFactory({ modeConfiguration }) { return { /** * Mode ID, which should be unique among modes used by the viewer. This ID * is used to identify the mode in the viewer's state. */ id, routeName: 'segmentation', /** * Mode name, which is displayed in the viewer's UI in the workList, for the * user to select the mode. */ displayName: 'Segmentation', /** * Runs when the Mode Route is mounted to the DOM. Usually used to initialize * Services and other resources. */ onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => { const { measurementService, toolbarService, toolGroupService } = servicesManager.services; measurementService.clearMeasurements(); // Init Default and SR ToolGroups initToolGroups(extensionManager, toolGroupService, commandsManager); let unsubscribe; const activateTool = () => { toolbarService.recordInteraction({ groupId: 'WindowLevel', interactionType: 'tool', commands: [ { commandName: 'setToolActive', commandOptions: { toolName: 'WindowLevel', }, context: 'CORNERSTONE', }, ], }); // We don't need to reset the active tool whenever a viewport is getting // added to the toolGroup. unsubscribe(); }; // Since we only have one viewport for the basic cs3d mode and it has // only one hanging protocol, we can just use the first viewport ({ unsubscribe } = toolGroupService.subscribe( toolGroupService.EVENTS.VIEWPORT_ADDED, activateTool )); toolbarService.init(extensionManager); toolbarService.addButtons(toolbarButtons); toolbarService.createButtonSection('primary', [ 'Zoom', 'WindowLevel', 'Pan', 'Capture', 'Layout', 'MPR', 'Crosshairs', 'MoreTools', ]); }, onModeExit: ({ servicesManager }) => { const { toolGroupService, syncGroupService, toolbarService, segmentationService, cornerstoneViewportService, } = servicesManager.services; toolGroupService.destroy(); syncGroupService.destroy(); segmentationService.destroy(); cornerstoneViewportService.destroy(); }, /** */ validationTags: { study: [], series: [], }, /** * A boolean return value that indicates whether the mode is valid for the * modalities of the selected studies. Currently we don't have stack viewport * segmentations and we should exclude them */ isValidMode: ({ modalities }) => { // Don't show the mode if the selected studies have only one modality // that is not supported by the mode const modalitiesArray = modalities.split('\\'); if (modalitiesArray.length === 1) { return !['SM', 'US', 'MG', 'OT', 'DOC', 'CR'].includes(modalitiesArray[0]); } return true; }, /** * Mode Routes are used to define the mode's behavior. A list of Mode Route * that includes the mode's path and the layout to be used. The layout will * include the components that are used in the layout. For instance, if the * default layoutTemplate is used (id: '@ohif/extension-default.layoutTemplateModule.viewerLayout') * it will include the leftPanels, rightPanels, and viewports. However, if * you define another layoutTemplate that includes a Footer for instance, * you should provide the Footer component here too. Note: We use Strings * to reference the component's ID as they are registered in the internal * ExtensionManager. The template for the string is: * `${extensionId}.{moduleType}.${componentId}`. */ routes: [ { path: 'template', layoutTemplate: ({ location, servicesManager }) => { return { id: ohif.layout, props: { leftPanels: [ohif.leftPanel], rightPanels: [segmentation.panelTool], viewports: [ { namespace: cornerstone.viewport, displaySetsToDisplay: [ohif.sopClassHandler], }, { namespace: segmentation.viewport, displaySetsToDisplay: [segmentation.sopClassHandler], }, ], }, }; }, }, ], /** List of extensions that are used by the mode */ extensions: extensionDependencies, /** HangingProtocol used by the mode */ // hangingProtocol: [''], /** SopClassHandlers used by the mode */ sopClassHandlers: [ohif.sopClassHandler, segmentation.sopClassHandler], /** hotkeys for mode */ hotkeys: [...hotkeys.defaults.hotkeyBindings], }; } const mode = { id, modeFactory, extensionDependencies, }; export default mode;