feat(4D): Add 4D dynamic volume rendering and new pre-clinical 4d pt/ct mode (#3664)
Co-authored-by: Alireza <ar.sedghi@gmail.com> Co-authored-by: Neil <neil.a.macphee@gmail.com>
This commit is contained in:
200 files changed
+9589
-2178
No files matched your search
@@ -6,13 +6,11 @@ import { useLocation } from 'react-router';
|
||||
import { ErrorBoundary, UserPreferences, AboutModal, Header, useModal } from '@ohif/ui';
|
||||
import i18n from '@ohif/i18n';
|
||||
import { hotkeys } from '@ohif/core';
|
||||
import { useAppConfig } from '@state';
|
||||
import { Toolbar } from '../Toolbar/Toolbar';
|
||||
|
||||
const { availableLanguages, defaultLanguage, currentLanguage } = i18n;
|
||||
|
||||
function ViewerHeader({ hotkeysManager, extensionManager, servicesManager }) {
|
||||
const [appConfig] = useAppConfig();
|
||||
function ViewerHeader({ hotkeysManager, extensionManager, servicesManager, appConfig }) {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
@@ -107,6 +105,13 @@ function ViewerHeader({ hotkeysManager, extensionManager, servicesManager }) {
|
||||
WhiteLabeling={appConfig.whiteLabeling}
|
||||
showPatientInfo={appConfig.showPatientInfo}
|
||||
servicesManager={servicesManager}
|
||||
Secondary={
|
||||
<Toolbar
|
||||
servicesManager={servicesManager}
|
||||
buttonSection="secondary"
|
||||
/>
|
||||
}
|
||||
appConfig={appConfig}
|
||||
>
|
||||
<ErrorBoundary context="Primary Toolbar">
|
||||
<div className="relative flex justify-center">
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
SidePanel,
|
||||
ErrorBoundary,
|
||||
LoadingIndicatorProgress,
|
||||
InvestigationalUseDialog,
|
||||
} from '@ohif/ui';
|
||||
import { ErrorBoundary, LoadingIndicatorProgress, InvestigationalUseDialog } from '@ohif/ui';
|
||||
import { ServicesManager, HangingProtocolService, CommandsManager } from '@ohif/core';
|
||||
import { useAppConfig } from '@state';
|
||||
import ViewerHeader from './ViewerHeader';
|
||||
@@ -21,16 +16,24 @@ function ViewerLayout({
|
||||
// From Modes
|
||||
viewports,
|
||||
ViewportGridComp,
|
||||
leftPanels = [],
|
||||
rightPanels = [],
|
||||
leftPanelDefaultClosed = false,
|
||||
rightPanelDefaultClosed = false,
|
||||
leftPanelClosed = false,
|
||||
rightPanelClosed = false,
|
||||
}): React.FunctionComponent {
|
||||
const [appConfig] = useAppConfig();
|
||||
|
||||
const { hangingProtocolService } = servicesManager.services;
|
||||
const { panelService, hangingProtocolService } = servicesManager.services;
|
||||
const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
|
||||
|
||||
const hasPanels = useCallback(
|
||||
(side): boolean => !!panelService.getPanels(side).length,
|
||||
[panelService]
|
||||
);
|
||||
|
||||
const [hasRightPanels, setHasRightPanels] = useState(hasPanels('right'));
|
||||
const [hasLeftPanels, setHasLeftPanels] = useState(hasPanels('left'));
|
||||
const [leftPanelClosedState, setLeftPanelClosed] = useState(leftPanelClosed);
|
||||
const [rightPanelClosedState, setRightPanelClosed] = useState(rightPanelClosed);
|
||||
|
||||
/**
|
||||
* Set body classes (tailwindcss) that don't allow vertical
|
||||
* or horizontal overflow (no scrolling). Also guarantee window
|
||||
@@ -57,20 +60,6 @@ function ViewerLayout({
|
||||
return { entry, content: entry.component };
|
||||
};
|
||||
|
||||
const getPanelData = id => {
|
||||
const { content, entry } = getComponent(id);
|
||||
|
||||
return {
|
||||
id: entry.id,
|
||||
iconName: entry.iconName,
|
||||
iconLabel: entry.iconLabel,
|
||||
label: entry.label,
|
||||
name: entry.name,
|
||||
content,
|
||||
contexts: entry.contexts,
|
||||
};
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const { unsubscribe } = hangingProtocolService.subscribe(
|
||||
HangingProtocolService.EVENTS.PROTOCOL_CHANGED,
|
||||
@@ -97,8 +86,26 @@ function ViewerLayout({
|
||||
};
|
||||
};
|
||||
|
||||
const leftPanelComponents = leftPanels.map(getPanelData);
|
||||
const rightPanelComponents = rightPanels.map(getPanelData);
|
||||
useEffect(() => {
|
||||
const { unsubscribe } = panelService.subscribe(
|
||||
panelService.EVENTS.PANELS_CHANGED,
|
||||
({ options }) => {
|
||||
setHasLeftPanels(hasPanels('left'));
|
||||
setHasRightPanels(hasPanels('right'));
|
||||
if (options?.leftPanelClosed !== undefined) {
|
||||
setLeftPanelClosed(options.leftPanelClosed);
|
||||
}
|
||||
if (options?.rightPanelClosed !== undefined) {
|
||||
setRightPanelClosed(options.rightPanelClosed);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [panelService, hasPanels]);
|
||||
|
||||
const viewportComponents = viewports.map(getViewportComponentData);
|
||||
|
||||
return (
|
||||
@@ -107,6 +114,7 @@ function ViewerLayout({
|
||||
hotkeysManager={hotkeysManager}
|
||||
extensionManager={extensionManager}
|
||||
servicesManager={servicesManager}
|
||||
appConfig={appConfig}
|
||||
/>
|
||||
<div
|
||||
className="relative flex w-full flex-row flex-nowrap items-stretch overflow-hidden bg-black"
|
||||
@@ -115,12 +123,11 @@ function ViewerLayout({
|
||||
<React.Fragment>
|
||||
{showLoadingIndicator && <LoadingIndicatorProgress className="h-full w-full bg-black" />}
|
||||
{/* LEFT SIDEPANELS */}
|
||||
{leftPanelComponents.length ? (
|
||||
{hasLeftPanels ? (
|
||||
<ErrorBoundary context="Left Panel">
|
||||
<SidePanelWithServices
|
||||
side="left"
|
||||
activeTabIndex={leftPanelDefaultClosed ? null : 0}
|
||||
tabs={leftPanelComponents}
|
||||
activeTabIndex={leftPanelClosedState ? null : 0}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
@@ -137,12 +144,11 @@ function ViewerLayout({
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
{rightPanelComponents.length ? (
|
||||
{hasRightPanels ? (
|
||||
<ErrorBoundary context="Right Panel">
|
||||
<SidePanelWithServices
|
||||
side="right"
|
||||
activeTabIndex={rightPanelDefaultClosed ? null : 0}
|
||||
tabs={rightPanelComponents}
|
||||
activeTabIndex={rightPanelClosedState ? null : 0}
|
||||
servicesManager={servicesManager}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
@@ -165,8 +171,8 @@ ViewerLayout.propTypes = {
|
||||
// From modes
|
||||
leftPanels: PropTypes.array,
|
||||
rightPanels: PropTypes.array,
|
||||
leftPanelDefaultClosed: PropTypes.bool.isRequired,
|
||||
rightPanelDefaultClosed: PropTypes.bool.isRequired,
|
||||
leftPanelClosed: PropTypes.bool.isRequired,
|
||||
rightPanelClosed: PropTypes.bool.isRequired,
|
||||
/** Responsible for rendering our grid of viewports; provided by consuming application */
|
||||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
||||
viewports: PropTypes.array,
|
||||
|
||||
Reference in new issue
Block a user