diff --git a/extensions/vtk/package.json b/extensions/vtk/package.json
index 307c67f63..cfd3fb215 100644
--- a/extensions/vtk/package.json
+++ b/extensions/vtk/package.json
@@ -49,7 +49,7 @@
"dependencies": {
"@babel/runtime": "^7.5.5",
"lodash.throttle": "^4.1.1",
- "react-vtkjs-viewport": "^0.3.9"
+ "react-vtkjs-viewport": "^0.8.3"
},
"devDependencies": {
"@ohif/core": "^2.3.6",
diff --git a/extensions/vtk/src/ConnectedVTKViewport.js b/extensions/vtk/src/ConnectedVTKViewport.js
index baf50c2c4..1c1a500e6 100644
--- a/extensions/vtk/src/ConnectedVTKViewport.js
+++ b/extensions/vtk/src/ConnectedVTKViewport.js
@@ -1,6 +1,6 @@
import OHIF from '@ohif/core';
-import { View2D } from 'react-vtkjs-viewport';
import { connect } from 'react-redux';
+import VTKViewport from './VTKViewport';
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
@@ -18,6 +18,7 @@ const mapStateToProps = (state, ownProps) => {
const pluginDetails = viewportLayout.vtk || {};
return {
+ activeViewportIndex: state.viewports.activeViewportIndex,
layout: state.viewports.layout,
isActive,
...pluginDetails,
@@ -75,6 +76,6 @@ const ConnectedVTKViewport = connect(
mapStateToProps,
mapDispatchToProps,
mergeProps
-)(View2D);
+)(VTKViewport);
export default ConnectedVTKViewport;
diff --git a/extensions/vtk/src/OHIFVTKViewport.js b/extensions/vtk/src/OHIFVTKViewport.js
index 32732e5cd..379c87af3 100644
--- a/extensions/vtk/src/OHIFVTKViewport.js
+++ b/extensions/vtk/src/OHIFVTKViewport.js
@@ -77,6 +77,11 @@ class OHIFVTKViewport extends Component {
}),
viewportIndex: PropTypes.number,
children: PropTypes.node,
+ onScroll: PropTypes.func,
+ };
+
+ static defaultProps = {
+ onScroll: () => {},
};
static id = 'OHIFVTKViewport';
@@ -386,6 +391,7 @@ class OHIFVTKViewport extends Component {
this.state.paintFilterBackgroundImageData
}
viewportIndex={this.props.viewportIndex}
+ onScroll={this.props.onScroll}
/>
)}
diff --git a/extensions/vtk/src/VTKViewport.css b/extensions/vtk/src/VTKViewport.css
new file mode 100644
index 000000000..10fc3ac70
--- /dev/null
+++ b/extensions/vtk/src/VTKViewport.css
@@ -0,0 +1,3 @@
+.vtk-viewport-handler svg {
+ pointer-events: none;
+}
diff --git a/extensions/vtk/src/VTKViewport.js b/extensions/vtk/src/VTKViewport.js
new file mode 100644
index 000000000..fa77c262c
--- /dev/null
+++ b/extensions/vtk/src/VTKViewport.js
@@ -0,0 +1,58 @@
+import React, { useEffect, useCallback } from 'react';
+import { View2D } from 'react-vtkjs-viewport';
+import PropTypes from 'prop-types';
+
+import './VTKViewport.css';
+
+const VTKViewport = props => {
+ const style = { width: '100%', height: '100%', position: 'relative' };
+
+ const setViewportActiveHandler = useCallback(() => {
+ const { setViewportActive, viewportIndex, activeViewportIndex } = props;
+
+ if (viewportIndex !== activeViewportIndex) {
+ // set in Connected
+ setViewportActive();
+ }
+ });
+
+ useEffect(() => {
+ const handleScrollEvent = evt => {
+ const vtkViewportApiReference = props.onScroll(props.viewportIndex) || {};
+ const viewportUid = vtkViewportApiReference.uid;
+ const viewportWasScrolled = viewportUid === evt.detail.uid;
+
+ if (viewportWasScrolled) {
+ setViewportActiveHandler();
+ }
+ };
+
+ window.addEventListener('vtkscrollevent', handleScrollEvent);
+ return () =>
+ window.removeEventListener('vtkscrollevent', handleScrollEvent);
+ }, [props, props.onScroll, props.viewportIndex, setViewportActiveHandler]);
+
+ return (
+
+
+
+ );
+};
+
+VTKViewport.propTypes = {
+ setViewportActive: PropTypes.func.isRequired,
+ viewportIndex: PropTypes.number.isRequired,
+ activeViewportIndex: PropTypes.number.isRequired,
+ /* Receives viewportIndex */
+ onScroll: PropTypes.func,
+};
+
+VTKViewport.defaultProps = {
+ onScroll: () => {},
+};
+
+export default VTKViewport;
diff --git a/extensions/vtk/src/commandsModule.js b/extensions/vtk/src/commandsModule.js
index 4e85d99cc..a0aadcc1d 100644
--- a/extensions/vtk/src/commandsModule.js
+++ b/extensions/vtk/src/commandsModule.js
@@ -103,6 +103,9 @@ const commandsModule = ({ commandsManager }) => {
}
const actions = {
+ getVtkApis: ({ index }) => {
+ return apis[index];
+ },
axial: async ({ viewports }) => {
const api = await _getActiveViewportVTKApi(viewports);
@@ -266,11 +269,12 @@ const commandsModule = ({ commandsManager }) => {
'crosshairsWidget'
);
+ const uid = api.uid;
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
api.setInteractorStyle({
istyle,
- configuration: { apis, apiIndex },
+ configuration: { apis, apiIndex, uid },
});
});
},
@@ -296,55 +300,45 @@ const commandsModule = ({ commandsManager }) => {
},
enableRotateTool: {
commandFn: actions.enableRotateTool,
- storeContexts: [],
options: {},
},
enableCrosshairsTool: {
commandFn: actions.enableCrosshairsTool,
- storeContexts: [],
options: {},
},
enableLevelTool: {
commandFn: actions.enableLevelTool,
- storeContexts: [],
options: {},
},
setBlendModeToComposite: {
commandFn: actions.setBlendModeToComposite,
- storeContexts: [],
options: { blendMode: BlendMode.COMPOSITE_BLEND },
},
setBlendModeToMaximumIntensity: {
commandFn: actions.setBlendModeToMaximumIntensity,
- storeContexts: [],
options: { blendMode: BlendMode.MAXIMUM_INTENSITY_BLEND },
},
setBlendModeToMinimumIntensity: {
commandFn: actions.setBlendMode,
- storeContexts: [],
options: { blendMode: BlendMode.MINIMUM_INTENSITY_BLEND },
},
setBlendModeToAverageIntensity: {
commandFn: actions.setBlendMode,
- storeContexts: [],
options: { blendMode: BlendMode.AVERAGE_INTENSITY_BLEND },
},
setSlabThickness: {
// TODO: How do we pass in a function argument?
commandFn: actions.setSlabThickness,
- storeContexts: [],
options: {},
},
increaseSlabThickness: {
commandFn: actions.changeSlabThickness,
- storeContexts: [],
options: {
change: 3,
},
},
decreaseSlabThickness: {
commandFn: actions.changeSlabThickness,
- storeContexts: [],
options: {
change: -3,
},
@@ -355,6 +349,10 @@ const commandsModule = ({ commandsManager }) => {
options: {},
context: 'VIEWER',
},
+ getVtkApiForViewportIndex: {
+ commandFn: actions.getVtkApis,
+ context: 'VIEWER',
+ },
};
return {
diff --git a/extensions/vtk/src/index.js b/extensions/vtk/src/index.js
index dbc53f6e0..f66061b43 100644
--- a/extensions/vtk/src/index.js
+++ b/extensions/vtk/src/index.js
@@ -1,6 +1,7 @@
import asyncComponent from './asyncComponent.js';
import commandsModule from './commandsModule.js';
import toolbarModule from './toolbarModule.js';
+import withCommandsManager from './withCommandsManager.js';
// This feels weird
// import loadLocales from './loadLocales';
@@ -14,8 +15,8 @@ const vtkExtension = {
*/
id: 'vtk',
- getViewportModule() {
- return OHIFVTKViewport;
+ getViewportModule({ commandsManager }) {
+ return withCommandsManager(OHIFVTKViewport, commandsManager);
},
getToolbarModule() {
return toolbarModule;
diff --git a/extensions/vtk/src/withCommandsManager.js b/extensions/vtk/src/withCommandsManager.js
new file mode 100644
index 000000000..cec049547
--- /dev/null
+++ b/extensions/vtk/src/withCommandsManager.js
@@ -0,0 +1,18 @@
+import React from 'react';
+
+export default function withCommandsManager(Component, commandsManager = {}) {
+ return class WithCommandsManager extends React.Component {
+ render() {
+ return (
+
+ commandsManager.runCommand('getVtkApiForViewportIndex', {
+ index: viewportIndex,
+ })
+ }
+ />
+ );
+ }
+ };
+}
diff --git a/platform/core/src/classes/CommandsManager.js b/platform/core/src/classes/CommandsManager.js
index 52e70da11..ca4555206 100644
--- a/platform/core/src/classes/CommandsManager.js
+++ b/platform/core/src/classes/CommandsManager.js
@@ -161,7 +161,7 @@ export class CommandsManager {
return;
}
- const { commandFn, storeContexts } = definition;
+ const { commandFn, storeContexts = [] } = definition;
const definitionOptions = definition.options;
let commandParams = {};
diff --git a/yarn.lock b/yarn.lock
index b06bfd2fc..f5c75992a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1100,13 +1100,34 @@
pirates "^4.0.0"
source-map-support "^0.5.9"
-"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@7.6.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3":
+"@babel/runtime@7.1.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3"
+ integrity sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg==
+ dependencies:
+ regenerator-runtime "^0.12.0"
+
+"@babel/runtime@7.6.0":
+ version "7.6.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
+ integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==
+ dependencies:
+ regenerator-runtime "^0.13.2"
+
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
dependencies:
regenerator-runtime "^0.13.2"
+"@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
+ integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
+ dependencies:
+ regenerator-runtime "^0.13.2"
+
"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6"
@@ -15660,10 +15681,10 @@ react-transition-group@^4.1.1:
loose-envify "^1.4.0"
prop-types "^15.6.2"
-react-vtkjs-viewport@^0.3.9:
- version "0.3.9"
- resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.3.9.tgz#dc3dd5323c4cbaf5978cd64af2794b6b4ed61642"
- integrity sha512-Sc3dRRz8tRSdUrdgL8tuYwVEl0CTjaZfDLqP5ufMXH2KjwBt3T5bjpk4xvzFyPc9CG6ywEX5MSa6eQ+NNjaUkw==
+react-vtkjs-viewport@^0.8.2:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.8.2.tgz#cdccf156cb089d32b935ebc3dc5f31213ba17bef"
+ integrity sha512-2OPbU5y4ay+E6qfZw4sW19uqfBnNw9kAF1PaZ/Sk5XMEEKnebplEof9ZZtE6nhPImFqMCfu4TXzYVHIAPmwFYA==
dependencies:
date-fns "^2.2.1"
gl-matrix "^3.1.0"
@@ -16038,6 +16059,11 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+regenerator-runtime@^0.12.0:
+ version "0.12.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
+ integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
+
regenerator-runtime@^0.13.1, regenerator-runtime@^0.13.2:
version "0.13.3"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5"