feat(grid): remove viewportIndex and only rely on viewportId (#3591)

Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
This commit is contained in:
AlirezaandBill Wallace authored and GitHub committed 2023-08-30 16:46:55 -04:00
1 parent 5dafac7c92
commit 4c6ff873e8
83 files changed
+1309 -1123

No files matched your search

@@ -63,6 +63,10 @@ function areEqual(prevProps, nextProps) {
return false;
}
if (nextProps.viewportOptions.needsRerendering) {
return false;
}
const prevDisplaySets = prevProps.displaySets;
const nextDisplaySets = nextProps.displaySets;
@@ -107,7 +111,6 @@ function areEqual(prevProps, nextProps) {
// Then we don't need to worry about the re-renders if the props change.
const OHIFCornerstoneViewport = React.memo(props => {
const {
viewportIndex,
displaySets,
dataSource,
viewportOptions,
@@ -123,6 +126,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
initialImageIndex,
} = props;
const viewportId = viewportOptions.viewportId;
const [scrollbarHeight, setScrollbarHeight] = useState('100px');
const [enabledVPElement, setEnabledVPElement] = useState(null);
const elementRef = useRef();
@@ -154,27 +158,24 @@ const OHIFCornerstoneViewport = React.memo(props => {
}
}, [elementRef]);
const cleanUpServices = useCallback(() => {
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
const cleanUpServices = useCallback(
viewportInfo => {
const renderingEngineId = viewportInfo.getRenderingEngineId();
const syncGroups = viewportInfo.getSyncGroups();
if (!viewportInfo) {
return;
}
toolGroupService.removeViewportFromToolGroup(
viewportId,
renderingEngineId
);
const viewportId = viewportInfo.getViewportId();
const renderingEngineId = viewportInfo.getRenderingEngineId();
const syncGroups = viewportInfo.getSyncGroups();
toolGroupService.removeViewportFromToolGroup(viewportId, renderingEngineId);
syncGroupService.removeViewportFromSyncGroup(
viewportId,
renderingEngineId,
syncGroups
);
}, [viewportIndex, viewportOptions.viewportId]);
syncGroupService.removeViewportFromSyncGroup(
viewportId,
renderingEngineId,
syncGroups
);
},
[viewportId]
);
const elementEnabledHandler = useCallback(
evt => {
@@ -187,9 +188,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
const viewportInfo = cornerstoneViewportService.getViewportInfo(
viewportId
);
const viewportIndex = viewportInfo.getViewportIndex();
setEnabledElement(viewportIndex, element);
setEnabledElement(viewportId, element);
setEnabledVPElement(element);
const renderingEngineId = viewportInfo.getRenderingEngineId();
@@ -212,16 +211,12 @@ const OHIFCornerstoneViewport = React.memo(props => {
onElementEnabled(evt);
}
},
[viewportIndex, onElementEnabled, toolGroupService]
[viewportId, onElementEnabled, toolGroupService]
);
// disable the element upon unmounting
useEffect(() => {
cornerstoneViewportService.enableViewport(
viewportIndex,
viewportOptions,
elementRef.current
);
cornerstoneViewportService.enableViewport(viewportId, elementRef.current);
eventTarget.addEventListener(
Enums.Events.ELEMENT_ENABLED,
@@ -231,17 +226,16 @@ const OHIFCornerstoneViewport = React.memo(props => {
setImageScrollBarHeight();
return () => {
commandsManager.runCommand('storePresentation', {
viewportIndex,
});
cleanUpServices();
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
const viewportInfo = cornerstoneViewportService.getViewportInfo(
viewportId
);
cornerstoneViewportService.disableElement(viewportIndex);
if (!viewportInfo) {
return;
}
cleanUpServices(viewportInfo);
cornerstoneViewportService.storePresentation({ viewportId });
if (onElementDisabled) {
onElementDisabled(viewportInfo);
@@ -273,8 +267,8 @@ const OHIFCornerstoneViewport = React.memo(props => {
return;
}
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
const viewportInfo = cornerstoneViewportService.getViewportInfo(
viewportId
);
if (viewportInfo.hasDisplaySet(invalidatedDisplaySetInstanceUID)) {
@@ -288,7 +282,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
const keepCamera = true;
cornerstoneViewportService.updateViewport(
viewportIndex,
viewportId,
newViewportData,
keepCamera
);
@@ -298,7 +292,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
return () => {
unsubscribe();
};
}, [viewportIndex]);
}, [viewportId]);
useEffect(() => {
// handle the default viewportType to be stack
@@ -329,15 +323,25 @@ const OHIFCornerstoneViewport = React.memo(props => {
lutPresentationStore[presentationIds?.lutPresentationId],
};
let measurement;
if (cacheJumpToMeasurementEvent?.viewportIndex === viewportIndex) {
if (cacheJumpToMeasurementEvent?.viewportId === viewportId) {
measurement = cacheJumpToMeasurementEvent.measurement;
// Delete the position presentation so that viewport navigates direct
presentations.positionPresentation = null;
cacheJumpToMeasurementEvent = null;
}
// Note: This is a hack to get the grid to re-render the OHIFCornerstoneViewport component
// Used for segmentation hydration right now, since the logic to decide whether
// a viewport needs to render a segmentation lives inside the CornerstoneViewportService
// so we need to re-render (force update via change of the needsRerendering) so that React
// does the diffing and decides we should render this again (although the id and element has not changed)
// so that the CornerstoneViewportService can decide whether to render the segmentation or not. Not that we reached here we can turn it off.
if (viewportOptions.needsRerendering) {
viewportOptions.needsRerendering = false;
}
cornerstoneViewportService.setViewportData(
viewportIndex,
viewportId,
viewportData,
viewportOptions,
displaySetOptions,
@@ -370,7 +374,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
measurementService,
displaySetService,
elementRef,
viewportIndex,
viewportId,
displaySets,
viewportGridService,
cornerstoneViewportService
@@ -380,7 +384,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
measurementService,
displaySetService,
elementRef,
viewportIndex,
viewportId,
displaySets,
viewportGridService,
cornerstoneViewportService
@@ -389,7 +393,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
return () => {
unsubscribeFromJumpToMeasurementEvents();
};
}, [displaySets, elementRef, viewportIndex]);
}, [displaySets, elementRef, viewportId]);
return (
<React.Fragment>
@@ -408,7 +412,7 @@ const OHIFCornerstoneViewport = React.memo(props => {
ref={elementRef}
></div>
<CornerstoneOverlays
viewportIndex={viewportIndex}
viewportId={viewportId}
toolBarService={toolbarService}
element={elementRef.current}
scrollbarHeight={scrollbarHeight}
@@ -416,12 +420,12 @@ const OHIFCornerstoneViewport = React.memo(props => {
/>
<CinePlayer
enabledVPElement={enabledVPElement}
viewportIndex={viewportIndex}
viewportId={viewportId}
servicesManager={servicesManager}
/>
</div>
<div className="absolute w-full">
{viewportDialogState.viewportIndex === viewportIndex && (
{viewportDialogState.viewportId === viewportId && (
<Notification
id="viewport-notification"
message={viewportDialogState.message}
@@ -440,37 +444,34 @@ function _subscribeToJumpToMeasurementEvents(
measurementService,
displaySetService,
elementRef,
viewportIndex,
viewportId,
displaySets,
viewportGridService,
cornerstoneViewportService
) {
const displaysUIDs = displaySets.map(
displaySet => displaySet.displaySetInstanceUID
);
const { unsubscribe } = measurementService.subscribe(
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT,
props => {
cacheJumpToMeasurementEvent = props;
const { viewportIndex: jumpIndex, measurement, isConsumed } = props;
const { viewportId: jumpId, measurement, isConsumed } = props;
if (!measurement || isConsumed) {
return;
}
if (cacheJumpToMeasurementEvent.cornerstoneViewport === undefined) {
// Decide on which viewport should handle this
cacheJumpToMeasurementEvent.cornerstoneViewport = cornerstoneViewportService.getViewportIndexToJump(
jumpIndex,
cacheJumpToMeasurementEvent.cornerstoneViewport = cornerstoneViewportService.getViewportIdToJump(
jumpId,
measurement.displaySetInstanceUID,
{ referencedImageId: measurement.referencedImageId }
);
}
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportIndex) {
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportId) {
return;
}
_jumpToMeasurement(
measurement,
elementRef,
viewportIndex,
viewportId,
measurementService,
displaySetService,
viewportGridService,
@@ -487,7 +488,7 @@ function _checkForCachedJumpToMeasurementEvents(
measurementService,
displaySetService,
elementRef,
viewportIndex,
viewportId,
displaySets,
viewportGridService,
cornerstoneViewportService
@@ -513,7 +514,7 @@ function _checkForCachedJumpToMeasurementEvents(
_jumpToMeasurement(
measurement,
elementRef,
viewportIndex,
viewportId,
measurementService,
displaySetService,
viewportGridService,
@@ -526,7 +527,7 @@ function _checkForCachedJumpToMeasurementEvents(
function _jumpToMeasurement(
measurement,
targetElementRef,
viewportIndex,
viewportId,
measurementService,
displaySetService,
viewportGridService,
@@ -548,13 +549,10 @@ function _jumpToMeasurement(
// to set it properly
// setCornerstoneMeasurementActive(measurement);
viewportGridService.setActiveViewportIndex(viewportIndex);
viewportGridService.setActiveViewportId(viewportId);
const enabledElement = getEnabledElement(targetElement);
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
if (enabledElement) {
// See how the jumpToSlice() of Cornerstone3D deals with imageIdx param.
const viewport = enabledElement.viewport as
@@ -621,7 +619,6 @@ OHIFCornerstoneViewport.defaultProps = {
};
OHIFCornerstoneViewport.propTypes = {
viewportIndex: PropTypes.number.isRequired,
displaySets: PropTypes.array.isRequired,
dataSource: PropTypes.object.isRequired,
viewportOptions: PropTypes.object,
@@ -6,7 +6,7 @@ import ViewportOrientationMarkers from './ViewportOrientationMarkers';
import ViewportImageSliceLoadingIndicator from './ViewportImageSliceLoadingIndicator';
function CornerstoneOverlays(props) {
const { viewportIndex, element, scrollbarHeight, servicesManager } = props;
const { viewportId, element, scrollbarHeight, servicesManager } = props;
const { cornerstoneViewportService } = servicesManager.services;
const [imageSliceData, setImageSliceData] = useState({
imageIndex: 0,
@@ -18,7 +18,7 @@ function CornerstoneOverlays(props) {
const { unsubscribe } = cornerstoneViewportService.subscribe(
cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED,
props => {
if (props.viewportIndex !== viewportIndex) {
if (props.viewportId !== viewportId) {
return;
}
@@ -29,16 +29,14 @@ function CornerstoneOverlays(props) {
return () => {
unsubscribe();
};
}, [viewportIndex]);
}, [viewportId]);
if (!element) {
return null;
}
if (viewportData) {
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
if (viewportInfo?.viewportOptions?.customViewportProps?.hideOverlays) {
return null;
@@ -48,7 +46,7 @@ function CornerstoneOverlays(props) {
return (
<div className="noselect">
<ViewportImageScrollbar
viewportIndex={viewportIndex}
viewportId={viewportId}
viewportData={viewportData}
element={element}
imageSliceData={imageSliceData}
@@ -60,7 +58,7 @@ function CornerstoneOverlays(props) {
<CustomizableViewportOverlay
imageSliceData={imageSliceData}
viewportData={viewportData}
viewportIndex={viewportIndex}
viewportId={viewportId}
servicesManager={servicesManager}
element={element}
/>
@@ -75,7 +73,7 @@ function CornerstoneOverlays(props) {
element={element}
viewportData={viewportData}
servicesManager={servicesManager}
viewportIndex={viewportIndex}
viewportId={viewportId}
/>
</div>
);
@@ -21,7 +21,6 @@ interface OverlayItemProps {
element: any;
viewportData: any;
imageSliceData: ImageSliceData;
viewportIndex: number | null;
servicesManager: ServicesManager;
instance: InstanceMetadata;
customization: any;
@@ -114,7 +113,7 @@ function CustomizableViewportOverlay({
element,
viewportData,
imageSliceData,
viewportIndex,
viewportId,
servicesManager,
}) {
const {
@@ -152,13 +151,13 @@ function CustomizableViewportOverlay({
if (viewportData != null) {
return _getInstanceNumber(
viewportData,
viewportIndex,
viewportId,
imageIndex,
cornerstoneViewportService
);
}
return null;
}, [viewportData, viewportIndex, imageIndex, cornerstoneViewportService]);
}, [viewportData, viewportId, imageIndex, cornerstoneViewportService]);
/**
* Initial toolbar state
@@ -192,7 +191,7 @@ function CustomizableViewportOverlay({
return () => {
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
};
}, [viewportIndex, viewportData, voi, element]);
}, [viewportId, viewportData, voi, element]);
/**
* Updating the scale when the viewport changes its zoom
@@ -205,8 +204,8 @@ function CustomizableViewportOverlay({
previousCamera.parallelScale !== camera.parallelScale ||
previousCamera.scale !== camera.scale
) {
const viewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const viewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
if (!viewport) {
@@ -237,7 +236,7 @@ function CustomizableViewportOverlay({
return () => {
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, updateScale);
};
}, [viewportIndex, viewportData, cornerstoneViewportService, element]);
}, [viewportId, viewportData, cornerstoneViewportService, element]);
/**
* Updating the active tools when the toolbar changes
@@ -262,7 +261,7 @@ function CustomizableViewportOverlay({
element,
viewportData,
imageSliceData,
viewportIndex,
viewportId,
servicesManager,
customization: item,
formatters: {
@@ -296,7 +295,7 @@ function CustomizableViewportOverlay({
element,
viewportData,
imageSliceData,
viewportIndex,
viewportId,
servicesManager,
customizationService,
instance,
@@ -390,7 +389,7 @@ function _getViewportInstance(viewportData, imageIndex) {
function _getInstanceNumber(
viewportData,
viewportIndex,
viewportId,
imageIndex,
cornerstoneViewportService
) {
@@ -406,7 +405,7 @@ function _getInstanceNumber(
instanceNumber = _getInstanceNumberFromVolume(
viewportData,
imageIndex,
viewportIndex,
viewportId,
cornerstoneViewportService
);
}
@@ -438,8 +437,7 @@ function _getInstanceNumberFromStack(viewportData, imageIndex) {
// Here we check if viewport is in the acquisition direction and if so, we get the instanceNumber
function _getInstanceNumberFromVolume(
viewportData,
imageIndex,
viewportIndex,
viewportId,
cornerstoneViewportService
) {
const volumes = viewportData.volumes;
@@ -452,8 +450,8 @@ function _getInstanceNumberFromVolume(
const volume = volumes[0];
const { direction, imageIds } = volume;
const cornerstoneViewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const cornerstoneViewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
if (!cornerstoneViewport) {
@@ -486,7 +484,7 @@ function _getInstanceNumberFromVolume(
CustomizableViewportOverlay.propTypes = {
viewportData: PropTypes.object,
imageIndex: PropTypes.number,
viewportIndex: PropTypes.number,
viewportId: PropTypes.string,
};
export default CustomizableViewportOverlay;
@@ -7,7 +7,7 @@ import { ServicesManger } from '@ohif/core';
function CornerstoneImageScrollbar({
viewportData,
viewportIndex,
viewportId,
element,
imageSliceData,
setImageSliceData,
@@ -19,12 +19,7 @@ function CornerstoneImageScrollbar({
cornerstoneViewportService,
} = (servicesManager as ServicesManger).services;
const onImageScrollbarChange = (imageIndex, viewportIndex) => {
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
const viewportId = viewportInfo.getViewportId();
const onImageScrollbarChange = (imageIndex, viewportId) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
@@ -34,7 +29,7 @@ function CornerstoneImageScrollbar({
if (isCineEnabled) {
// on image scrollbar change, stop the CINE if it is playing
cineService.stopClip(element);
cineService.setCine({ id: viewportIndex, isPlaying: false });
cineService.setCine({ id: viewportId, isPlaying: false });
}
csToolsUtils.jumpToSlice(viewport.element, {
@@ -48,8 +43,8 @@ function CornerstoneImageScrollbar({
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const viewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
if (!viewport) {
@@ -79,7 +74,7 @@ function CornerstoneImageScrollbar({
const { imageIndex, numberOfSlices } = sliceData;
setImageSliceData({ imageIndex, numberOfSlices });
}
}, [viewportIndex, viewportData]);
}, [viewportId, viewportData]);
useEffect(() => {
if (viewportData?.viewportType !== Enums.ViewportType.STACK) {
@@ -131,7 +126,7 @@ function CornerstoneImageScrollbar({
return (
<ImageScrollbar
onChange={evt => onImageScrollbarChange(evt, viewportIndex)}
onChange={evt => onImageScrollbarChange(evt, viewportId)}
max={
imageSliceData.numberOfSlices ? imageSliceData.numberOfSlices - 1 : 0
}
@@ -143,7 +138,7 @@ function CornerstoneImageScrollbar({
CornerstoneImageScrollbar.propTypes = {
viewportData: PropTypes.object,
viewportIndex: PropTypes.number.isRequired,
viewportId: PropTypes.string.isRequired,
element: PropTypes.instanceOf(Element),
scrollbarHeight: PropTypes.string,
imageSliceData: PropTypes.object.isRequired,
@@ -22,7 +22,7 @@ function ViewportOrientationMarkers({
element,
viewportData,
imageSliceData,
viewportIndex,
viewportId,
servicesManager,
orientationMarkers = ['top', 'left'],
}) {
@@ -114,9 +114,7 @@ function ViewportOrientationMarkers({
flipHorizontal
);
const ohifViewport = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
console.log('ViewportOrientationMarkers::No viewport');
@@ -11,7 +11,7 @@ function CornerstoneViewportOverlay({
element,
viewportData,
imageSliceData,
viewportIndex,
viewportId,
servicesManager,
}) {
const {
@@ -73,7 +73,7 @@ function CornerstoneViewportOverlay({
return () => {
element.removeEventListener(Enums.Events.VOI_MODIFIED, updateVOI);
};
}, [viewportIndex, viewportData, voi, element]);
}, [viewportId, viewportData, voi, element]);
/**
* Updating the scale when the viewport changes its zoom
@@ -86,8 +86,8 @@ function CornerstoneViewportOverlay({
previousCamera.parallelScale !== camera.parallelScale ||
previousCamera.scale !== camera.scale
) {
const viewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const viewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
if (!viewport) {
@@ -118,7 +118,7 @@ function CornerstoneViewportOverlay({
return () => {
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, updateScale);
};
}, [viewportIndex, viewportData]);
}, [viewportId, viewportData]);
const getTopLeftContent = useCallback(() => {
const { windowWidth, windowCenter } = voi;
@@ -168,7 +168,7 @@ function CornerstoneViewportOverlay({
instanceNumber = _getInstanceNumberFromVolume(
viewportData,
imageIndex,
viewportIndex,
viewportId,
cornerstoneViewportService
);
}
@@ -183,15 +183,13 @@ function CornerstoneViewportOverlay({
</span>
</div>
);
}, [imageSliceData, viewportData, viewportIndex]);
}, [imageSliceData, viewportData, viewportId]);
if (!viewportData) {
return null;
}
const ohifViewport = cornerstoneViewportService.getViewportInfoByIndex(
viewportIndex
);
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
return null;
@@ -240,7 +238,7 @@ function _getInstanceNumberFromStack(viewportData, imageIndex) {
function _getInstanceNumberFromVolume(
viewportData,
imageIndex,
viewportIndex,
viewportId,
cornerstoneViewportService
) {
const volumes = viewportData.volumes;
@@ -253,8 +251,8 @@ function _getInstanceNumberFromVolume(
const volume = volumes[0];
const { direction, imageIds } = volume;
const cornerstoneViewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const cornerstoneViewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
if (!cornerstoneViewport) {
@@ -287,7 +285,7 @@ function _getInstanceNumberFromVolume(
CornerstoneViewportOverlay.propTypes = {
viewportData: PropTypes.object,
imageIndex: PropTypes.number,
viewportIndex: PropTypes.number,
viewportId: PropTypes.string,
servicesManager: PropTypes.instanceOf(ServicesManager),
};
+33 -63
View File
@@ -239,8 +239,7 @@ function commandsModule({
return;
}
const viewportIndex = viewportInfo.getViewportIndex();
viewportGridService.setActiveViewportIndex(viewportIndex);
viewportGridService.setActiveViewportId(viewportId);
},
arrowTextCallback: ({ callback, data }) => {
callInputDialog(uiDialogService, data, callback);
@@ -310,9 +309,11 @@ function commandsModule({
}
}
const { viewports } = viewportGridService.getState() || {
viewports: [],
};
const { viewports } = viewportGridService.getState();
if (!viewports.size) {
return;
}
const toolGroup = toolGroupService.getToolGroup(toolGroupId);
const toolGroupViewportIds = toolGroup?.getViewportIds?.();
@@ -322,15 +323,11 @@ function commandsModule({
return;
}
const filteredViewports = viewports.filter(viewport => {
if (!viewport.viewportOptions) {
return false;
const filteredViewports = Array.from(viewports.values()).filter(
viewport => {
return toolGroupViewportIds.includes(viewport.viewportId);
}
return toolGroupViewportIds.includes(
viewport.viewportOptions.viewportId
);
});
);
if (!filteredViewports.length) {
return;
@@ -368,12 +365,10 @@ function commandsModule({
});
},
showDownloadViewportModal: () => {
const { activeViewportIndex } = viewportGridService.getState();
const { activeViewportId } = viewportGridService.getState();
if (
!cornerstoneViewportService.getCornerstoneViewportByIndex(
activeViewportIndex
)
!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)
) {
// Cannot download a non-cornerstone viewport (image).
uiNotificationService.show({
@@ -391,7 +386,7 @@ function commandsModule({
content: CornerstoneViewportDownloadForm,
title: 'Download High Quality Image',
contentProps: {
activeViewportIndex,
activeViewportId,
onClose: uiModalService.hide,
cornerstoneViewportService,
},
@@ -554,13 +549,13 @@ function commandsModule({
cstUtils.scroll(viewport, options);
},
setViewportColormap: ({
viewportIndex,
viewportId,
displaySetInstanceUID,
colormap,
immediate = false,
}) => {
const viewport = cornerstoneViewportService.getCornerstoneViewportByIndex(
viewportIndex
const viewport = cornerstoneViewportService.getCornerstoneViewport(
viewportId
);
const actorEntries = viewport.getActors();
@@ -577,17 +572,17 @@ function commandsModule({
viewport.render();
}
},
incrementActiveViewport: () => {
const { activeViewportIndex, viewports } = viewportGridService.getState();
const nextViewportIndex = (activeViewportIndex + 1) % viewports.length;
viewportGridService.setActiveViewportIndex(nextViewportIndex);
},
decrementActiveViewport: () => {
const { activeViewportIndex, viewports } = viewportGridService.getState();
changeActiveViewport: ({ direction = 1 }) => {
const { activeViewportId, viewports } = viewportGridService.getState();
const viewportIds = Array.from(viewports.keys());
const currentIndex = viewportIds.indexOf(activeViewportId);
const nextViewportIndex =
(activeViewportIndex - 1 + viewports.length) % viewports.length;
viewportGridService.setActiveViewportIndex(nextViewportIndex);
(currentIndex + direction + viewportIds.length) % viewportIds.length;
viewportGridService.setActiveViewportId(
viewportIds[nextViewportIndex] as string
);
},
toggleStackImageSync: ({ toggledState }) => {
toggleStackImageSync({
getEnabledElement,
@@ -596,9 +591,9 @@ function commandsModule({
});
},
toggleReferenceLines: ({ toggledState }) => {
const { activeViewportIndex } = viewportGridService.getState();
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
activeViewportIndex
const { activeViewportId } = viewportGridService.getState();
const viewportInfo = cornerstoneViewportService.getViewportInfo(
activeViewportId
);
const viewportId = viewportInfo.getViewportId();
@@ -617,34 +612,8 @@ function commandsModule({
);
toolGroup.setToolEnabled(ReferenceLinesTool.toolName);
},
storePresentation: ({ viewportIndex }) => {
const presentation = cornerstoneViewportService.getPresentation(
viewportIndex
);
if (!presentation || !presentation.presentationIds) {
return;
}
const {
lutPresentationStore,
positionPresentationStore,
} = stateSyncService.getState();
const { presentationIds } = presentation;
const { lutPresentationId, positionPresentationId } =
presentationIds || {};
const storeState = {};
if (lutPresentationId) {
storeState.lutPresentationStore = {
...lutPresentationStore,
[lutPresentationId]: presentation,
};
}
if (positionPresentationId) {
storeState.positionPresentationStore = {
...positionPresentationStore,
[positionPresentationId]: presentation,
};
}
stateSyncService.store(storeState);
storePresentation: ({ viewportId }) => {
cornerstoneViewportService.storePresentation({ viewportId });
},
};
@@ -701,10 +670,11 @@ function commandsModule({
options: { rotation: -90 },
},
incrementActiveViewport: {
commandFn: actions.incrementActiveViewport,
commandFn: actions.changeActiveViewport,
},
decrementActiveViewport: {
commandFn: actions.decrementActiveViewport,
commandFn: actions.changeActiveViewport,
options: { direction: -1 },
},
flipViewportHorizontal: {
commandFn: actions.flipViewportHorizontal,
@@ -2,14 +2,10 @@ import React, { useEffect } from 'react';
import { CinePlayer, useCine, useViewportGrid } from '@ohif/ui';
import { Enums, eventTarget } from '@cornerstonejs/core';
function WrappedCinePlayer({
enabledVPElement,
viewportIndex,
servicesManager,
}) {
function WrappedCinePlayer({ enabledVPElement, viewportId, servicesManager }) {
const { toolbarService, customizationService } = servicesManager.services;
const [{ isCineEnabled, cines }, cineService] = useCine();
const [{ activeViewportIndex }] = useViewportGrid();
const [{ activeViewportId }] = useViewportGrid();
const { component: CinePlayerComponent = CinePlayer } =
customizationService.get('cinePlayer') ?? {};
@@ -30,11 +26,11 @@ function WrappedCinePlayer({
};
const cineHandler = () => {
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
if (!cines || !cines[viewportId] || !enabledVPElement) {
return;
}
const cine = cines[viewportIndex];
const cine = cines[viewportId];
const isPlaying = cine.isPlaying || false;
const frameRate = cine.frameRate || 24;
@@ -56,7 +52,7 @@ function WrappedCinePlayer({
);
return () => {
cineService.setCine({ id: viewportIndex, isPlaying: false });
cineService.setCine({ id: viewportId, isPlaying: false });
eventTarget.removeEventListener(
Enums.Events.STACK_VIEWPORT_NEW_STACK,
cineHandler
@@ -65,20 +61,20 @@ function WrappedCinePlayer({
}, [enabledVPElement]);
useEffect(() => {
if (!cines || !cines[viewportIndex] || !enabledVPElement) {
if (!cines || !cines[viewportId] || !enabledVPElement) {
return;
}
cineHandler();
return () => {
if (enabledVPElement && cines?.[viewportIndex]?.isPlaying) {
if (enabledVPElement && cines?.[viewportId]?.isPlaying) {
cineService.stopClip(enabledVPElement);
}
};
}, [cines, viewportIndex, cineService, enabledVPElement, cineHandler]);
}, [cines, viewportId, cineService, enabledVPElement, cineHandler]);
const cine = cines[viewportIndex];
const cine = cines[viewportId];
const isPlaying = (cine && cine.isPlaying) || false;
return (
@@ -89,13 +85,13 @@ function WrappedCinePlayer({
onClose={handleCineClose}
onPlayPauseChange={isPlaying =>
cineService.setCine({
id: activeViewportIndex,
id: activeViewportId,
isPlaying,
})
}
onFrameRateChange={frameRate =>
cineService.setCine({
id: activeViewportIndex,
id: activeViewportId,
frameRate,
})
}
@@ -88,6 +88,7 @@ const mpr: Types.HangingProtocol.Protocol = {
viewports: [
{
viewportOptions: {
viewportId: 'mpr-axial',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'axial',
@@ -111,6 +112,7 @@ const mpr: Types.HangingProtocol.Protocol = {
},
{
viewportOptions: {
viewportId: 'mpr-sagittal',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'sagittal',
@@ -134,6 +136,7 @@ const mpr: Types.HangingProtocol.Protocol = {
},
{
viewportOptions: {
viewportId: 'mpr-coronal',
toolGroupId: 'mpr',
viewportType: 'volume',
orientation: 'coronal',
+2 -3
View File
@@ -282,9 +282,8 @@ export default async function init({
);
viewportGridService.subscribe(
viewportGridService.EVENTS.ACTIVE_VIEWPORT_INDEX_CHANGED,
({ viewportIndex, viewportId }) => {
viewportId = viewportId || `viewport-${viewportIndex}`;
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
({ viewportId }) => {
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
if (!toolGroup || !toolGroup._toolInstances?.['ReferenceLines']) {
@@ -63,7 +63,6 @@ function initContextMenu({
customizationService.get('cornerstoneViewportClickCommands') ||
DEFAULT_CONTEXT_MENU_CLICKS;
const toRun = customizations[name];
console.log('initContextMenu::cornerstoneViewportHandleEvent', name, toRun);
const options = {
nearbyToolData: findNearbyToolData(commandsManager, evt),
event: evt,
@@ -82,9 +81,8 @@ function initContextMenu({
if (!viewportInfo) {
return;
}
const viewportIndex = viewportInfo.getViewportIndex();
// TODO check update upstream
setEnabledElement(viewportIndex, element);
setEnabledElement(viewportId, element);
element.addEventListener(
cs3DToolsEvents.MOUSE_CLICK,
@@ -9,8 +9,6 @@ import {
VolumeViewport,
VolumeViewport3D,
cache,
utilities,
CONSTANTS,
Enums as csEnums,
} from '@cornerstonejs/core';
@@ -55,7 +53,6 @@ class CornerstoneViewportService extends PubSubService
};
renderingEngine: Types.IRenderingEngine | null;
viewportsInfo: Map<number, ViewportInfo> = new Map();
viewportsById: Map<string, ViewportInfo> = new Map();
viewportGridResizeObserver: ResizeObserver | null;
viewportsDisplaySets: Map<string, string[]> = new Map();
@@ -75,45 +72,17 @@ class CornerstoneViewportService extends PubSubService
/**
* Adds the HTML element to the viewportService
* @param {*} viewportIndex
* @param {*} viewportId
* @param {*} elementRef
*/
public enableViewport(
viewportIndex: number,
viewportOptions: PublicViewportOptions,
elementRef: HTMLDivElement
): void {
// Use the provided viewportId
// Not providing a viewportId is frowned upon because it does weird things
// on moving them around, but it does mostly work.
if (!viewportOptions.viewportId) {
console.warn('Should provide viewport id externally', viewportOptions);
viewportOptions.viewportId =
this.getViewportId(viewportIndex) || `viewport-${viewportIndex}`;
}
const { viewportId } = viewportOptions;
const viewportInfo = new ViewportInfo(viewportIndex, viewportId);
if (!viewportInfo.viewportId) {
throw new Error('Should have viewport ID afterwards');
}
public enableViewport(viewportId: string, elementRef: HTMLDivElement): void {
const viewportInfo = new ViewportInfo(viewportId);
viewportInfo.setElement(elementRef);
this.viewportsInfo.set(viewportIndex, viewportInfo);
this.viewportsById.set(viewportId, viewportInfo);
}
public getViewportIds(): string[] {
const viewportIds = [];
this.viewportsInfo.forEach(viewportInfo => {
viewportIds.push(viewportInfo.getViewportId());
});
return viewportIds;
}
public getViewportId(viewportIndex: number): string {
return this.viewportsInfo[viewportIndex]?.viewportId;
return Array.from(this.viewportsById.keys());
}
/**
@@ -171,21 +140,14 @@ class CornerstoneViewportService extends PubSubService
* created for every new viewport, this will be called whenever the set of
* viewports is changed, but NOT when the viewport position changes only.
*
* @param viewportIndex
* @param viewportId - The viewportId to disable
*/
public disableElement(viewportIndex: number): void {
const viewportInfo = this.viewportsInfo.get(viewportIndex);
if (!viewportInfo) {
return;
}
public disableElement(viewportId: string): void {
this.renderingEngine?.disableElement(viewportId);
const viewportId = viewportInfo.getViewportId();
this.renderingEngine && this.renderingEngine.disableElement(viewportId);
this.viewportsInfo.get(viewportIndex).destroy();
this.viewportsInfo.delete(viewportIndex);
// clean up
this.viewportsById.delete(viewportId);
this.viewportsDisplaySets.delete(viewportId);
}
public setPresentations(viewport, presentations?: Presentations): void {
@@ -199,14 +161,14 @@ class CornerstoneViewportService extends PubSubService
}
}
public getPresentation(viewportIndex: number): Presentation {
const viewportInfo = this.viewportsInfo.get(viewportIndex);
public getPresentation(viewportId: string): Presentation {
const viewportInfo = this.viewportsById.get(viewportId);
if (!viewportInfo) {
return;
}
const { viewportType, presentationIds } = viewportInfo.getViewportOptions();
const csViewport = this.getCornerstoneViewportByIndex(viewportIndex);
const csViewport = this.getCornerstoneViewport(viewportId);
if (!csViewport) {
return;
}
@@ -228,55 +190,80 @@ class CornerstoneViewportService extends PubSubService
};
}
public storePresentation({ viewportId }) {
const stateSyncService = this.servicesManager.services.stateSyncService;
let presentation;
try {
presentation = this.getPresentation(viewportId);
} catch (error) {
console.warn(error);
}
if (!presentation || !presentation.presentationIds) {
return;
}
const {
lutPresentationStore,
positionPresentationStore,
} = stateSyncService.getState();
const { presentationIds } = presentation;
const { lutPresentationId, positionPresentationId } = presentationIds || {};
const storeState = {};
if (lutPresentationId) {
storeState.lutPresentationStore = {
...lutPresentationStore,
[lutPresentationId]: presentation,
};
}
if (positionPresentationId) {
storeState.positionPresentationStore = {
...positionPresentationStore,
[positionPresentationId]: presentation,
};
}
stateSyncService.store(storeState);
}
/**
* Uses the renderingEngine to enable the element for the given viewport index
* and sets the displaySet data to the viewport
* @param {*} viewportIndex
* @param {*} displaySet
* @param {*} dataSource
* @returns
* Sets the viewport data for a viewport.
* @param viewportId - The ID of the viewport to set the data for.
* @param viewportData - The viewport data to set.
* @param publicViewportOptions - The public viewport options.
* @param publicDisplaySetOptions - The public display set options.
* @param presentations - The presentations to set.
*/
public setViewportData(
viewportIndex: number,
viewportId: string,
viewportData: StackViewportData | VolumeViewportData,
publicViewportOptions: PublicViewportOptions,
publicDisplaySetOptions: DisplaySetOptions[],
presentations?: Presentations
): void {
const renderingEngine = this.getRenderingEngine();
const viewportId =
publicViewportOptions.viewportId || this.getViewportId(viewportIndex);
if (!viewportId) {
throw new Error('Must define viewportId externally');
}
// This is the old viewportInfo, which may have old options but we might be
// using its viewport (same viewportId as the new viewportInfo)
const viewportInfo = this.viewportsById.get(viewportId);
// We should store the presentation for the current viewport since we can't only
// rely to store it WHEN the viewport is disabled since we might keep around the
// same viewport/element and just change the viewportData for it (drag and drop etc.)
// the disableElement storePresentation handle would not be called in this case
// and we would lose the presentation.
this.storePresentation({ viewportId: viewportInfo.getViewportId() });
if (!viewportInfo) {
throw new Error('Viewport info not defined');
throw new Error('element is not enabled for the given viewportId');
}
// If the viewport has moved index, then record the new index
if (viewportInfo.viewportIndex !== viewportIndex) {
this.viewportsInfo.delete(viewportInfo.viewportIndex);
this.viewportsInfo.set(viewportIndex, viewportInfo);
viewportInfo.viewportIndex = viewportIndex;
}
viewportInfo.setRenderingEngineId(renderingEngine.id);
const {
viewportOptions,
displaySetOptions,
} = this._getViewportAndDisplaySetOptions(
publicViewportOptions,
publicDisplaySetOptions,
viewportInfo
// override the viewportOptions and displaySetOptions with the public ones
// since those are the newly set ones, we set them here so that it handles defaults
const displaySetOptions = viewportInfo.setPublicDisplaySetOptions(
publicDisplaySetOptions
);
const viewportOptions = viewportInfo.setPublicViewportOptions(
publicViewportOptions
);
viewportInfo.setViewportOptions(viewportOptions);
viewportInfo.setDisplaySetOptions(displaySetOptions);
viewportInfo.setViewportData(viewportData);
const element = viewportInfo.getElement();
const type = viewportInfo.getViewportType();
@@ -293,12 +280,26 @@ class CornerstoneViewportService extends PubSubService
},
};
// Rendering Engine Id set should happen before enabling the element
// since there are callbacks that depend on the renderingEngine id
// Todo: however, this is a limitation which means that we can't change
// the rendering engine id for a given viewport which might be a super edge
// case
viewportInfo.setRenderingEngineId(renderingEngine.id);
// Todo: this is not optimal at all, we are re-enabling the already enabled
// element which is not what we want. But enabledElement as part of the
// renderingEngine is designed to be used like this. This will trigger
// ENABLED_ELEMENT again and again, which will run onEnableElement callbacks
renderingEngine.enableElement(viewportInput);
viewportInfo.setViewportOptions(viewportOptions);
viewportInfo.setDisplaySetOptions(displaySetOptions);
viewportInfo.setViewportData(viewportData);
viewportInfo.setViewportId(viewportId);
this.viewportsById.set(viewportId, viewportInfo);
const viewport = renderingEngine.getViewport(viewportId);
this._setDisplaySets(viewport, viewportData, viewportInfo, presentations);
@@ -307,7 +308,6 @@ class CornerstoneViewportService extends PubSubService
// invalid data.
this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
viewportData,
viewportIndex,
viewportId,
});
}
@@ -330,43 +330,8 @@ class CornerstoneViewportService extends PubSubService
return viewport;
}
public getCornerstoneViewportByIndex(
viewportIndex: number
): Types.IStackViewport | Types.IVolumeViewport | null {
const viewportInfo = this.getViewportInfoByIndex(viewportIndex);
if (
!viewportInfo ||
!this.renderingEngine ||
this.renderingEngine.hasBeenDestroyed
) {
return null;
}
const viewport = this.renderingEngine.getViewport(
viewportInfo.getViewportId()
);
return viewport;
}
/**
* Returns the viewportIndex for the provided viewportId
* @param {string} viewportId - the viewportId
* @returns {number} - the viewportIndex
*/
public getViewportInfoByIndex(viewportIndex: number): ViewportInfo {
return this.viewportsInfo.get(viewportIndex);
}
public getViewportInfo(viewportId: string): ViewportInfo {
// @ts-ignore
for (const [index, viewport] of this.viewportsInfo.entries()) {
if (viewport.getViewportId() === viewportId) {
return viewport;
}
}
return null;
return this.viewportsById.get(viewportId);
}
_setStackViewport(
@@ -414,7 +379,7 @@ class CornerstoneViewportService extends PubSubService
}
viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
viewport.setProperties(properties);
viewport.setProperties({ ...properties });
const camera = presentations.positionPresentation?.camera;
if (camera) {
viewport.setCamera(camera);
@@ -541,10 +506,7 @@ class CornerstoneViewportService extends PubSubService
this.viewportsDisplaySets.set(viewport.id, displaySetInstanceUIDs);
if (
hangingProtocolService.hasCustomImageLoadStrategy() &&
!hangingProtocolService.customImageLoadPerformed
) {
if (hangingProtocolService.getShouldPerformCustomImageLoad()) {
// delegate the volume loading to the hanging protocol service if it has a custom image load strategy
return hangingProtocolService.runImageLoadStrategy({
viewportId: viewport.id,
@@ -744,14 +706,8 @@ class CornerstoneViewportService extends PubSubService
// Todo: keepCamera is an interim solution until we have a better solution for
// keeping the camera position when the viewport data is changed
public updateViewport(
viewportIndex: number,
viewportData,
keepCamera = false
) {
const viewportInfo = this.getViewportInfoByIndex(viewportIndex);
const viewportId = viewportInfo.getViewportId();
public updateViewport(viewportId: string, viewportData, keepCamera = false) {
const viewportInfo = this.getViewportInfo(viewportId);
const viewport = this.getCornerstoneViewport(viewportId);
const viewportCamera = viewport.getCamera();
@@ -841,36 +797,6 @@ class CornerstoneViewportService extends PubSubService
}
}
_getViewportAndDisplaySetOptions(
publicViewportOptions: PublicViewportOptions,
publicDisplaySetOptions: DisplaySetOptions[],
viewportInfo: ViewportInfo
): {
viewportOptions: ViewportOptions;
displaySetOptions: DisplaySetOptions[];
} {
const viewportIndex = viewportInfo.getViewportIndex();
// Creating a temporary viewportInfo to handle defaults
const newViewportInfo = new ViewportInfo(
viewportIndex,
viewportInfo.getViewportId()
);
// To handle setting the default values if missing for the viewportOptions and
// displaySetOptions
newViewportInfo.setPublicViewportOptions(publicViewportOptions);
newViewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
const newViewportOptions = newViewportInfo.getViewportOptions();
const newDisplaySetOptions = newViewportInfo.getDisplaySetOptions();
return {
viewportOptions: newViewportOptions,
displaySetOptions: newDisplaySetOptions,
};
}
_getFrameOfReferenceUID(displaySetInstanceUID) {
const { displaySetService } = this.servicesManager.services;
const displaySet = displaySetService.getDisplaySetByUID(
@@ -907,25 +833,25 @@ class CornerstoneViewportService extends PubSubService
*
* @param measurement
* The measurement that is desired to view.
* @param activeViewportIndex - the index that was active at the time the jump
* @param activeViewportId - the index that was active at the time the jump
* was initiated.
* @return the viewportIndex to display the given measurement
* @return the viewportId that the measurement should be displayed in.
*/
public getViewportIndexToJump(
activeViewportIndex: number,
public getViewportIdToJump(
activeViewportId: string,
displaySetInstanceUID: string,
cameraProps: unknown
): number {
const viewportInfo = this.viewportsInfo.get(activeViewportIndex);
): string {
const viewportInfo = this.getViewportInfo(activeViewportId);
const { referencedImageId } = cameraProps;
if (viewportInfo?.contains(displaySetInstanceUID, referencedImageId)) {
return activeViewportIndex;
return activeViewportId;
}
return (
[...this.viewportsById.values()].find(viewportInfo =>
viewportInfo.contains(displaySetInstanceUID, referencedImageId)
)?.viewportIndex ?? -1
)?.viewportId ?? null
);
}
}
@@ -17,7 +17,6 @@ export interface IViewportService {
viewportGridResizeObserver: unknown;
viewportsInfo: unknown;
sceneVolumeInputs: unknown;
viewportIndexUIDMap: unknown;
viewportDivElements: unknown;
ViewportPropertiesMap: unknown;
volumeUIDs: unknown;
@@ -28,14 +27,9 @@ export interface IViewportService {
_broadcastEvent: unknown;
/**
* Adds the HTML element to the viewportService
* @param {*} viewportIndex
* @param {*} elementRef
*/
enableViewport(
viewportIndex: number,
viewportOptions: ViewportOptions,
elementRef: HTMLDivElement
): void;
enableViewport(viewportId: string, elementRef: HTMLDivElement): void;
/**
* It retrieves the renderingEngine if it does exist, or creates one otherwise
* @returns {RenderingEngine} rendering engine
@@ -54,19 +48,17 @@ export interface IViewportService {
/**
* Disables the viewport inside the renderingEngine, if no viewport is left
* it destroys the renderingEngine.
* @param viewportIndex
* @param viewportId
*/
disableElement(viewportIndex: number): void;
disableElement(viewportId: string): void;
/**
* Uses the renderingEngine to enable the element for the given viewport index
* and sets the displaySet data to the viewport
* @param {*} viewportIndex
* @param {*} displaySet
* @param {*} dataSource
* @returns
*/
setViewportData(
viewportIndex: number,
viewportData: StackData | VolumeData,
publicViewportOptions: PublicViewportOptions,
publicDisplaySetOptions: DisplaySetOptions[]
@@ -106,15 +106,13 @@ const dataContains = (
class ViewportInfo {
private viewportId = '';
private viewportIndex: number;
private element: HTMLDivElement;
private viewportOptions: ViewportOptions;
private displaySetOptions: Array<DisplaySetOptions>;
private viewportData: StackViewportData | VolumeViewportData;
private renderingEngineId: string;
constructor(viewportIndex: number, viewportId: string) {
this.viewportIndex = viewportIndex;
constructor(viewportId: string) {
this.viewportId = viewportId;
this.setPublicViewportOptions({});
this.setPublicDisplaySetOptions([{}]);
@@ -155,9 +153,6 @@ class ViewportInfo {
public setViewportId(viewportId: string): void {
this.viewportId = viewportId;
}
public setViewportIndex(viewportIndex: number): void {
this.viewportIndex = viewportIndex;
}
public setElement(element: HTMLDivElement): void {
this.element = element;
@@ -173,9 +168,6 @@ class ViewportInfo {
return this.viewportData;
}
public getViewportIndex(): number {
return this.viewportIndex;
}
public getElement(): HTMLDivElement {
return this.element;
@@ -187,13 +179,15 @@ class ViewportInfo {
public setPublicDisplaySetOptions(
publicDisplaySetOptions: PublicDisplaySetOptions[] | DisplaySetSelector[]
): void {
): Array<DisplaySetOptions> {
// map the displaySetOptions and check if they are undefined then set them to default values
const displaySetOptions = this.mapDisplaySetOptions(
publicDisplaySetOptions
);
this.setDisplaySetOptions(displaySetOptions);
return this.displaySetOptions
}
public hasDisplaySet(displaySetInstanceUID: string): boolean {
@@ -217,7 +211,7 @@ class ViewportInfo {
public setPublicViewportOptions(
viewportOptionsEntry: PublicViewportOptions
): void {
): ViewportOptions {
let viewportType = viewportOptionsEntry.viewportType;
const {
toolGroupId = DEFAULT_TOOLGROUP_ID,
@@ -250,6 +244,8 @@ class ViewportInfo {
toolGroupId,
presentationIds,
});
return this.viewportOptions;
}
public setViewportOptions(viewportOptions: ViewportOptions): void {
+4 -4
View File
@@ -10,13 +10,13 @@ const state = {
* @return void
*/
const setEnabledElement = (
viewportIndex: number,
viewportId: string,
element: HTMLElement,
context?: string
): void => {
const targetContext = context || state.DEFAULT_CONTEXT;
state.enabledElements[viewportIndex] = {
state.enabledElements[viewportId] = {
element,
context: targetContext,
};
@@ -27,8 +27,8 @@ const setEnabledElement = (
*
* @return {HTMLElement} Active viewport element.
*/
const getEnabledElement = viewportIndex => {
return state.enabledElements[viewportIndex];
const getEnabledElement = viewportId => {
return state.enabledElements[viewportId];
};
const reset = () => {
@@ -20,10 +20,10 @@ const VIEWPORT_ID = 'cornerstone-viewport-download-form';
const CornerstoneViewportDownloadForm = ({
onClose,
activeViewportIndex,
activeViewportId: activeViewportIdProp,
cornerstoneViewportService,
}) => {
const enabledElement = OHIFgetEnabledElement(activeViewportIndex);
const enabledElement = OHIFgetEnabledElement(activeViewportIdProp);
const activeViewportElement = enabledElement?.element;
const activeViewportEnabledElement = getEnabledElement(activeViewportElement);
@@ -268,7 +268,7 @@ const CornerstoneViewportDownloadForm = ({
CornerstoneViewportDownloadForm.propTypes = {
onClose: PropTypes.func,
activeViewportIndex: PropTypes.number.isRequired,
activeViewportId: PropTypes.string.isRequired,
};
export default CornerstoneViewportDownloadForm;
@@ -6,8 +6,8 @@ import { getEnabledElement as OHIFgetEnabledElement } from '../state';
export default function getActiveViewportEnabledElement(
viewportGridService
): IEnabledElement {
const { activeViewportIndex } = viewportGridService.getState();
const { element } = OHIFgetEnabledElement(activeViewportIndex) || {};
const { activeViewportId } = viewportGridService.getState();
const { element } = OHIFgetEnabledElement(activeViewportId) || {};
const enabledElement = getEnabledElement(element);
return enabledElement;
}
@@ -2,7 +2,7 @@ import calculateViewportRegistrations from './calculateViewportRegistrations';
// [ {
// synchronizerId: string,
// viewports: [ { viewportId: number, renderingEngineId: string, index: number } , ...]
// viewports: [ { viewportId: string, renderingEngineId: string, index: number } , ...]
// ]}
let STACK_IMAGE_SYNC_GROUPS_INFO = [];
@@ -37,32 +37,25 @@ export default function toggleStackImageSync({
STACK_IMAGE_SYNC_GROUPS_INFO = [];
// create synchronization groups and add viewports
let { viewports } = viewportGridService.getState();
const { viewports } = viewportGridService.getState();
// filter empty viewports
viewports = viewports.filter(
viewport =>
viewport.displaySetInstanceUIDs && viewport.displaySetInstanceUIDs.length
);
const viewportsArray = Array.from(viewports.values())
.filter(viewport => viewport.displaySetInstanceUIDs?.length)
// filter reconstructable viewports
.filter(viewport => {
const { displaySetInstanceUIDs } = viewport;
// filter reconstructable viewports
viewports = viewports.filter(viewport => {
const { displaySetInstanceUIDs } = viewport;
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
const displaySet = displaySetService.getDisplaySetByUID(
displaySetInstanceUID
);
for (const displaySetInstanceUID of displaySetInstanceUIDs) {
const displaySet = displaySetService.getDisplaySetByUID(
displaySetInstanceUID
);
if (displaySet && displaySet.isReconstructable) {
return true;
return !!displaySet?.isReconstructable;
}
});
return false;
}
});
const viewportsByOrientation = viewports.reduce((acc, viewport) => {
const viewportsByOrientation = viewportsArray.reduce((acc, viewport) => {
const { viewportId, viewportType } = viewport.viewportOptions;
if (viewportType !== 'stack') {
@@ -71,9 +64,8 @@ export default function toggleStackImageSync({
}
const { element } = cornerstoneViewportService.getViewportInfo(viewportId);
const { viewport: csViewport, renderingEngineId } = getEnabledElement(
element
);
const { viewport: csViewport, renderingEngineId } =
getEnabledElement(element);
const { viewPlaneNormal } = csViewport.getCamera();
// Should we round here? I guess so, but not sure how much precision we need