ohif-viewer/extensions/cornerstone/src/getToolbarModule.tsx

249 lines
6.9 KiB
TypeScript

import { Enums } from '@cornerstonejs/tools';
import { utils } from '@ohif/ui-next';
const getDisabledState = (disabledText?: string) => ({
disabled: true,
disabledText: disabledText ?? 'Not available on the current viewport',
});
export default function getToolbarModule({ commandsManager, servicesManager }: withAppTypes) {
const {
toolGroupService,
toolbarService,
syncGroupService,
cornerstoneViewportService,
hangingProtocolService,
displaySetService,
viewportGridService,
} = servicesManager.services;
return [
// functions/helpers to be used by the toolbar buttons to decide if they should
// enabled or not
{
name: 'evaluate.viewport.supported',
evaluate: ({ viewportId, unsupportedViewportTypes, disabledText }) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (viewport && unsupportedViewportTypes?.includes(viewport.type)) {
return getDisabledState(disabledText);
}
return undefined;
},
},
{
name: 'evaluate.modality.supported',
evaluate: ({ viewportId, unsupportedModalities, supportedModalities, disabledText }) => {
const displaySetUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId);
if (!displaySetUIDs?.length) {
return;
}
const displaySets = displaySetUIDs.map(displaySetService.getDisplaySetByUID);
// Check for unsupported modalities (exclusion)
if (unsupportedModalities?.length) {
const hasUnsupportedModality = displaySets.some(displaySet =>
unsupportedModalities.includes(displaySet?.Modality)
);
if (hasUnsupportedModality) {
return getDisabledState(disabledText);
}
}
// Check for supported modalities (inclusion)
if (supportedModalities?.length) {
const hasAnySupportedModality = displaySets.some(displaySet =>
supportedModalities.includes(displaySet?.Modality)
);
if (!hasAnySupportedModality) {
return getDisabledState(disabledText || 'Tool not available for this modality');
}
}
},
},
{
name: 'evaluate.cornerstoneTool',
evaluate: ({ viewportId, button, toolNames, disabledText }) => {
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
if (!toolGroup) {
return;
}
const toolName = toolbarService.getToolNameForButton(button);
if (!toolGroup || (!toolGroup.hasTool(toolName) && !toolNames)) {
return getDisabledState(disabledText);
}
const isPrimaryActive = toolNames
? toolNames.includes(toolGroup.getActivePrimaryMouseButtonTool())
: toolGroup.getActivePrimaryMouseButtonTool() === toolName;
return {
disabled: false,
isActive: isPrimaryActive,
};
},
},
{
name: 'evaluate.action',
evaluate: () => {
return {
disabled: false,
};
},
},
{
name: 'evaluate.cornerstoneTool.toggle.ifStrictlyDisabled',
evaluate: ({ viewportId, button, disabledText }) =>
_evaluateToggle({
viewportId,
button,
toolbarService,
disabledText,
offModes: [Enums.ToolModes.Disabled],
toolGroupService,
}),
},
{
name: 'evaluate.cornerstoneTool.toggle',
evaluate: ({ viewportId, button, disabledText }) =>
_evaluateToggle({
viewportId,
button,
toolbarService,
disabledText,
offModes: [Enums.ToolModes.Disabled, Enums.ToolModes.Passive],
toolGroupService,
}),
},
{
name: 'evaluate.cornerstone.synchronizer',
evaluate: ({ viewportId, button }) => {
let synchronizers = syncGroupService.getSynchronizersForViewport(viewportId);
if (!synchronizers?.length) {
return {
className: utils.getToggledClassName(false),
};
}
const isArray = Array.isArray(button.commands);
const synchronizerType = isArray
? button.commands?.[0].commandOptions.type
: button.commands?.commandOptions.type;
synchronizers = syncGroupService.getSynchronizersOfType(synchronizerType);
if (!synchronizers?.length) {
return {
className: utils.getToggledClassName(false),
};
}
// Todo: we need a better way to find the synchronizers based on their
// type, but for now we just check the first one and see if it is
// enabled
const synchronizer = synchronizers[0];
const isEnabled = synchronizer?._enabled;
return {
className: utils.getToggledClassName(isEnabled),
};
},
},
{
name: 'evaluate.viewportProperties.toggle',
evaluate: ({ viewportId, button }) => {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport || viewport.isDisabled) {
return;
}
const propId = button.id;
const properties = viewport.getProperties();
const camera = viewport.getCamera();
const prop = camera?.[propId] || properties?.[propId];
if (!prop) {
return {
disabled: false,
};
}
const isToggled = prop;
return {
className: utils.getToggledClassName(isToggled),
};
},
},
{
name: 'evaluate.mpr',
evaluate: ({ viewportId, disabledText = 'Selected viewport is not reconstructable' }) => {
const { protocol } = hangingProtocolService.getActiveProtocol();
const displaySetUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId);
if (!displaySetUIDs?.length) {
return;
}
const displaySets = displaySetUIDs.map(displaySetService.getDisplaySetByUID);
const areReconstructable = displaySets.every(displaySet => {
return displaySet?.isReconstructable;
});
if (!areReconstructable) {
return getDisabledState(disabledText);
}
const isMpr = protocol?.id === 'mpr';
return {
disabled: false,
className: utils.getToggledClassName(isMpr),
};
},
},
];
}
function _evaluateToggle({
viewportId,
toolbarService,
button,
disabledText,
offModes,
toolGroupService,
}) {
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
if (!toolGroup) {
return;
}
const toolName = toolbarService.getToolNameForButton(button);
if (!toolGroup.hasTool(toolName)) {
return getDisabledState(disabledText);
}
const isOff = offModes.includes(toolGroup.getToolOptions(toolName).mode);
return {
className: utils.getToggledClassName(!isOff),
};
}