2025-05-15 12:08:12 -04:00
|
|
|
import React, { ReactElement, useMemo } from 'react';
|
2024-04-02 09:35:30 -04:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2025-05-15 12:08:12 -04:00
|
|
|
import { AllInOneMenu } from '@ohif/ui-next';
|
2024-04-02 09:35:30 -04:00
|
|
|
import { Colormap } from './Colormap';
|
|
|
|
|
import { Colorbar } from './Colorbar';
|
|
|
|
|
import { WindowLevel } from './WindowLevel';
|
|
|
|
|
import { VolumeRenderingPresets } from './VolumeRenderingPresets';
|
|
|
|
|
import { VolumeRenderingOptions } from './VolumeRenderingOptions';
|
2025-05-15 12:08:12 -04:00
|
|
|
import { useViewportRendering } from '../../hooks/useViewportRendering';
|
2025-09-25 22:22:02 +08:00
|
|
|
import i18n from 'i18next';
|
2024-11-06 07:15:27 -05:00
|
|
|
|
2024-04-02 09:35:30 -04:00
|
|
|
export type WindowLevelActionMenuProps = {
|
|
|
|
|
viewportId: string;
|
2025-05-15 12:08:12 -04:00
|
|
|
element?: HTMLElement;
|
|
|
|
|
align?: 'start' | 'end' | 'center';
|
|
|
|
|
side?: 'top' | 'bottom' | 'left' | 'right';
|
2024-04-02 09:35:30 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function WindowLevelActionMenu({
|
|
|
|
|
viewportId,
|
|
|
|
|
element,
|
2025-05-15 12:08:12 -04:00
|
|
|
align,
|
|
|
|
|
side,
|
|
|
|
|
}: WindowLevelActionMenuProps): ReactElement {
|
|
|
|
|
return (
|
|
|
|
|
<WindowLevelActionMenuContent
|
|
|
|
|
viewportId={viewportId}
|
|
|
|
|
align={align}
|
|
|
|
|
side={side}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-04-02 09:35:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
export function WindowLevelActionMenuContent({
|
|
|
|
|
viewportId,
|
|
|
|
|
align,
|
|
|
|
|
side,
|
|
|
|
|
}: {
|
|
|
|
|
viewportId: string;
|
|
|
|
|
align?: string;
|
|
|
|
|
side?: string;
|
|
|
|
|
}): ReactElement {
|
2024-04-02 09:35:30 -04:00
|
|
|
const { t } = useTranslation('WindowLevelActionMenu');
|
2025-05-15 12:08:12 -04:00
|
|
|
// Use a stable key for the menu to avoid infinite re-renders
|
|
|
|
|
const menuKey = useMemo(() => `${viewportId}`, [viewportId]);
|
2024-04-02 09:35:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
const {
|
|
|
|
|
is3DVolume,
|
2024-04-02 09:35:30 -04:00
|
|
|
colorbarProperties,
|
2025-05-15 12:08:12 -04:00
|
|
|
windowLevelPresets,
|
|
|
|
|
volumeRenderingPresets,
|
|
|
|
|
volumeRenderingQualityRange,
|
|
|
|
|
} = useViewportRendering(viewportId);
|
2024-04-02 09:35:30 -04:00
|
|
|
|
|
|
|
|
return (
|
2025-05-08 12:51:30 -04:00
|
|
|
<AllInOneMenu.Menu
|
|
|
|
|
key={menuKey}
|
|
|
|
|
// the visibility is handled by the parent component
|
|
|
|
|
isVisible={true}
|
2025-05-15 12:08:12 -04:00
|
|
|
align={align}
|
|
|
|
|
side={side}
|
2025-09-25 22:22:02 +08:00
|
|
|
backLabel={i18n.t('WindowLevelActionMenu:Back to Display Options')}
|
2024-04-02 09:35:30 -04:00
|
|
|
>
|
|
|
|
|
<AllInOneMenu.ItemPanel>
|
2025-05-15 12:08:12 -04:00
|
|
|
{!is3DVolume && <Colorbar viewportId={viewportId} />}
|
2024-04-02 09:35:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
{colorbarProperties?.colormaps && !is3DVolume && (
|
2024-04-02 09:35:30 -04:00
|
|
|
<AllInOneMenu.SubMenu
|
|
|
|
|
key="colorLUTPresets"
|
2025-09-25 22:22:02 +08:00
|
|
|
itemLabel={t('Color LUT')}
|
2024-04-02 09:35:30 -04:00
|
|
|
itemIcon="icon-color-lut"
|
2025-04-07 16:45:05 -04:00
|
|
|
className="flex h-[calc(100%-32px)] flex-col"
|
2024-04-02 09:35:30 -04:00
|
|
|
>
|
2025-05-15 12:08:12 -04:00
|
|
|
<Colormap viewportId={viewportId} />
|
2024-04-02 09:35:30 -04:00
|
|
|
</AllInOneMenu.SubMenu>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
{windowLevelPresets?.length > 0 && !is3DVolume && (
|
2024-04-02 09:35:30 -04:00
|
|
|
<AllInOneMenu.SubMenu
|
|
|
|
|
key="windowLevelPresets"
|
2024-04-16 10:31:06 -02:30
|
|
|
itemLabel={t('Modality Window Presets')}
|
2024-04-02 09:35:30 -04:00
|
|
|
itemIcon="viewport-window-level"
|
|
|
|
|
>
|
2025-05-15 12:08:12 -04:00
|
|
|
<WindowLevel viewportId={viewportId} />
|
2024-04-02 09:35:30 -04:00
|
|
|
</AllInOneMenu.SubMenu>
|
|
|
|
|
)}
|
|
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
{volumeRenderingPresets && is3DVolume && <VolumeRenderingPresets viewportId={viewportId} />}
|
2024-04-02 09:35:30 -04:00
|
|
|
|
|
|
|
|
{volumeRenderingQualityRange && is3DVolume && (
|
2025-09-25 22:22:02 +08:00
|
|
|
<AllInOneMenu.SubMenu itemLabel={t('Rendering Options')}>
|
2025-05-15 12:08:12 -04:00
|
|
|
<VolumeRenderingOptions viewportId={viewportId} />
|
2024-04-02 09:35:30 -04:00
|
|
|
</AllInOneMenu.SubMenu>
|
|
|
|
|
)}
|
|
|
|
|
</AllInOneMenu.ItemPanel>
|
2025-05-08 12:51:30 -04:00
|
|
|
</AllInOneMenu.Menu>
|
2024-04-02 09:35:30 -04:00
|
|
|
);
|
|
|
|
|
}
|