From 6e873cc92a16bea9ebbbd39318bcac5435b27af3 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Thu, 25 Jun 2020 17:00:42 -0400 Subject: [PATCH 1/9] Expose ViewportGridService API methods to extensions --- platform/core/src/index.js | 7 +- .../ViewportGridService.js | 54 +++++++ .../src/services/ViewportGridService/index.js | 3 + platform/core/src/services/index.js | 2 + .../contextProviders/ViewportGridProvider.jsx | 141 ++++++++++++++++-- platform/viewer/src/App.jsx | 50 +------ platform/viewer/src/appInit.js | 2 + 7 files changed, 199 insertions(+), 60 deletions(-) create mode 100644 platform/core/src/services/ViewportGridService/ViewportGridService.js diff --git a/platform/core/src/index.js b/platform/core/src/index.js index 9ffa1c70a..acfdd3fbf 100644 --- a/platform/core/src/index.js +++ b/platform/core/src/index.js @@ -30,8 +30,9 @@ import { // DicomMetadataStore, DisplaySetService, - ToolBarSerivce, + ToolBarSerivce, // TODO: Typo MeasurementService, + ViewportGridService, } from './services'; import IWebApiDataSource from './DataSources/IWebApiDataSource'; @@ -70,7 +71,8 @@ const OHIF = { UIViewportDialogService, DisplaySetService, MeasurementService, - ToolBarSerivce, + ToolBarSerivce, // TODO: TYPO + ViewportGridService, IWebApiDataSource, DicomMetadataStore, // @@ -112,6 +114,7 @@ export { DisplaySetService, MeasurementService, ToolBarSerivce, + ViewportGridService, IWebApiDataSource, DicomMetadataStore, ViewModelProvider, diff --git a/platform/core/src/services/ViewportGridService/ViewportGridService.js b/platform/core/src/services/ViewportGridService/ViewportGridService.js new file mode 100644 index 000000000..b4b213969 --- /dev/null +++ b/platform/core/src/services/ViewportGridService/ViewportGridService.js @@ -0,0 +1,54 @@ +const name = 'ViewportGridService'; + +const publicAPI = { + name, + hide: _hide, + show: _show, + setServiceImplementation, +}; + +const serviceImplementation = { + _hide: () => console.warn('hide() NOT IMPLEMENTED'), + _show: () => console.warn('show() NOT IMPLEMENTED'), +}; + +function _show({ viewportIndex, type, message, actions, onSubmit }) { + return serviceImplementation._show({ + viewportIndex, + type, + message, + actions, + onSubmit, + }); +} + +function _hide() { + return serviceImplementation._hide(); +} + +function setServiceImplementation({ + hide: hideImplementation, + show: showImplementation, +}) { + if (hideImplementation) { + serviceImplementation._hide = hideImplementation; + } + if (showImplementation) { + serviceImplementation._show = showImplementation; + } +} + +export default { + name, + create: ({ configuration = {} }) => { + return publicAPI; + }, +}; + +// initialState={{ +// numRows: 1, +// numCols: 1, +// viewports: [], +// activeViewportIndex: 0, +// }} +// reducer={viewportGridReducer} diff --git a/platform/core/src/services/ViewportGridService/index.js b/platform/core/src/services/ViewportGridService/index.js index e69de29bb..47d083531 100644 --- a/platform/core/src/services/ViewportGridService/index.js +++ b/platform/core/src/services/ViewportGridService/index.js @@ -0,0 +1,3 @@ +import ViewportGridService from './ViewportGridService'; + +export default ViewportGridService; diff --git a/platform/core/src/services/index.js b/platform/core/src/services/index.js index 96ecfb4d5..3862a2554 100644 --- a/platform/core/src/services/index.js +++ b/platform/core/src/services/index.js @@ -7,6 +7,7 @@ import UIViewportDialogService from './UIViewportDialogService'; import DicomMetadataStore from './DicomMetadataStore'; import DisplaySetService from './DisplaySetService'; import ToolBarSerivce from './ToolBarService'; +import ViewportGridService from './ViewportGridService'; export { MeasurementService, @@ -18,4 +19,5 @@ export { DicomMetadataStore, DisplaySetService, ToolBarSerivce, + ViewportGridService, }; diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx index c56268cc4..b718d5145 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx @@ -1,20 +1,141 @@ -import React, { createContext, useContext, useReducer } from 'react'; - -// export const VIEWPORT_GRID_DEFAULT_VALUE = { -// numCols: 1, -// numRows: 1, -// activeViewportIndex: 0, -// viewports: [], -// }; +import React, { + createContext, + useCallback, + useContext, + useEffect, + useReducer, +} from 'react'; +import PropTypes from 'prop-types'; export const ViewportGridContext = createContext(); -export function ViewportGridProvider({ reducer, initialState, children }) { +// export function ViewportGridProvider({ reducer, initialState, children }) { +// return ( +// +// {children} +// +// ); +// } + +export function ViewportGridProvider({ children, service }) { + const DEFAULT_STATE = { + numRows: 1, + numCols: 1, + viewports: [], + activeViewportIndex: 0, + }; + + const viewportGridReducer = (state, action) => { + switch (action.type) { + case 'SET_ACTIVE_VIEWPORT_INDEX': + return { ...state, ...{ activeViewportIndex: action.payload } }; + case 'SET_DISPLAYSET_FOR_VIEWPORT': { + const { viewportIndex, displaySetInstanceUID } = action.payload; + const viewports = state.viewports.slice(); + + viewports[viewportIndex] = { displaySetInstanceUID }; + + return { ...state, ...{ viewports } }; + } + case 'SET_LAYOUT': { + const { numCols, numRows } = action.payload; + const numPanes = numCols * numRows; + const viewports = state.viewports.slice(); + const activeViewportIndex = + state.activeViewportIndex >= numPanes ? 0 : state.activeViewportIndex; + + while (viewports.length < numPanes) { + viewports.push({}); + } + while (viewports.length > numPanes) { + viewports.pop(); + } + + return { + ...state, + ...{ activeViewportIndex, numCols, numRows, viewports }, + }; + } + default: + return action.payload; + } + }; + + const [viewportGridState, dispatch] = useReducer( + DEFAULT_STATE, + viewportGridReducer + ); + + const getState = useCallback(() => viewportGridState, [viewportGridState]); + const setActiveViewportIndex = useCallback( + index => dispatch({ type: 'SET_ACTIVE_VIEWPORT_INDEX', payload: index }), + [dispatch] + ); + const setDisplaysetForViewport = useCallback( + ({ viewportIndex, displaySetInstanceUID }) => + dispatch({ + type: 'SET_DISPLAYSET_FOR_VIEWPORT', + payload: { + viewportIndex, + displaySetInstanceUID, + }, + }), + [dispatch] + ); + + const setLayout = useCallback( + ({ numCols, numRows }) => + dispatch({ + type: 'SET_LAYOUT', + payload: { + numCols, + numRows, + }, + }), + [dispatch] + ); + + /** + * Sets the implementation of a modal service that can be used by extensions. + * + * @returns void + */ + useEffect(() => { + if (service) { + service.setServiceImplementation({ + getState, + setActiveViewportIndex, + setDisplaysetForViewport, + setLayout, + }); + } + }, [ + getState, + service, + setActiveViewportIndex, + setDisplaysetForViewport, + setLayout, + ]); + + const api = { + // getState, + setActiveViewportIndex, + setDisplaysetForViewport, + setLayout, + }; + return ( - + {children} ); } +ViewportGridProvider.propTypes = { + children: PropTypes.any, + service: PropTypes.shape({ + setServiceImplementation: PropTypes.func, + }).isRequired, +}; + export const useViewportGrid = () => useContext(ViewportGridContext); diff --git a/platform/viewer/src/App.jsx b/platform/viewer/src/App.jsx index 969977107..01f1e3a3d 100644 --- a/platform/viewer/src/App.jsx +++ b/platform/viewer/src/App.jsx @@ -54,60 +54,14 @@ function App({ config, defaultExtensions }) { UIModalService, UINotificationService, UIViewportDialogService, + ViewportGridService, // TODO: Should this be a "UI" Service? } = servicesManager.services; - // A UI Service may need to use the ViewportGrid context - const viewportGridReducer = (state, action) => { - console.log(state, action); - - switch (action.type) { - case 'SET_ACTIVE_VIEWPORT_INDEX': - return { ...state, ...{ activeViewportIndex: action.payload } }; - case 'SET_DISPLAYSET_FOR_VIEWPORT': { - const { viewportIndex, displaySetInstanceUID } = action.payload; - const viewports = state.viewports.slice(); - - viewports[viewportIndex] = { displaySetInstanceUID }; - - return { ...state, ...{ viewports } }; - } - case 'SET_LAYOUT': { - const { numCols, numRows } = action.payload; - const numPanes = numCols * numRows; - const viewports = state.viewports.slice(); - const activeViewportIndex = - state.activeViewportIndex >= numPanes ? 0 : state.activeViewportIndex; - - while (viewports.length < numPanes) { - viewports.push({}); - } - while (viewports.length > numPanes) { - viewports.pop(); - } - - return { - ...state, - ...{ activeViewportIndex, numCols, numRows, viewports }, - }; - } - default: - return action.payload; - } - }; - return ( - + diff --git a/platform/viewer/src/appInit.js b/platform/viewer/src/appInit.js index ef8c16641..2f5433f54 100644 --- a/platform/viewer/src/appInit.js +++ b/platform/viewer/src/appInit.js @@ -10,6 +10,7 @@ import { MeasurementService, DisplaySetService, ToolBarSerivce, + ViewportGridService, // utils, // redux as reduxOHIF, } from '@ohif/core'; @@ -51,6 +52,7 @@ function appInit(appConfigOrFunc, defaultExtensions) { MeasurementService, DisplaySetService, ToolBarSerivce, + ViewportGridService, ]); /** From dfbf32fe43cc8e4e4047622875aa9d30cf561ba0 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Thu, 25 Jun 2020 17:02:10 -0400 Subject: [PATCH 2/9] Add "todo" notes for next work day --- platform/ui/src/contextProviders/ViewportGridProvider.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx index b718d5145..480114d61 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx @@ -139,3 +139,8 @@ ViewportGridProvider.propTypes = { }; export const useViewportGrid = () => useContext(ViewportGridContext); + +// TODO: +// - Update dependents of `useViewportGrid` to use new API instead of generic `dispatch` +// - Update `@ohif/core` interface `setServiceImplementation` to accomodate defined API methods +// - Update `@ohif/ext-cornerstone` commands to use new service to get the activeViewportIndex and restore command functionality From 3993c1270140895ce312c4e0907428375acab208 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 13:28:30 -0400 Subject: [PATCH 3/9] Update dependents to use new exposed service --- .../default/src/Toolbar/ToolbarLayoutSelector.jsx | 10 ++-------- .../dicom-sr/src/OHIFCornerstoneSRViewport.js | 2 +- .../PanelStudyBrowserTracking.jsx | 5 +---- .../src/viewports/TrackedCornerstoneViewport.js | 5 +---- platform/viewer/src/components/ViewportGrid.jsx | 15 +++++++-------- 5 files changed, 12 insertions(+), 25 deletions(-) diff --git a/extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx b/extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx index 36236b93b..aac3b1151 100644 --- a/extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx +++ b/extensions/default/src/Toolbar/ToolbarLayoutSelector.jsx @@ -7,7 +7,7 @@ import { function LayoutSelector() { const [isOpen, setIsOpen] = useState(false); - const [viewportGridState, dispatch] = useViewportGrid(); + const [viewportGridState, viewportGridService] = useViewportGrid(); useEffect(() => { function closeOnOutsideClick() { @@ -35,13 +35,7 @@ function LayoutSelector() { DropdownContent !== null && ( { - dispatch({ - type: 'SET_LAYOUT', - payload: { - numCols, - numRows, - }, - }); + viewportGridService.setLayout({ numCols, numRows }); }} /> ) diff --git a/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js b/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js index dfc685e43..d17ec1469 100644 --- a/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js +++ b/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js @@ -25,7 +25,7 @@ function OHIFCornerstoneSRViewport({ viewportIndex, DisplaySetService, }) { - const [viewportGrid, dispatchViewportGrid] = useViewportGrid(); + const [viewportGrid, viewportGridService] = useViewportGrid(); const [measurementSelected, setMeasurementSelected] = useState(0); const [measurementCount, setMeasurementCount] = useState(1); const [viewportData, setViewportData] = useState(null); diff --git a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.jsx b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.jsx index d33724702..e13e9d504 100644 --- a/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.jsx +++ b/extensions/measurement-tracking/src/panels/PanelStudyBrowserTracking/PanelStudyBrowserTracking.jsx @@ -19,10 +19,7 @@ function PanelStudyBrowserTracking({ // doesn't have to have such an intense shape. This works well enough for now. // Tabs --> Studies --> DisplaySets --> Thumbnails const [{ StudyInstanceUIDs }, dispatchImageViewer] = useImageViewer(); - const [ - { activeViewportIndex, viewports }, - dispatchViewportGrid, - ] = useViewportGrid(); + const [{ activeViewportIndex, viewports }] = useViewportGrid(); const [ trackedMeasurements, sendTrackedMeasurementsEvent, diff --git a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js index c582bd929..224e3bb4a 100644 --- a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js +++ b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js @@ -41,10 +41,7 @@ function TrackedCornerstoneViewport({ }) { const [trackedMeasurements] = useTrackedMeasurements(); - const [ - { activeViewportIndex, viewports }, - dispatchViewportGrid, - ] = useViewportGrid(); + const [{ activeViewportIndex, viewports }] = useViewportGrid(); // viewportIndex, onSubmit const [viewportDialogState, viewportDialogApi] = useViewportDialog(); const [viewportData, setViewportData] = useState(null); diff --git a/platform/viewer/src/components/ViewportGrid.jsx b/platform/viewer/src/components/ViewportGrid.jsx index fa7a6c7e4..50dfab8bb 100644 --- a/platform/viewer/src/components/ViewportGrid.jsx +++ b/platform/viewer/src/components/ViewportGrid.jsx @@ -10,11 +10,13 @@ function ViewerViewportGrid(props) { const { servicesManager, viewportComponents, dataSource } = props; const [ { numCols, numRows, activeViewportIndex, viewports }, - dispatch, + viewportGridService, ] = useViewportGrid(); + debugger; + const setActiveViewportIndex = index => { - dispatch({ type: 'SET_ACTIVE_VIEWPORT_INDEX', payload: index }); + viewportGridService.setActiveViewportIndex(index); }; // TODO -> Need some way of selecting which displaySets hit the viewports. @@ -71,12 +73,9 @@ function ViewerViewportGrid(props) { // ]); const onDropHandler = (viewportIndex, { displaySetInstanceUID }) => { console.warn(`DROPPED: ${displaySetInstanceUID}`); - dispatch({ - type: 'SET_DISPLAYSET_FOR_VIEWPORT', - payload: { - viewportIndex, - displaySetInstanceUID, - }, + viewportGridService.setDisplaysetForViewport({ + viewportIndex, + displaySetInstanceUID, }); }; From 077143bd4ad8e2444d5061be0cfa1cba9646c57b Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 13:28:50 -0400 Subject: [PATCH 4/9] Update ViewportGridService interface --- .../ViewportGridService.js | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/platform/core/src/services/ViewportGridService/ViewportGridService.js b/platform/core/src/services/ViewportGridService/ViewportGridService.js index b4b213969..662d543b9 100644 --- a/platform/core/src/services/ViewportGridService/ViewportGridService.js +++ b/platform/core/src/services/ViewportGridService/ViewportGridService.js @@ -2,39 +2,56 @@ const name = 'ViewportGridService'; const publicAPI = { name, - hide: _hide, - show: _show, + getState: _getState, + setActiveViewportIndex: _setActiveViewportIndex, + setDisplaysetForViewport: _setDisplaysetForViewport, + setLayout: _setLayout, setServiceImplementation, }; const serviceImplementation = { - _hide: () => console.warn('hide() NOT IMPLEMENTED'), - _show: () => console.warn('show() NOT IMPLEMENTED'), + _getState: () => console.warn('getState() NOT IMPLEMENTED'), + _setActiveViewportIndex: () => console.warn('setActiveViewportIndex() NOT IMPLEMENTED'), + _setDisplaysetForViewport: () => console.warn('setDisplaysetForViewport() NOT IMPLEMENTED'), + _setLayout: () => console.warn('setLayout() NOT IMPLEMENTED'), }; -function _show({ viewportIndex, type, message, actions, onSubmit }) { - return serviceImplementation._show({ +function _getState() { + return serviceImplementation._getState(); +} + +function _setActiveViewportIndex(index) { + return serviceImplementation._setActiveViewportIndex(index); +} + +function _setDisplaysetForViewport({ viewportIndex, displaySetInstanceUID }) { + return serviceImplementation._setDisplaysetForViewport({ viewportIndex, - type, - message, - actions, - onSubmit, + displaySetInstanceUID, }); } -function _hide() { - return serviceImplementation._hide(); +function _setLayout({ numCols, numRows }) { + return serviceImplementation._setLayout({ numCols, numRows }); } function setServiceImplementation({ - hide: hideImplementation, - show: showImplementation, + getState: getStateImplementation, + setActiveViewportIndex: setActiveViewportIndexImplementation, + setDisplaysetForViewport: setDisplaysetForViewportImplementation, + setLayout: setLayoutImplementation, }) { - if (hideImplementation) { - serviceImplementation._hide = hideImplementation; + if (getStateImplementation) { + serviceImplementation._getState = getStateImplementation; } - if (showImplementation) { - serviceImplementation._show = showImplementation; + if (setActiveViewportIndexImplementation) { + serviceImplementation._setActiveViewportIndex = setActiveViewportIndexImplementation; + } + if (setDisplaysetForViewportImplementation) { + serviceImplementation._setDisplaysetForViewport = setDisplaysetForViewportImplementation; + } + if (setLayoutImplementation) { + serviceImplementation._setLayout = setLayoutImplementation; } } @@ -44,11 +61,3 @@ export default { return publicAPI; }, }; - -// initialState={{ -// numRows: 1, -// numCols: 1, -// viewports: [], -// activeViewportIndex: 0, -// }} -// reducer={viewportGridReducer} From aa4e88c2fa1e767f49e5dd417417367b292e77a0 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 13:29:10 -0400 Subject: [PATCH 5/9] Set initial state for provider; fix useReducer usage --- .../contextProviders/ViewportGridProvider.jsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx index 480114d61..0dadaaa0c 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx @@ -7,7 +7,14 @@ import React, { } from 'react'; import PropTypes from 'prop-types'; -export const ViewportGridContext = createContext(); +const DEFAULT_STATE = { + numRows: 1, + numCols: 1, + viewports: [], + activeViewportIndex: 0, +}; + +export const ViewportGridContext = createContext(DEFAULT_STATE); // export function ViewportGridProvider({ reducer, initialState, children }) { // return ( @@ -18,13 +25,6 @@ export const ViewportGridContext = createContext(); // } export function ViewportGridProvider({ children, service }) { - const DEFAULT_STATE = { - numRows: 1, - numCols: 1, - viewports: [], - activeViewportIndex: 0, - }; - const viewportGridReducer = (state, action) => { switch (action.type) { case 'SET_ACTIVE_VIEWPORT_INDEX': @@ -62,8 +62,8 @@ export function ViewportGridProvider({ children, service }) { }; const [viewportGridState, dispatch] = useReducer( + viewportGridReducer, DEFAULT_STATE, - viewportGridReducer ); const getState = useCallback(() => viewportGridState, [viewportGridState]); From 8607659501f106e3084eeca544d45833e4a56f76 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 13:51:27 -0400 Subject: [PATCH 6/9] Test that we can access activeViewportIndex from extension --- extensions/cornerstone/src/commandsModule.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/cornerstone/src/commandsModule.js b/extensions/cornerstone/src/commandsModule.js index a1d799b86..eab81fad5 100644 --- a/extensions/cornerstone/src/commandsModule.js +++ b/extensions/cornerstone/src/commandsModule.js @@ -11,6 +11,8 @@ const { studyMetadataManager } = OHIF.utils; const { setViewportSpecificData } = OHIF.redux.actions; const commandsModule = ({ servicesManager }) => { + const { ViewportGridService } = servicesManager.services; + const actions = { getCornerstoneLibraries: () => { return { cornerstone, cornerstoneTools }; @@ -66,7 +68,7 @@ const commandsModule = ({ servicesManager }) => { } }, invertViewport: () => { - const activeViewportIndex = 0; + const { activeViewportIndex } = ViewportGridService.getState(); const enabledElement = getEnabledElement(activeViewportIndex); if (enabledElement) { From c6ec439331be6ad59a25dd59a990a9016af222b6 Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 14:14:25 -0400 Subject: [PATCH 7/9] Make sure primary cornerstone extension has references to enabled elements --- extensions/cornerstone/src/init.js | 19 +++++++++++++++++++ .../viewports/TrackedCornerstoneViewport.js | 12 ++++++++++++ .../viewer/src/components/ViewportGrid.jsx | 2 -- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/extensions/cornerstone/src/init.js b/extensions/cornerstone/src/init.js index 5f80a9d6f..a3fdf065c 100644 --- a/extensions/cornerstone/src/init.js +++ b/extensions/cornerstone/src/init.js @@ -6,6 +6,8 @@ import merge from 'lodash.merge'; import initCornerstoneTools from './initCornerstoneTools.js'; import initWADOImageLoader from './initWADOImageLoader.js'; import measurementServiceMappingsFactory from './utils/measurementServiceMappings/measurementServiceMappingsFactory'; +// +import { setEnabledElement } from './state'; /** * @@ -54,6 +56,23 @@ export default function init({ servicesManager, configuration }) { }; initCornerstoneTools(defaultCsToolsConfig); + // TODO: Extensions are still registered at time of registration globally + // These should be registered as a part of mode route spin up, + // and they need to self-clean on mode route destroy + // THIS + // is a way for extensions that "depend" on this extension to notify it of + // new cornerstone enabled elements so it's commands continue to work. + const handleOhifCornerstoneEnabledElementEvent = function(evt) { + const { viewportIndex, enabledElement } = evt.detail; + + console.log(evt, viewportIndex, enabledElement); + setEnabledElement(viewportIndex, enabledElement); + }; + + document.addEventListener( + 'ohif-cornerstone-enabled-element-event', + handleOhifCornerstoneEnabledElementEvent + ); const toolsGroupedByType = { touch: [csTools.PanMultiTouchTool, csTools.ZoomTouchPinchTool], diff --git a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js index 224e3bb4a..c76efba79 100644 --- a/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js +++ b/extensions/measurement-tracking/src/viewports/TrackedCornerstoneViewport.js @@ -122,6 +122,18 @@ function TrackedCornerstoneViewport({ } setElement(targetElement); + + const OHIFCornerstoneEnabledElementEvent = new CustomEvent( + 'ohif-cornerstone-enabled-element-event', + { + detail: { + enabledElement: targetElement, + viewportIndex, + }, + } + ); + + document.dispatchEvent(OHIFCornerstoneEnabledElementEvent); }; useEffect(() => { diff --git a/platform/viewer/src/components/ViewportGrid.jsx b/platform/viewer/src/components/ViewportGrid.jsx index 50dfab8bb..c9300381f 100644 --- a/platform/viewer/src/components/ViewportGrid.jsx +++ b/platform/viewer/src/components/ViewportGrid.jsx @@ -13,8 +13,6 @@ function ViewerViewportGrid(props) { viewportGridService, ] = useViewportGrid(); - debugger; - const setActiveViewportIndex = index => { viewportGridService.setActiveViewportIndex(index); }; From 833915482007b3226ac341832e5977b8a049beab Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 14:17:45 -0400 Subject: [PATCH 8/9] Clean up old comments --- extensions/cornerstone/src/init.js | 1 - .../src/contextProviders/ViewportGridProvider.jsx | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/extensions/cornerstone/src/init.js b/extensions/cornerstone/src/init.js index a3fdf065c..e7b321935 100644 --- a/extensions/cornerstone/src/init.js +++ b/extensions/cornerstone/src/init.js @@ -65,7 +65,6 @@ export default function init({ servicesManager, configuration }) { const handleOhifCornerstoneEnabledElementEvent = function(evt) { const { viewportIndex, enabledElement } = evt.detail; - console.log(evt, viewportIndex, enabledElement); setEnabledElement(viewportIndex, enabledElement); }; diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.jsx b/platform/ui/src/contextProviders/ViewportGridProvider.jsx index 0dadaaa0c..fe77ef0a0 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.jsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.jsx @@ -16,14 +16,6 @@ const DEFAULT_STATE = { export const ViewportGridContext = createContext(DEFAULT_STATE); -// export function ViewportGridProvider({ reducer, initialState, children }) { -// return ( -// -// {children} -// -// ); -// } - export function ViewportGridProvider({ children, service }) { const viewportGridReducer = (state, action) => { switch (action.type) { @@ -139,8 +131,3 @@ ViewportGridProvider.propTypes = { }; export const useViewportGrid = () => useContext(ViewportGridContext); - -// TODO: -// - Update dependents of `useViewportGrid` to use new API instead of generic `dispatch` -// - Update `@ohif/core` interface `setServiceImplementation` to accomodate defined API methods -// - Update `@ohif/ext-cornerstone` commands to use new service to get the activeViewportIndex and restore command functionality From 33a2df6ad9bd53aebc1c5c2e5660b91ede3f067f Mon Sep 17 00:00:00 2001 From: dannyrb Date: Fri, 26 Jun 2020 14:22:45 -0400 Subject: [PATCH 9/9] Update all cornerstone commands --- extensions/cornerstone/src/commandsModule.js | 66 ++++++++++---------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/extensions/cornerstone/src/commandsModule.js b/extensions/cornerstone/src/commandsModule.js index eab81fad5..89ffa1bc4 100644 --- a/extensions/cornerstone/src/commandsModule.js +++ b/extensions/cornerstone/src/commandsModule.js @@ -13,12 +13,17 @@ const { setViewportSpecificData } = OHIF.redux.actions; const commandsModule = ({ servicesManager }) => { const { ViewportGridService } = servicesManager.services; + function _getActiveViewportsEnabledElement() { + const { activeViewportIndex } = ViewportGridService.getState(); + return getEnabledElement(activeViewportIndex); + } + const actions = { getCornerstoneLibraries: () => { return { cornerstone, cornerstoneTools }; }, - rotateViewport: ({ viewports, rotation }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + rotateViewport: ({ rotation }) => { + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { let viewport = cornerstone.getViewport(enabledElement); @@ -27,8 +32,7 @@ const commandsModule = ({ servicesManager }) => { } }, flipViewportHorizontal: () => { - const activeViewportIndex = 0; - const enabledElement = getEnabledElement(activeViewportIndex); + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { let viewport = cornerstone.getViewport(enabledElement); @@ -36,8 +40,8 @@ const commandsModule = ({ servicesManager }) => { cornerstone.setViewport(enabledElement, viewport); } }, - flipViewportVertical: ({ viewports }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + flipViewportVertical: () => { + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { let viewport = cornerstone.getViewport(enabledElement); @@ -45,8 +49,8 @@ const commandsModule = ({ servicesManager }) => { cornerstone.setViewport(enabledElement, viewport); } }, - scaleViewport: ({ direction, viewports }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + scaleViewport: ({ direction }) => { + const enabledElement = _getActiveViewportsEnabledElement(); const step = direction * 0.15; if (enabledElement) { @@ -60,16 +64,14 @@ const commandsModule = ({ servicesManager }) => { } }, resetViewport: () => { - const activeViewportIndex = 0; - const enabledElement = getEnabledElement(activeViewportIndex); + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { cornerstone.reset(enabledElement); } }, invertViewport: () => { - const { activeViewportIndex } = ViewportGridService.getState(); - const enabledElement = getEnabledElement(activeViewportIndex); + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { let viewport = cornerstone.getViewport(enabledElement); @@ -85,8 +87,8 @@ const commandsModule = ({ servicesManager }) => { } cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 }); }, - clearAnnotations: ({ viewports }) => { - const element = getEnabledElement(viewports.activeViewportIndex); + clearAnnotations: () => { + const element = _getActiveViewportsEnabledElement(); if (!element) { return; } @@ -141,16 +143,16 @@ const commandsModule = ({ servicesManager }) => { }); }); }, - nextImage: ({ viewports }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + nextImage: () => { + const enabledElement = _getActiveViewportsEnabledElement(); scroll(enabledElement, 1); }, - previousImage: ({ viewports }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + previousImage: () => { + const enabledElement = _getActiveViewportsEnabledElement(); scroll(enabledElement, -1); }, - getActiveViewportEnabledElement: ({ viewports }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + getActiveViewportEnabledElement: () => { + const enabledElement = _getActiveViewportsEnabledElement(); return enabledElement; }, showDownloadViewportModal: () => { @@ -253,8 +255,8 @@ const commandsModule = ({ servicesManager }) => { setCornerstoneLayout: () => { setCornerstoneLayout(); }, - setWindowLevel: ({ viewports, window, level }) => { - const enabledElement = getEnabledElement(viewports.activeViewportIndex); + setWindowLevel: ({ window, level }) => { + const enabledElement = _getActiveViewportsEnabledElement(); if (enabledElement) { let viewport = cornerstone.getViewport(enabledElement); @@ -328,7 +330,7 @@ const commandsModule = ({ servicesManager }) => { }, getActiveViewportEnabledElement: { commandFn: actions.getActiveViewportEnabledElement, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, rotateViewportCW: { @@ -338,7 +340,7 @@ const commandsModule = ({ servicesManager }) => { }, rotateViewportCCW: { commandFn: actions.rotateViewport, - storeContexts: ['viewports'], + storeContexts: [], options: { rotation: -90 }, }, invertViewport: { @@ -348,7 +350,7 @@ const commandsModule = ({ servicesManager }) => { }, flipViewportVertical: { commandFn: actions.flipViewportVertical, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, flipViewportHorizontal: { @@ -358,17 +360,17 @@ const commandsModule = ({ servicesManager }) => { }, scaleUpViewport: { commandFn: actions.scaleViewport, - storeContexts: ['viewports'], + storeContexts: [], options: { direction: 1 }, }, scaleDownViewport: { commandFn: actions.scaleViewport, - storeContexts: ['viewports'], + storeContexts: [], options: { direction: -1 }, }, fitViewportToWindow: { commandFn: actions.scaleViewport, - storeContexts: ['viewports'], + storeContexts: [], options: { direction: 0 }, }, resetViewport: { @@ -378,17 +380,17 @@ const commandsModule = ({ servicesManager }) => { }, clearAnnotations: { commandFn: actions.clearAnnotations, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, nextImage: { commandFn: actions.nextImage, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, previousImage: { commandFn: actions.previousImage, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, // TOOLS @@ -410,7 +412,7 @@ const commandsModule = ({ servicesManager }) => { }, setWindowLevel: { commandFn: actions.setWindowLevel, - storeContexts: ['viewports'], + storeContexts: [], options: {}, }, };