2025-05-08 12:51:30 -04:00
|
|
|
import React, { ReactNode } from 'react';
|
|
|
|
|
import { useSystem } from '@ohif/core';
|
|
|
|
|
import {
|
|
|
|
|
Button,
|
|
|
|
|
Icons,
|
|
|
|
|
Popover,
|
|
|
|
|
PopoverContent,
|
|
|
|
|
PopoverTrigger,
|
|
|
|
|
useViewportGrid,
|
2025-05-15 12:08:12 -04:00
|
|
|
useIconPresentation,
|
2025-05-08 12:51:30 -04:00
|
|
|
} from '@ohif/ui-next';
|
|
|
|
|
import { WindowLevelActionMenu } from './WindowLevelActionMenu';
|
2025-05-15 12:08:12 -04:00
|
|
|
import { useViewportDisplaySets } from '../../hooks/useViewportDisplaySets';
|
|
|
|
|
import { useViewportRendering } from '../../hooks';
|
2025-05-08 12:51:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
export function WindowLevelActionMenuWrapper(
|
|
|
|
|
props: withAppTypes<{
|
|
|
|
|
viewportId: string;
|
|
|
|
|
location?: number;
|
|
|
|
|
isOpen?: boolean;
|
|
|
|
|
onOpen?: () => void;
|
|
|
|
|
onClose?: () => void;
|
|
|
|
|
displaySets?: Array<AppTypes.DisplaySet>;
|
|
|
|
|
disabled?: boolean;
|
|
|
|
|
isEmbedded?: boolean;
|
|
|
|
|
}>
|
|
|
|
|
): ReactNode {
|
|
|
|
|
const {
|
|
|
|
|
viewportId,
|
|
|
|
|
location,
|
|
|
|
|
isOpen = false,
|
|
|
|
|
onOpen,
|
|
|
|
|
onClose,
|
|
|
|
|
disabled,
|
|
|
|
|
isEmbedded = false,
|
|
|
|
|
onInteraction: onInteractionProps,
|
|
|
|
|
hasEmbeddedVariantToUse,
|
|
|
|
|
...rest
|
|
|
|
|
} = props;
|
2025-05-08 12:51:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
const [gridState] = useViewportGrid();
|
|
|
|
|
const viewportIdToUse = viewportId || gridState.activeViewportId;
|
2025-05-08 12:51:30 -04:00
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
const { viewportDisplaySets: displaySets } = useViewportDisplaySets(viewportIdToUse);
|
|
|
|
|
const { servicesManager } = useSystem();
|
|
|
|
|
const { toolbarService } = servicesManager.services;
|
|
|
|
|
const { IconContainer, className: iconClassName, containerProps } = useIconPresentation();
|
|
|
|
|
const { hasColorbar, toggleColorbar } = useViewportRendering(viewportId);
|
2025-05-08 12:51:30 -04:00
|
|
|
|
|
|
|
|
const handleOpenChange = (openState: boolean) => {
|
2025-05-15 12:08:12 -04:00
|
|
|
const shouldToggleColorbar = hasColorbar && !isEmbedded;
|
|
|
|
|
|
|
|
|
|
if (isOpen && shouldToggleColorbar && openState) {
|
|
|
|
|
toggleColorbar();
|
|
|
|
|
onClose?.();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isOpen && openState && shouldToggleColorbar) {
|
|
|
|
|
toggleColorbar();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-08 12:51:30 -04:00
|
|
|
if (openState) {
|
2025-05-15 12:08:12 -04:00
|
|
|
onOpen?.();
|
2025-05-08 12:51:30 -04:00
|
|
|
} else {
|
2025-05-15 12:08:12 -04:00
|
|
|
onClose?.();
|
2025-05-08 12:51:30 -04:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
const { align, side } = toolbarService.getAlignAndSide(location);
|
2025-05-08 12:51:30 -04:00
|
|
|
|
|
|
|
|
const modalities = displaySets.map(displaySet => displaySet.supportsWindowLevel);
|
|
|
|
|
|
|
|
|
|
if (modalities.length === 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-15 12:08:12 -04:00
|
|
|
const Icon =
|
|
|
|
|
hasColorbar && !isEmbedded && hasEmbeddedVariantToUse ? (
|
|
|
|
|
<Icons.Close className={iconClassName} />
|
|
|
|
|
) : (
|
|
|
|
|
<Icons.ViewportWindowLevel className={iconClassName} />
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-08 12:51:30 -04:00
|
|
|
return (
|
|
|
|
|
<Popover
|
2025-05-15 12:08:12 -04:00
|
|
|
open={isOpen}
|
2025-05-08 12:51:30 -04:00
|
|
|
onOpenChange={handleOpenChange}
|
|
|
|
|
>
|
|
|
|
|
<PopoverTrigger
|
|
|
|
|
asChild
|
|
|
|
|
className="flex items-center justify-center"
|
|
|
|
|
>
|
2025-05-15 12:08:12 -04:00
|
|
|
<div>
|
|
|
|
|
{IconContainer ? (
|
|
|
|
|
<IconContainer
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
{...rest}
|
|
|
|
|
{...containerProps}
|
|
|
|
|
>
|
|
|
|
|
{Icon}
|
|
|
|
|
</IconContainer>
|
|
|
|
|
) : (
|
|
|
|
|
<Button
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="icon"
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
>
|
|
|
|
|
{Icon}
|
|
|
|
|
</Button>
|
2025-05-08 12:51:30 -04:00
|
|
|
)}
|
2025-05-15 12:08:12 -04:00
|
|
|
</div>
|
2025-05-08 12:51:30 -04:00
|
|
|
</PopoverTrigger>
|
|
|
|
|
<PopoverContent
|
|
|
|
|
className="border-none bg-transparent p-0 shadow-none"
|
|
|
|
|
side={side}
|
|
|
|
|
align={align}
|
|
|
|
|
alignOffset={0}
|
|
|
|
|
sideOffset={5}
|
|
|
|
|
>
|
|
|
|
|
<WindowLevelActionMenu
|
2025-05-15 12:08:12 -04:00
|
|
|
viewportId={viewportIdToUse}
|
|
|
|
|
align={align}
|
|
|
|
|
side={side}
|
2026-01-14 16:50:24 -05:00
|
|
|
onVisibilityChange={handleOpenChange}
|
2025-05-08 12:51:30 -04:00
|
|
|
/>
|
|
|
|
|
</PopoverContent>
|
|
|
|
|
</Popover>
|
|
|
|
|
);
|
|
|
|
|
}
|