Create and use ViewportGrid component

This commit is contained in:
dannyrb 2020-05-14 15:58:06 -04:00 committed by James A. Petts
parent ba152f082b
commit 70ce476c32
4 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,100 @@
/**
* CSS Grid Reference: http://grid.malven.co/
*/
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
//
import ViewportPane from './ViewportPane.jsx';
// import DefaultViewport from './DefaultViewport.js';
// import EmptyViewport from './EmptyViewport.js';
function ViewportGrid(props) {
const {
activeViewportIndex,
viewports,
displaySets,
numRows,
numColumns,
children,
} = props;
const rowSize = 100 / numRows;
const colSize = 100 / numColumns;
// viewportData --> displaySets
const getViewportPanes = () =>
viewports.map((viewport, viewportIndex) => {
const someId = viewport.displaySetId;
const displaySet = displaySets[someId];
if (!displaySet) {
// TODO: Empty Viewport
return null;
}
// const pluginName =
// !layout.plugin && displaySet && displaySet.plugin
// ? displaySet.plugin
// : layout.plugin;
// const ViewportComponent = _getViewportComponent(
// data, // Why do we pass this as `ViewportData`, when that's not really what it is?
// viewportIndex,
// children,
// pluginName,
// defaultPluginName
// );
return (
<ViewportPane
key={viewportIndex}
onDrop={() => { /* setDisplaySet for Viewport */ }}
viewportIndex={viewportIndex}
isActive={activeViewportIndex === viewportIndex}
>
{/* {ViewportComponent} */}
</ViewportPane>
);
});
// const ViewportPanes = React.useMemo(getViewportPanes, [
// viewportData,
// children,
// setViewportData,
// activeViewportIndex,
// ]);
return (
<div
data-cy="viewport-grid"
style={{
display: 'grid',
gridTemplateRows: `repeat(${numRows}, ${rowSize}%)`,
gridTemplateColumns: `repeat(${numColumns}, ${colSize}%)`,
height: '100%',
width: '100%',
}}
>
{/* {ViewportPanes} */}
</div>
);
};
ViewportGrid.propTypes = {
viewports: PropTypes.array.isRequired,
activeViewportIndex: PropTypes.number.isRequired,
children: PropTypes.node,
numRows: PropTypes.number.isRequired,
numColumns: PropTypes.number.isRequired,
};
ViewportGrid.defaultProps = {
viewports: [],
numRows: 1,
numColumns: 1,
activeViewportIndex: 0,
};
export default ViewportGrid;

View File

@ -0,0 +1,47 @@
import React from 'react';
import { useDrop } from 'react-dnd';
import PropTypes from 'prop-types';
import classNames from 'classnames';
const ViewportPane = function(props) {
const { children, onDrop, viewportIndex } = props;
const [{ isHovered, isHighlighted }, drop] = useDrop({
accept: 'displayset',
drop: (displaySet, monitor) => {
const canDrop = monitor.canDrop();
const isOver = monitor.isOver();
if (canDrop && isOver && onDrop) {
const { StudyInstanceUID, displaySetInstanceUID } = displaySet;
onDrop({ viewportIndex, StudyInstanceUID, displaySetInstanceUID });
}
},
// Monitor, and collect props; returned as values by `useDrop`
collect: monitor => ({
isHighlighted: monitor.canDrop(),
isHovered: monitor.isOver(),
}),
});
return (
<div
ref={drop}
className={classNames({ hovered: isHovered, highlighted: isHighlighted })}
data-cy={`viewport-pane-${viewportIndex}`}
>
{children}
</div>
);
};
ViewportPane.propTypes = {
/** The ViewportComp */
children: PropTypes.node.isRequired,
/** Function that handles drop events */
onDrop: PropTypes.func.isRequired,
/** The "index" of the viewport in the current ViewportGrid */
viewportIndex: PropTypes.number.isRequired,
};
export default ViewportPane;

View File

@ -0,0 +1,39 @@
/**
*
*
* @param {*} plugin
* @param {*} viewportData
* @param {*} viewportIndex
* @param {*} children
* @returns
*/
function _getViewportComponent(
viewportData,
viewportIndex,
children,
availablePlugins,
pluginName,
defaultPluginName
) {
if (viewportData.displaySet) {
pluginName = pluginName || defaultPluginName;
const ViewportComponent = availablePlugins[pluginName];
if (!ViewportComponent) {
throw new Error(
`No Viewport Component available for name ${pluginName}.
Available plugins: ${JSON.stringify(availablePlugins)}`
);
}
return (
<ViewportComponent
viewportData={viewportData}
viewportIndex={viewportIndex}
children={[children]}
/>
);
}
return <EmptyViewport />;
}

View File

@ -2,6 +2,7 @@ import React, { useContext, useEffect, useCallback } from 'react';
import { displaySetManager, ToolBarManager } from '@ohif/core';
import { useViewModel } from '@ohif/core';
import Compose from './Compose';
import ViewportGrid from './../components/ViewportGrid.jsx';
export default function ModeRoute({
location,
@ -85,10 +86,14 @@ export default function ModeRoute({
return (
<CombinedContextProvider>
{/* TODO: extensionManager is already provided to the extension module.
* Use it from there instead of passing as a prop here.
*/}
<LayoutComponent
extensionManager={extensionManager}
displaySetInstanceUids={displaySetInstanceUids}
toolBarLayout={toolBarLayout}
ViewportGrid={ViewportGrid}
{...layoutTemplateData.props}
/>
</CombinedContextProvider>