feat(extensions): Toolbar module depends on plugin in active viewport
This commit is contained in:
parent
2fdc1687d0
commit
f111411046
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -6,4 +6,7 @@
|
|||||||
url = https://github.com/OHIF/react-viewerbase.git
|
url = https://github.com/OHIF/react-viewerbase.git
|
||||||
[submodule "Packages-react/react-cornerstone-viewport"]
|
[submodule "Packages-react/react-cornerstone-viewport"]
|
||||||
path = Packages-react/react-cornerstone-viewport
|
path = Packages-react/react-cornerstone-viewport
|
||||||
url = https://github.com/cornerstonejs/react-cornerstone-viewport.git
|
url = https://github.com/cornerstonejs/react-cornerstone-viewport.git
|
||||||
|
[submodule "Packages-react/react-vtkjs-viewport"]
|
||||||
|
path = Packages-react/react-vtkjs-viewport
|
||||||
|
url = https://github.com/OHIF/react-vtkjs-viewport.git
|
||||||
|
|||||||
@ -22,4 +22,5 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
yalc.lock
|
yalc.lock
|
||||||
|
.yalc
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ohif-cornerstone-extension",
|
"name": "ohif-cornerstone-extension",
|
||||||
"version": "0.0.17",
|
"version": "0.0.20",
|
||||||
"description": "OHIF extension for Cornerstone",
|
"description": "OHIF extension for Cornerstone",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -26,12 +26,13 @@
|
|||||||
"dcmjs": "^0.3.3",
|
"dcmjs": "^0.3.3",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"ohif-core": "^0.3.0",
|
"ohif-core": "^0.3.3",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^15.0.0 || ^16.0.0",
|
"react": "^15.0.0 || ^16.0.0",
|
||||||
"react-dom": "^15.0.0 || ^16.0.0",
|
"react-dom": "^15.0.0 || ^16.0.0",
|
||||||
"react-redux": "^6.0.0",
|
"react-redux": "^6.0.0",
|
||||||
"react-resize-detector": "^3.4.0",
|
"react-resize-detector": "^3.4.0",
|
||||||
|
"react-viewerbase": "^0.2.10",
|
||||||
"redux": "^4.0.1"
|
"redux": "^4.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -51,6 +52,7 @@
|
|||||||
"gh-pages": "^2.0.1",
|
"gh-pages": "^2.0.1",
|
||||||
"husky": "^1.3.1",
|
"husky": "^1.3.1",
|
||||||
"lint-staged": "^8.1.0",
|
"lint-staged": "^8.1.0",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
"prettier": "^1.15.3",
|
"prettier": "^1.15.3",
|
||||||
"react": "^16.6.3",
|
"react": "^16.6.3",
|
||||||
"react-dom": "^16.6.3",
|
"react-dom": "^16.6.3",
|
||||||
@ -90,6 +92,6 @@
|
|||||||
"@babel/runtime": "^7.2.0",
|
"@babel/runtime": "^7.2.0",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"react-cornerstone-viewport": "^0.1.16"
|
"react-cornerstone-viewport": "^0.1.20"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { ToolbarSection } from 'react-viewerbase';
|
||||||
|
import OHIF from 'ohif-core'
|
||||||
|
|
||||||
|
const { setToolActive } = OHIF.redux.actions;
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
const activeButton = state.tools.buttons.find(tool => tool.active === true);
|
||||||
|
|
||||||
|
return {
|
||||||
|
buttons: state.tools.buttons,
|
||||||
|
activeCommand: activeButton && activeButton.command
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
setToolActive: tool => {
|
||||||
|
dispatch(setToolActive(tool.command))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConnectedToolbarSection = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ToolbarSection);
|
||||||
|
|
||||||
|
export default ConnectedToolbarSection;
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import OHIFCornerstoneViewport from './OHIFCornerstoneViewport.js';
|
import OHIFCornerstoneViewport from './OHIFCornerstoneViewport.js';
|
||||||
|
import ToolbarModule from './ToolbarModule.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass in 'children' to a React component. The purpose of this is to
|
* Pass in 'children' to a React component. The purpose of this is to
|
||||||
@ -48,6 +49,6 @@ export default class OHIFCornerstoneExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getToolbarModule() {
|
getToolbarModule() {
|
||||||
return null;
|
return ToolbarModule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import ConnectedToolbarSection from './ConnectedToolbarSection';
|
||||||
|
import { ToolbarButton } from 'react-viewerbase';
|
||||||
|
import ConnectedCineDialog from './ConnectedCineDialog';
|
||||||
|
|
||||||
|
class ToolbarModule extends Component {
|
||||||
|
state = {
|
||||||
|
cineDialogOpen: false
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickCineToolbarButton = () => {
|
||||||
|
this.setState({
|
||||||
|
cineDialogOpen: !this.state.cineDialogOpen
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const cineDialogContainerStyle = {
|
||||||
|
display: this.state.cineDialogOpen ? 'inline-block' : 'none'
|
||||||
|
};
|
||||||
|
|
||||||
|
return (<div className="ToolbarModule">
|
||||||
|
<ConnectedToolbarSection />
|
||||||
|
<ToolbarButton
|
||||||
|
active={this.state.cineDialogOpen}
|
||||||
|
onClick={this.onClickCineToolbarButton}
|
||||||
|
text={'CINE'}
|
||||||
|
iconClasses={'fab fa-youtube'}
|
||||||
|
/>
|
||||||
|
<div className="CineDialogContainer" style={cineDialogContainerStyle}>
|
||||||
|
<ConnectedCineDialog />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ToolbarModule;
|
||||||
@ -3248,6 +3248,11 @@ lodash.camelcase@^4.3.0:
|
|||||||
version "4.3.0"
|
version "4.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||||
|
|
||||||
|
lodash.clonedeep@^4.5.0:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||||
|
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||||
|
|
||||||
lodash.debounce@^4.0.8:
|
lodash.debounce@^4.0.8:
|
||||||
version "4.0.8"
|
version "4.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||||
@ -4413,10 +4418,10 @@ randomfill@^1.0.3:
|
|||||||
randombytes "^2.0.5"
|
randombytes "^2.0.5"
|
||||||
safe-buffer "^5.1.0"
|
safe-buffer "^5.1.0"
|
||||||
|
|
||||||
react-cornerstone-viewport@^0.1.16:
|
react-cornerstone-viewport@^0.1.20:
|
||||||
version "0.1.16"
|
version "0.1.20"
|
||||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.16.tgz#b1db13a3160ee10ffa9bfd91a6a0247f008170e2"
|
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.20.tgz#90e369a48e3f47dd5da69d42f0c8ee7e87e81543"
|
||||||
integrity sha512-hMEWoA3oDuurJ0AWZDH/hw1jPD7yY3EbaguE0CFusXdHsclCa7GjZXZb9EPqiAw8bF8vBIty7s96dwkqSFSLdw==
|
integrity sha512-SbaSjCAVFpQoUUXZ6d5F5QwKrP66zRJ4mN7JXPGyiL6+/m0jGkaBVci6pftkth66Lu5HRlCZUS8nh0plONPUtA==
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.debounce "^4.0.8"
|
lodash.debounce "^4.0.8"
|
||||||
moment "^2.23.0"
|
moment "^2.23.0"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ohif-dicom-pdf-extension",
|
"name": "ohif-dicom-pdf-extension",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"description": "OHIF extension for Dicom PDF",
|
"description": "OHIF extension for Dicom PDF",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"ohif-core": "^0.2.6",
|
"ohif-core": "^0.3.4",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^15.0.0 || ^16.0.0",
|
"react": "^15.0.0 || ^16.0.0",
|
||||||
"react-dom": "^15.0.0 || ^16.0.0"
|
"react-dom": "^15.0.0 || ^16.0.0"
|
||||||
|
|||||||
@ -17,11 +17,11 @@ export default class OHIFDicomPDFExtension {
|
|||||||
return OHIFDicomPDFSopClassHandler;
|
return OHIFDicomPDFSopClassHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPanelModuleDefinition() {
|
getPanelModule() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getToolbarModuleDefinition() {
|
getToolbarModule() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3173,11 +3173,6 @@ detect-port-alt@1.1.6:
|
|||||||
address "^1.0.1"
|
address "^1.0.1"
|
||||||
debug "^2.6.0"
|
debug "^2.6.0"
|
||||||
|
|
||||||
dicom-parser@^1.8.3:
|
|
||||||
version "1.8.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/dicom-parser/-/dicom-parser-1.8.3.tgz#6e4b862898112304db30143147562011c1ce6a4d"
|
|
||||||
integrity sha512-CMeUr+jea7Ml70N+/Z5Pd2MYtvLp6IU+TnvdLe6VRVKzZuTeYLYyuAQa9R+sFK4v4N39hig+hKHN+Wfi9sQ6GA==
|
|
||||||
|
|
||||||
diff@^3.2.0:
|
diff@^3.2.0:
|
||||||
version "3.5.0"
|
version "3.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||||
|
|||||||
14
Packages-react/extensions/ohif-vtk-extension/.babelrc
Normal file
14
Packages-react/extensions/ohif-vtk-extension/.babelrc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["@babel/preset-env", {
|
||||||
|
"targets": {
|
||||||
|
"ie": "11"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"@babel/preset-react"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-proposal-class-properties",
|
||||||
|
"@babel/plugin-transform-runtime"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
16
Packages-react/extensions/ohif-vtk-extension/.eslintrc
Normal file
16
Packages-react/extensions/ohif-vtk-extension/.eslintrc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:react/recommended"
|
||||||
|
],
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"env": {
|
||||||
|
"jest": true
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"react": {
|
||||||
|
"version": "detect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
25
Packages-react/extensions/ohif-vtk-extension/.gitignore
vendored
Normal file
25
Packages-react/extensions/ohif-vtk-extension/.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# builds
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
.rpt2_cache
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.idea
|
||||||
|
|
||||||
|
yalc.lock
|
||||||
3
Packages-react/extensions/ohif-vtk-extension/.prettierrc
Normal file
3
Packages-react/extensions/ohif-vtk-extension/.prettierrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
4
Packages-react/extensions/ohif-vtk-extension/.travis.yml
Normal file
4
Packages-react/extensions/ohif-vtk-extension/.travis.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 9
|
||||||
|
- 8
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Open Health Imaging Foundation
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
# react-vtkjs-viewport
|
||||||
|
|
||||||
|
> VTK.js image viewport component for React
|
||||||
|
|
||||||
|
[](https://www.npmjs.com/package/react-vtkjs-viewport)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save react-vtkjs-viewport
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
|
||||||
|
import CornerstoneViewport from 'react-cornerstone-viewport'
|
||||||
|
|
||||||
|
class Example extends Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<CornerstoneViewport />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT © [OHIF](https://github.com/OHIF)
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"name": "react-vtkjs-viewport",
|
||||||
|
"version": "0.0.6-76b678ec",
|
||||||
|
"description": "VTK.js image viewport component for React",
|
||||||
|
"author": "OHIF Contributors",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "OHIF/react-vtkjs-viewport",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8",
|
||||||
|
"npm": ">=5"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --progress --colors --mode development",
|
||||||
|
"build:release": "webpack --progress --colors --mode production",
|
||||||
|
"start": "webpack --watch --progress --colors --mode development",
|
||||||
|
"prepare": "npm run build:release",
|
||||||
|
"predeploy": "cd example && npm install && npm run build:release",
|
||||||
|
"prepublishOnly": "npm run build:release",
|
||||||
|
"deploy": "gh-pages -d example/build",
|
||||||
|
"generateStaticSite": "./generateStaticSite.sh"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^15.0.0 || ^16.0.0",
|
||||||
|
"react-dom": "^15.0.0 || ^16.0.0"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"src/**/*.{js,jsx,json,css}": [
|
||||||
|
"prettier --single-quote --write",
|
||||||
|
"git add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": "react-app"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not ie <= 11",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"cornerstone-core": "^2.2.8",
|
||||||
|
"cornerstone-math": "^0.1.8",
|
||||||
|
"vtk.js": "^8.3.11"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
76b678ec6a9c889ca68231a62fd71346
|
||||||
21
Packages-react/extensions/ohif-vtk-extension/LICENSE
Normal file
21
Packages-react/extensions/ohif-vtk-extension/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Open Health Imaging Foundation
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
95
Packages-react/extensions/ohif-vtk-extension/package.json
Normal file
95
Packages-react/extensions/ohif-vtk-extension/package.json
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{
|
||||||
|
"name": "ohif-vtk-extension",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "OHIF extension for VTK.js",
|
||||||
|
"author": "OHIF",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "OHIF/Viewers",
|
||||||
|
"main": "dist/index.umd.js",
|
||||||
|
"module": "dist/index.es.js",
|
||||||
|
"jsnext:main": "dist/index.es.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8",
|
||||||
|
"npm": ">=5"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "rollup -c",
|
||||||
|
"prepublishOnly": "npm run build",
|
||||||
|
"start": "rollup -c -w",
|
||||||
|
"lint": "eslint -c .eslintrc --fix src && prettier --single-quote --write src/**/*.{js,jsx,json,css}"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"cornerstone-core": "^2.2.8",
|
||||||
|
"cornerstone-math": "^0.1.8",
|
||||||
|
"cornerstone-tools": "^3.1.0",
|
||||||
|
"cornerstone-wado-image-loader": "^2.2.3",
|
||||||
|
"dcmjs": "^0.3.6",
|
||||||
|
"dicom-parser": "^1.8.3",
|
||||||
|
"hammerjs": "^2.0.8",
|
||||||
|
"ohif-core": "^0.3.3",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"react": "^15.0.0 || ^16.0.0",
|
||||||
|
"react-dom": "^15.0.0 || ^16.0.0",
|
||||||
|
"react-redux": "^6.0.0",
|
||||||
|
"react-resize-detector": "^3.4.0",
|
||||||
|
"redux": "^4.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.2.2",
|
||||||
|
"@babel/plugin-external-helpers": "^7.2.0",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.2.3",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.2.0",
|
||||||
|
"@babel/preset-env": "^7.2.3",
|
||||||
|
"@babel/preset-react": "^7.0.0",
|
||||||
|
"babel-eslint": "^10.0.1",
|
||||||
|
"cross-env": "^5.2.0",
|
||||||
|
"eslint": "5.13.0",
|
||||||
|
"eslint-plugin-import": "^2.14.0",
|
||||||
|
"eslint-plugin-node": "^8.0.0",
|
||||||
|
"eslint-plugin-promise": "^4.0.1",
|
||||||
|
"eslint-plugin-react": "^7.11.1",
|
||||||
|
"gh-pages": "^2.0.1",
|
||||||
|
"husky": "^1.3.1",
|
||||||
|
"lint-staged": "^8.1.0",
|
||||||
|
"prettier": "^1.15.3",
|
||||||
|
"react": "^16.6.3",
|
||||||
|
"react-dom": "^16.6.3",
|
||||||
|
"react-viewerbase": "^0.2.10",
|
||||||
|
"rollup": "^1.1.2",
|
||||||
|
"rollup-plugin-babel": "^4.2.0",
|
||||||
|
"rollup-plugin-commonjs": "^9.2.0",
|
||||||
|
"rollup-plugin-node-builtins": "^2.1.2",
|
||||||
|
"rollup-plugin-node-resolve": "^4.0.0",
|
||||||
|
"rollup-plugin-peer-deps-external": "^2.2.0",
|
||||||
|
"rollup-plugin-postcss": "^2.0.3",
|
||||||
|
"rollup-plugin-url": "^2.1.0",
|
||||||
|
"stylelint": "^9.9.0",
|
||||||
|
"stylelint-config-recommended": "^2.1.0",
|
||||||
|
"stylus": "^0.54.5"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"src/**/*.{js,jsx,json,css}": [
|
||||||
|
"prettier --single-quote --write",
|
||||||
|
"git add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not ie <= 11",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.2.0",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"react-vtkjs-viewport": "file:.yalc/react-vtkjs-viewport"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
import babel from 'rollup-plugin-babel'
|
||||||
|
import commonjs from 'rollup-plugin-commonjs'
|
||||||
|
import external from 'rollup-plugin-peer-deps-external'
|
||||||
|
import postcss from 'rollup-plugin-postcss'
|
||||||
|
import resolve from 'rollup-plugin-node-resolve'
|
||||||
|
import url from 'rollup-plugin-url'
|
||||||
|
import pkg from './package.json'
|
||||||
|
// Deal with https://github.com/rollup/rollup-plugin-commonjs/issues/297
|
||||||
|
import builtins from 'rollup-plugin-node-builtins';
|
||||||
|
|
||||||
|
const globals = {
|
||||||
|
'react': 'React',
|
||||||
|
'react-dom': 'ReactDOM',
|
||||||
|
'react-redux': 'ReactRedux',
|
||||||
|
'react-resize-detector': 'ReactResizeDetector',
|
||||||
|
'prop-types': 'PropTypes',
|
||||||
|
'cornerstone-core': 'cornerstone',
|
||||||
|
'cornerstone-wado-image-loader': 'cornerstoneWADOImageLoader',
|
||||||
|
'cornerstone-math': 'cornerstoneMath',
|
||||||
|
'cornerstone-tools': 'cornerstoneTools',
|
||||||
|
'dcmjs': 'dcmjs',
|
||||||
|
'dicom-parser': 'dicomParser',
|
||||||
|
'ohif-core': 'OHIF',
|
||||||
|
'hammerjs': 'Hammer'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
input: 'src/index.js',
|
||||||
|
output: [
|
||||||
|
{
|
||||||
|
file: pkg.main,
|
||||||
|
format: 'umd',
|
||||||
|
name: 'ohif-vtk-extension',
|
||||||
|
sourcemap: true,
|
||||||
|
globals
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: pkg.module,
|
||||||
|
format: 'es',
|
||||||
|
sourcemap: true,
|
||||||
|
globals
|
||||||
|
}
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
builtins(),
|
||||||
|
external(),
|
||||||
|
postcss({
|
||||||
|
modules: false
|
||||||
|
}),
|
||||||
|
url(),
|
||||||
|
babel({
|
||||||
|
exclude: 'node_modules/**',
|
||||||
|
externalHelpers: true,
|
||||||
|
runtimeHelpers: true
|
||||||
|
}),
|
||||||
|
resolve(),
|
||||||
|
commonjs({
|
||||||
|
include: ['node_modules/**', '.yalc/**'],
|
||||||
|
namedExports: {
|
||||||
|
'.yalc/react-vtkjs-viewport/dist/index.js': [
|
||||||
|
'getImageData',
|
||||||
|
'loadImageData',
|
||||||
|
'VTKViewport',
|
||||||
|
'VTKMPRViewport',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
external: Object.keys(pkg.peerDependencies || {}),
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { ToolbarSection } from 'react-viewerbase';
|
||||||
|
import OHIF from 'ohif-core'
|
||||||
|
|
||||||
|
const { setToolActive } = OHIF.redux.actions;
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
const activeButton = state.tools.buttons.find(tool => tool.active === true);
|
||||||
|
|
||||||
|
return {
|
||||||
|
buttons: [ {
|
||||||
|
command: 'Rotate',
|
||||||
|
type: 'tool',
|
||||||
|
text: 'Rotate',
|
||||||
|
iconClasses: 'fa fa-rotate',
|
||||||
|
//svgUrl: `${Icons}#icon-tools-stack-scroll`,
|
||||||
|
active: true
|
||||||
|
}],
|
||||||
|
activeCommand: 'Rotate'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
setToolActive: tool => {
|
||||||
|
//dispatch(setToolActive(tool.command))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConnectedToolbarSection = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ToolbarSection);
|
||||||
|
|
||||||
|
export default ConnectedToolbarSection;
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { VTKMPRViewport } from 'react-vtkjs-viewport';
|
||||||
|
import OHIF from 'ohif-core';
|
||||||
|
|
||||||
|
const {
|
||||||
|
setViewportActive,
|
||||||
|
setViewportSpecificData,
|
||||||
|
clearViewportSpecificData
|
||||||
|
} = OHIF.redux.actions;
|
||||||
|
|
||||||
|
const mapStateToProps = (state, ownProps) => {
|
||||||
|
const activeButton = state.tools.buttons.find(tool => tool.active === true);
|
||||||
|
let dataFromStore;
|
||||||
|
|
||||||
|
if (state.extensions && state.extensions.vtk) {
|
||||||
|
dataFromStore = state.extensions.vtk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is the active viewport, enable prefetching.
|
||||||
|
const { viewportIndex } = ownProps; //.viewportData;
|
||||||
|
const isActive = viewportIndex === state.viewports.activeViewportIndex;
|
||||||
|
const viewportSpecificData =
|
||||||
|
state.viewports.viewportSpecificData[viewportIndex] || {};
|
||||||
|
|
||||||
|
const viewportLayout = state.viewports.layout.viewports[viewportIndex];
|
||||||
|
const pluginDetails = viewportLayout.vtk || {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
layout: state.viewports.layout,
|
||||||
|
isActive,
|
||||||
|
...pluginDetails,
|
||||||
|
activeTool: activeButton && activeButton.command,
|
||||||
|
...dataFromStore,
|
||||||
|
enableStackPrefetch: isActive,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => {
|
||||||
|
const { viewportIndex } = ownProps;
|
||||||
|
|
||||||
|
return {
|
||||||
|
setViewportActive: () => {
|
||||||
|
dispatch(setViewportActive(viewportIndex));
|
||||||
|
},
|
||||||
|
|
||||||
|
setViewportSpecificData: data => {
|
||||||
|
dispatch(setViewportSpecificData(viewportIndex, data));
|
||||||
|
},
|
||||||
|
|
||||||
|
clearViewportSpecificData: () => {
|
||||||
|
dispatch(clearViewportSpecificData(viewportIndex));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConnectedVTKViewport = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
//mapDispatchToProps
|
||||||
|
)(VTKMPRViewport);
|
||||||
|
|
||||||
|
export default ConnectedVTKViewport;
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
.imageViewerLoadingIndicator {
|
||||||
|
color: #91B9CD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loadingIndicator {
|
||||||
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
font-size: 18px;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
/* Necessary for click-through to cornerstone element below */
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import './LoadingIndicator.css';
|
||||||
|
|
||||||
|
class LoadingIndicator extends PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
percentComplete: PropTypes.number.isRequired,
|
||||||
|
error: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
percentComplete: 0,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let percComplete;
|
||||||
|
if (this.props.percentComplete && this.props.percentComplete !== 100) {
|
||||||
|
percComplete = `${this.props.percentComplete}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{this.props.error ? (
|
||||||
|
<div className="imageViewerErrorLoadingIndicator loadingIndicator">
|
||||||
|
<div className="indicatorContents">
|
||||||
|
<h4>Error Loading Image</h4>
|
||||||
|
<p className="description">An error has occurred.</p>
|
||||||
|
<p className="details">{this.props.error.message}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="imageViewerLoadingIndicator loadingIndicator">
|
||||||
|
<div className="indicatorContents">
|
||||||
|
<p>
|
||||||
|
Loading... <i className="fa fa-spin fa-circle-o-notch fa-fw" />{' '}
|
||||||
|
{percComplete}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoadingIndicator;
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import OHIFVTKViewport from './OHIFVTKViewport.js';
|
||||||
|
import ToolbarModule from './ToolbarModule.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass in 'children' to a React component. The purpose of this is to
|
||||||
|
* allow end users of this extension to pass in components which will
|
||||||
|
* be rendered on top of the base components.
|
||||||
|
*
|
||||||
|
* @param WrappedComponent
|
||||||
|
* @param children
|
||||||
|
* @return {function(*): *}
|
||||||
|
*/
|
||||||
|
function withChildren(WrappedComponent, children) {
|
||||||
|
return function(props) {
|
||||||
|
return <WrappedComponent children={children} { ...props } />;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: If you are authoring extensions which use stateful libraries (e.g. cornerstone-core, react-redux) as peerDependencies and are also duplicated at the application level, try using 'yalc' to link it to the application, rather than yarn link. This can help fix 'module not found' issues.
|
||||||
|
// https://github.com/whitecolor/yalc
|
||||||
|
|
||||||
|
export default class OHIFVTKExtension {
|
||||||
|
constructor(children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension ID is a unique id, might be used for namespacing extension specific redux actions/reducers (?)
|
||||||
|
*/
|
||||||
|
getExtensionId() {
|
||||||
|
return 'vtk';
|
||||||
|
}
|
||||||
|
|
||||||
|
getViewportModule() {
|
||||||
|
if (this.children && this.children.viewport) {
|
||||||
|
return withChildren(OHIFVTKViewport, this.children.viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OHIFVTKViewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSopClassHandler() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPanelModule() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getToolbarModule() {
|
||||||
|
return ToolbarModule;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,258 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import OHIF from 'ohif-core';
|
||||||
|
import ConnectedVTKViewport from './ConnectedVTKViewport';
|
||||||
|
import cornerstone from 'cornerstone-core';
|
||||||
|
import handleSegmentationStorage from './handleSegmentationStorage.js';
|
||||||
|
import { getImageData, loadImageData } from 'react-vtkjs-viewport';
|
||||||
|
import LoadingIndicator from './LoadingIndicator.js';
|
||||||
|
|
||||||
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
|
// Metadata configuration
|
||||||
|
const metadataProvider = new OHIF.cornerstone.MetadataProvider();
|
||||||
|
|
||||||
|
cornerstone.metaData.addProvider(
|
||||||
|
metadataProvider.provider.bind(metadataProvider)
|
||||||
|
);
|
||||||
|
|
||||||
|
StackManager.setMetadataProvider(metadataProvider);
|
||||||
|
|
||||||
|
const SOP_CLASSES = {
|
||||||
|
SEGMENTATION_STORAGE: '1.2.840.10008.5.1.4.1.1.66.4'
|
||||||
|
};
|
||||||
|
|
||||||
|
const specialCaseHandlers = {};
|
||||||
|
specialCaseHandlers[
|
||||||
|
SOP_CLASSES.SEGMENTATION_STORAGE
|
||||||
|
] = handleSegmentationStorage;
|
||||||
|
|
||||||
|
class OHIFVTKViewport extends Component {
|
||||||
|
state = {
|
||||||
|
viewportData: null
|
||||||
|
};
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
studies: PropTypes.object,
|
||||||
|
displaySet: PropTypes.object,
|
||||||
|
viewportIndex: PropTypes.number,
|
||||||
|
children: PropTypes.node
|
||||||
|
};
|
||||||
|
|
||||||
|
static id = 'OHIFCornerstoneViewport';
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
console.log('OHIFCornerstoneViewport init()');
|
||||||
|
}
|
||||||
|
|
||||||
|
static destroy() {
|
||||||
|
console.log('OHIFCornerstoneViewport destroy()');
|
||||||
|
StackManager.clearStacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCornerstoneStack(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
) {
|
||||||
|
// Create shortcut to displaySet
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
const displaySet = study.displaySets.find(set => {
|
||||||
|
return set.displaySetInstanceUid === displaySetInstanceUid;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get stack from Stack Manager
|
||||||
|
const storedStack = StackManager.findOrCreateStack(study, displaySet);
|
||||||
|
|
||||||
|
// Clone the stack here so we don't mutate it
|
||||||
|
const stack = Object.assign({}, storedStack);
|
||||||
|
|
||||||
|
if (frameIndex !== undefined) {
|
||||||
|
stack.currentImageIdIndex = frameIndex;
|
||||||
|
} else if (sopInstanceUid) {
|
||||||
|
const index = stack.imageIds.findIndex(imageId => {
|
||||||
|
const sopCommonModule = cornerstone.metaData.get(
|
||||||
|
'sopCommonModule',
|
||||||
|
imageId
|
||||||
|
);
|
||||||
|
if (!sopCommonModule) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sopCommonModule.sopInstanceUID === sopInstanceUid;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
stack.currentImageIdIndex = index;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack.currentImageIdIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getViewportData = (
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
) => {
|
||||||
|
return OHIFVTKViewport.getCornerstoneStack(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
getViewportData = (
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const stack = OHIFVTKViewport.getViewportData(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (sopClassUid) {
|
||||||
|
case SOP_CLASSES.SEGMENTATION_STORAGE:
|
||||||
|
throw new Error("Not yet implemented");
|
||||||
|
|
||||||
|
const data = handleSegmentationStorage(stack.imageIds, displaySetInstanceUid, cornerstone);
|
||||||
|
const imageDataObject = data.referenceDataObject;
|
||||||
|
const labelmapDataObject = data.labelmapDataObject;
|
||||||
|
|
||||||
|
const doneLoadingCallback = () => {
|
||||||
|
resolve({
|
||||||
|
data: imageDataObject.vtkImageData,
|
||||||
|
labelmap: labelmapDataObject
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const callbacks = [
|
||||||
|
doneLoadingCallback
|
||||||
|
];
|
||||||
|
|
||||||
|
loadImageData(imageDataObject, callbacks, cornerstone);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const imageDataObject = getImageData(stack.imageIds, displaySetInstanceUid, cornerstone);
|
||||||
|
const doneLoadingCallback = () => {
|
||||||
|
resolve({
|
||||||
|
data: imageDataObject.vtkImageData,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const callbacks = [
|
||||||
|
doneLoadingCallback
|
||||||
|
];
|
||||||
|
|
||||||
|
loadImageData(imageDataObject, callbacks, cornerstone);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
setStateFromProps() {
|
||||||
|
const { studies, displaySet } = this.props.viewportData;
|
||||||
|
const {
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUids,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
} = displaySet;
|
||||||
|
|
||||||
|
if (sopClassUids.length > 1) {
|
||||||
|
console.warn(
|
||||||
|
'More than one SOPClassUid in the same series is not yet supported.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sopClassUid = sopClassUids[0];
|
||||||
|
|
||||||
|
this.getViewportData(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUid,
|
||||||
|
sopInstanceUid,
|
||||||
|
frameIndex
|
||||||
|
).then(({ data, labelmap })=> {
|
||||||
|
this.setState({
|
||||||
|
viewportData: data,
|
||||||
|
labelmap
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setStateFromProps();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
const { studies, displaySet } = this.props.viewportData;
|
||||||
|
const prevDisplaySet = prevProps.viewportData.displaySet;
|
||||||
|
|
||||||
|
if (
|
||||||
|
displaySet.displaySetInstanceUid !==
|
||||||
|
prevDisplaySet.displaySetInstanceUid ||
|
||||||
|
displaySet.sopInstanceUid !== prevDisplaySet.sopInstanceUid ||
|
||||||
|
displaySet.frameIndex !== prevDisplaySet.frameIndex
|
||||||
|
) {
|
||||||
|
this.setStateFromProps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let childrenWithProps = null;
|
||||||
|
|
||||||
|
// TODO: Does it make more sense to use Context?
|
||||||
|
if (this.props.children && this.props.children.length) {
|
||||||
|
childrenWithProps = this.props.children.map((child, index) => {
|
||||||
|
return React.cloneElement(child, {
|
||||||
|
viewportIndex: this.props.viewportIndex,
|
||||||
|
key: index
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const style = { width: '100%', height: '100%', position: 'relative' };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{this.state.viewportData ? (
|
||||||
|
<ConnectedVTKViewport
|
||||||
|
data={this.state.viewportData}
|
||||||
|
labelmap={this.state.labelmap}
|
||||||
|
viewportIndex={this.props.viewportIndex}
|
||||||
|
/>
|
||||||
|
) : <div style={style}>
|
||||||
|
<LoadingIndicator/>
|
||||||
|
</div>}
|
||||||
|
{childrenWithProps}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OHIFVTKViewport;
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import ConnectedToolbarSection from './ConnectedToolbarSection';
|
||||||
|
|
||||||
|
class ToolbarModule extends Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="ToolbarModule">
|
||||||
|
<ConnectedToolbarSection />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ToolbarModule;
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
import OHIF from 'ohif-core';
|
||||||
|
import cornerstone from 'cornerstone-core';
|
||||||
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
|
import * as dcmjs from 'dcmjs';
|
||||||
|
|
||||||
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
|
function getDisplaySet(studies, studyInstanceUid, displaySetInstanceUid) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
const displaySet = study.displaySets.find(set => {
|
||||||
|
return set.displaySetInstanceUid === displaySetInstanceUid;
|
||||||
|
});
|
||||||
|
|
||||||
|
return displaySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplaySetsBySeries(studies, studyInstanceUid, seriesInstanceUid) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
return study.displaySets.filter(set => {
|
||||||
|
return set.seriesInstanceUid === seriesInstanceUid;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCornerstoneStack(studies, studyInstanceUid, displaySetInstanceUid) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create shortcut to displaySet
|
||||||
|
const displaySet = getDisplaySet(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get stack from Stack Manager
|
||||||
|
const stack = StackManager.findOrCreateStack(study, displaySet);
|
||||||
|
|
||||||
|
// Clone the stack here so we don't mutate it later
|
||||||
|
const stackClone = Object.assign({}, stack);
|
||||||
|
stackClone.currentImageIdIndex = 0;
|
||||||
|
|
||||||
|
return stackClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
function retrieveDicomData(wadoUri) {
|
||||||
|
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
||||||
|
// we will need to figure out how / when to pass this information in.
|
||||||
|
return fetch(wadoUri, {
|
||||||
|
headers: OHIF.DICOMWeb.getAuthorizationHeader()
|
||||||
|
}).then(response => response.arrayBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSegmentationStorage(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
const displaySet = getDisplaySet(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
const segWadoUri = displaySet.images[0].getData().wadouri;
|
||||||
|
const arrayBuffer = await retrieveDicomData(segWadoUri);
|
||||||
|
const dicomData = dcmjs.data.DicomMessage.readFile(arrayBuffer);
|
||||||
|
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
|
||||||
|
dicomData.dict
|
||||||
|
);
|
||||||
|
|
||||||
|
const segments = dcmjs.adapters.VTKjs.Segmentation.generateSegments(dataset);
|
||||||
|
|
||||||
|
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(dicomData.meta);
|
||||||
|
|
||||||
|
const seriesInstanceUid = dataset.ReferencedSeriesSequence.SeriesInstanceUID;
|
||||||
|
const displaySets = getDisplaySetsBySeries(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
seriesInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
if (displaySets.length > 1) {
|
||||||
|
console.warn(
|
||||||
|
'More than one display set with the same seriesInstanceUid. This is not supported yet...'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const referenceDisplaySet = displaySets[0];
|
||||||
|
const imageIds = referenceDisplaySet.images.map(image => image.getImageId());
|
||||||
|
|
||||||
|
if (!results) {
|
||||||
|
throw new Error('Fractional segmentations are not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachedStack = StackManager.findOrCreateStack(
|
||||||
|
study,
|
||||||
|
referenceDisplaySet
|
||||||
|
);
|
||||||
|
const stack = Object.assign({}, cachedStack);
|
||||||
|
stack.currentImageIdIndex = 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
referenceDataObject,
|
||||||
|
labelmapDataObject
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
stack
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default handleSegmentationStorage;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
import OHIFVTKExtension from './OHIFVTKExtension.js';
|
||||||
|
|
||||||
|
export default OHIFVTKExtension;
|
||||||
8949
Packages-react/extensions/ohif-vtk-extension/yarn.lock
Normal file
8949
Packages-react/extensions/ohif-vtk-extension/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
|||||||
Subproject commit 10701c5425c58ccfca7d8758a1698f438bc197e9
|
Subproject commit a728166da104670b9d62ba4cd8ec4eef645ff29e
|
||||||
5
Packages-react/ohif-viewer/.gitignore
vendored
5
Packages-react/ohif-viewer/.gitignore
vendored
@ -4,4 +4,7 @@ node_modules
|
|||||||
yarn.lock
|
yarn.lock
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
src/sha.js
|
src/sha.js
|
||||||
src/version.js
|
src/version.js
|
||||||
|
|
||||||
|
.yalc
|
||||||
|
yalc.lock
|
||||||
@ -106,11 +106,11 @@
|
|||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"ohif-core": "^0.3.3",
|
"ohif-core": "^0.3.4",
|
||||||
"ohif-cornerstone-extension": "0.0.17",
|
"ohif-cornerstone-extension": "^0.0.20",
|
||||||
"ohif-dicom-html-extension": "^0.0.2",
|
"ohif-dicom-html-extension": "^0.0.2",
|
||||||
"ohif-dicom-microscopy-extension": "^0.0.5",
|
"ohif-dicom-microscopy-extension": "^0.0.5",
|
||||||
"ohif-dicom-pdf-extension": "^0.0.5",
|
"ohif-dicom-pdf-extension": "^0.0.6",
|
||||||
"oidc-client": "^1.6.1",
|
"oidc-client": "^1.6.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react-bootstrap-modal": "^4.2.0",
|
"react-bootstrap-modal": "^4.2.0",
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import ui from './redux/ui.js';
|
|||||||
import OHIFStandaloneViewer from './OHIFStandaloneViewer';
|
import OHIFStandaloneViewer from './OHIFStandaloneViewer';
|
||||||
import WhiteLabellingContext from './WhiteLabellingContext';
|
import WhiteLabellingContext from './WhiteLabellingContext';
|
||||||
import OHIFCornerstoneExtension from 'ohif-cornerstone-extension';
|
import OHIFCornerstoneExtension from 'ohif-cornerstone-extension';
|
||||||
|
//import OHIFVTKExtension from 'ohif-vtk-extension';
|
||||||
import OHIFDicomPDFExtension from 'ohif-dicom-pdf-extension';
|
import OHIFDicomPDFExtension from 'ohif-dicom-pdf-extension';
|
||||||
import OHIFDicomHtmlExtension from 'ohif-dicom-html-extension';
|
import OHIFDicomHtmlExtension from 'ohif-dicom-html-extension';
|
||||||
import OHIFDicomMicroscopyExtension from 'ohif-dicom-microscopy-extension';
|
import OHIFDicomMicroscopyExtension from 'ohif-dicom-microscopy-extension';
|
||||||
@ -146,6 +147,7 @@ store.dispatch(toolAction);
|
|||||||
/** TODO: extensions should be passed in as prop as soon as we have the extensions as separate packages and then registered by ExtensionsManager */
|
/** TODO: extensions should be passed in as prop as soon as we have the extensions as separate packages and then registered by ExtensionsManager */
|
||||||
const extensions = [
|
const extensions = [
|
||||||
new OHIFCornerstoneExtension(),
|
new OHIFCornerstoneExtension(),
|
||||||
|
//new OHIFVTKExtension(),
|
||||||
new OHIFDicomPDFExtension(),
|
new OHIFDicomPDFExtension(),
|
||||||
new OHIFDicomHtmlExtension(),
|
new OHIFDicomHtmlExtension(),
|
||||||
new OHIFDicomMicroscopyExtension()
|
new OHIFDicomMicroscopyExtension()
|
||||||
|
|||||||
@ -0,0 +1,130 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import PluginSwitch from './PluginSwitch.js';
|
||||||
|
import OHIF from 'ohif-core'
|
||||||
|
|
||||||
|
const { setLayout } = OHIF.redux.actions;
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
const { activeViewportIndex, layout } = state.viewports;
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeViewportIndex,
|
||||||
|
layout
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
setLayout: (data) => {
|
||||||
|
dispatch(setLayout(data))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function setSingleLayoutData(originalArray, viewportIndex, data) {
|
||||||
|
const viewports = originalArray.slice();
|
||||||
|
const layoutData = Object.assign({}, viewports[viewportIndex], data);
|
||||||
|
|
||||||
|
viewports[viewportIndex] = layoutData;
|
||||||
|
|
||||||
|
return viewports;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergeProps = (propsFromState, propsFromDispatch, ownProps) => {
|
||||||
|
const { activeViewportIndex, layout } = propsFromState;
|
||||||
|
const { setLayout } = propsFromDispatch;
|
||||||
|
|
||||||
|
// TODO: Do not display certain options if the current display set
|
||||||
|
// cannot be displayed using these view types
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
title: 'Original Acquisition',
|
||||||
|
onClick: (click) => {
|
||||||
|
console.warn('Original Acquisition');
|
||||||
|
|
||||||
|
const layoutData = setSingleLayoutData(layout.viewports, activeViewportIndex, { plugin: 'cornerstone'});
|
||||||
|
|
||||||
|
setLayout({ viewports: layoutData });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Axial',
|
||||||
|
onClick: (click) => {
|
||||||
|
console.warn('Axial');
|
||||||
|
const data = {
|
||||||
|
plugin: 'vtk',
|
||||||
|
vtk: {
|
||||||
|
mode: 'mpr',
|
||||||
|
sliceNormal: [0, 0, 1]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const layoutData = setSingleLayoutData(layout.viewports, activeViewportIndex, data);
|
||||||
|
|
||||||
|
setLayout({ viewports: layoutData });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Sagittal',
|
||||||
|
onClick: (click) => {
|
||||||
|
console.warn('Sagittal');
|
||||||
|
const data = {
|
||||||
|
plugin: 'vtk',
|
||||||
|
vtk: {
|
||||||
|
mode: 'mpr',
|
||||||
|
sliceNormal: [1, 0, 0]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const layoutData = setSingleLayoutData(layout.viewports, activeViewportIndex, data);
|
||||||
|
|
||||||
|
setLayout({ viewports: layoutData });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Coronal',
|
||||||
|
onClick: (click) => {
|
||||||
|
console.warn('Coronal');
|
||||||
|
const data = {
|
||||||
|
plugin: 'vtk',
|
||||||
|
vtk: {
|
||||||
|
mode: 'mpr',
|
||||||
|
sliceNormal: [0, 1, 0]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const layoutData = setSingleLayoutData(layout.viewports, activeViewportIndex, data);
|
||||||
|
|
||||||
|
setLayout({ viewports: layoutData });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '3D Perspective',
|
||||||
|
onClick: (click) => {
|
||||||
|
console.warn('3D Perspective');
|
||||||
|
const data = {
|
||||||
|
plugin: 'vtk',
|
||||||
|
vtk: {
|
||||||
|
mode: '3d',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const layoutData = setSingleLayoutData(layout.viewports, activeViewportIndex, data);
|
||||||
|
|
||||||
|
setLayout({ viewports: layoutData });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return {
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const ConnectedPluginSwitch = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps,
|
||||||
|
mergeProps
|
||||||
|
)(PluginSwitch);
|
||||||
|
|
||||||
|
export default ConnectedPluginSwitch;
|
||||||
@ -2,8 +2,17 @@ import { connect } from 'react-redux';
|
|||||||
import ToolbarRow from './ToolbarRow';
|
import ToolbarRow from './ToolbarRow';
|
||||||
import { setLeftSidebarOpen, setRightSidebarOpen } from '../redux/actions.js';
|
import { setLeftSidebarOpen, setRightSidebarOpen } from '../redux/actions.js';
|
||||||
|
|
||||||
|
const defaultPlugin = 'cornerstone';
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
|
const { layout, viewportSpecificData, activeViewportIndex } = state.viewports;
|
||||||
|
const pluginInLayout = layout.viewports[activeViewportIndex] && layout.viewports[activeViewportIndex].plugin;
|
||||||
|
const pluginInViewportData = viewportSpecificData[activeViewportIndex] && viewportSpecificData[activeViewportIndex].plugin;
|
||||||
|
const pluginInActiveViewport = pluginInLayout || pluginInViewportData || defaultPlugin;
|
||||||
|
// const extensionData = state.extensions[pluginInActiveViewport];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
pluginId: pluginInActiveViewport,
|
||||||
leftSidebarOpen: state.ui.leftSidebarOpen,
|
leftSidebarOpen: state.ui.leftSidebarOpen,
|
||||||
rightSidebarOpen: state.ui.rightSidebarOpen
|
rightSidebarOpen: state.ui.rightSidebarOpen
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Dropdown } from 'react-viewerbase';
|
||||||
|
|
||||||
|
class PluginSwitch extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
options: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="PluginSwitch">
|
||||||
|
{this.props.options && <Dropdown title={"View"} list={this.props.options}/>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PluginSwitch;
|
||||||
@ -1,23 +1,20 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import ConnectedToolbarSection from './ConnectedToolbarSection';
|
|
||||||
import ConnectedLayoutButton from './ConnectedLayoutButton';
|
|
||||||
import ConnectedCineDialog from './ConnectedCineDialog.js';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ToolbarButton, RoundedButtonGroup } from 'react-viewerbase';
|
import OHIF from 'ohif-core';
|
||||||
|
import { RoundedButtonGroup } from 'react-viewerbase';
|
||||||
|
import ConnectedLayoutButton from './ConnectedLayoutButton';
|
||||||
|
///import ConnectedPluginSwitch from './ConnectedPluginSwitch.js';
|
||||||
import './ToolbarRow.css';
|
import './ToolbarRow.css';
|
||||||
|
|
||||||
const Icons = 'icons.svg';
|
const Icons = 'icons.svg';
|
||||||
|
|
||||||
class ToolbarRow extends Component {
|
class ToolbarRow extends Component {
|
||||||
state = {
|
|
||||||
cineDialogOpen: false
|
|
||||||
};
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
leftSidebarOpen: PropTypes.bool.isRequired,
|
leftSidebarOpen: PropTypes.bool.isRequired,
|
||||||
rightSidebarOpen: PropTypes.bool.isRequired,
|
rightSidebarOpen: PropTypes.bool.isRequired,
|
||||||
setLeftSidebarOpen: PropTypes.func,
|
setLeftSidebarOpen: PropTypes.func,
|
||||||
setRightSidebarOpen: PropTypes.func
|
setRightSidebarOpen: PropTypes.func,
|
||||||
|
pluginId: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -33,12 +30,6 @@ class ToolbarRow extends Component {
|
|||||||
this.props.setRightSidebarOpen(!!value);
|
this.props.setRightSidebarOpen(!!value);
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickCineToolbarButton = () => {
|
|
||||||
this.setState({
|
|
||||||
cineDialogOpen: !this.state.cineDialogOpen
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const leftSidebarToggle = [
|
const leftSidebarToggle = [
|
||||||
{
|
{
|
||||||
@ -68,9 +59,23 @@ class ToolbarRow extends Component {
|
|||||||
? rightSidebarToggle[0].value
|
? rightSidebarToggle[0].value
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const cineDialogContainerStyle = {
|
const currentPluginId = this.props.pluginId;
|
||||||
display: this.state.cineDialogOpen ? 'inline-block' : 'none'
|
|
||||||
};
|
const { PLUGIN_TYPES, availablePlugins } = OHIF.plugins;
|
||||||
|
const plugin = availablePlugins.find(entry => {
|
||||||
|
return (
|
||||||
|
entry.type === PLUGIN_TYPES.TOOLBAR &&
|
||||||
|
entry.id === currentPluginId
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let pluginComp;
|
||||||
|
if (plugin) {
|
||||||
|
const PluginComponent = plugin.component;
|
||||||
|
|
||||||
|
pluginComp = <PluginComponent/>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ToolbarRow">
|
<div className="ToolbarRow">
|
||||||
@ -81,17 +86,9 @@ class ToolbarRow extends Component {
|
|||||||
onValueChanged={this.onLeftSidebarValueChanged}
|
onValueChanged={this.onLeftSidebarValueChanged}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ConnectedToolbarSection />
|
{ pluginComp }
|
||||||
<ConnectedLayoutButton />
|
<ConnectedLayoutButton />
|
||||||
<ToolbarButton
|
{/*<ConnectedPluginSwitch/>*/}
|
||||||
active={this.state.cineDialogOpen}
|
|
||||||
onClick={this.onClickCineToolbarButton}
|
|
||||||
text={'CINE'}
|
|
||||||
iconClasses={'fab fa-youtube'}
|
|
||||||
/>
|
|
||||||
<div className="CineDialogContainer" style={cineDialogContainerStyle}>
|
|
||||||
<ConnectedCineDialog />
|
|
||||||
</div>
|
|
||||||
<div className="pull-right m-t-1 rm-x-1" style={{ marginLeft: 'auto' }}>
|
<div className="pull-right m-t-1 rm-x-1" style={{ marginLeft: 'auto' }}>
|
||||||
<RoundedButtonGroup
|
<RoundedButtonGroup
|
||||||
options={rightSidebarToggle}
|
options={rightSidebarToggle}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export default '6f8b9ae5932e23a1b2031ad173d9a87121e9eae8';
|
export default '416ecb659362a0ebf5449109186c55511421cc33';
|
||||||
|
|||||||
@ -7811,10 +7811,10 @@ octal@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/octal/-/octal-1.0.0.tgz#63e7162a68efbeb9e213588d58e989d1e5c4530b"
|
resolved "https://registry.yarnpkg.com/octal/-/octal-1.0.0.tgz#63e7162a68efbeb9e213588d58e989d1e5c4530b"
|
||||||
integrity sha1-Y+cWKmjvvrniE1iNWOmJ0eXEUws=
|
integrity sha1-Y+cWKmjvvrniE1iNWOmJ0eXEUws=
|
||||||
|
|
||||||
ohif-core@^0.3.3:
|
ohif-core@^0.3.4:
|
||||||
version "0.3.3"
|
version "0.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/ohif-core/-/ohif-core-0.3.3.tgz#6067b31dfdd7c91541aa4d5cf1ad617038147640"
|
resolved "https://registry.yarnpkg.com/ohif-core/-/ohif-core-0.3.4.tgz#0dbed1f7edbd1cd9a826157fba6937171633fb7c"
|
||||||
integrity sha512-uE1EzMrSE+HZIvCBysEvnIwZfb3M5HTLnDGh9NEurBmTOYjD0NIHVoMimjNbxINoNQUBUpOUdJbXAuUk2YOuZg==
|
integrity sha512-qK0fnQ6Yh7cYcQQN6D3csYGtRxVNxJOyT6yxmgQIdAEoK87oPmmApZL8jxMySPrGgF5RqPFqplPTrxrKh82tOw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.2.0"
|
"@babel/runtime" "^7.2.0"
|
||||||
dicomweb-client "^0.4.2"
|
dicomweb-client "^0.4.2"
|
||||||
@ -7825,15 +7825,15 @@ ohif-core@^0.3.3:
|
|||||||
lodash.merge "^4.6.1"
|
lodash.merge "^4.6.1"
|
||||||
validate.js "^0.12.0"
|
validate.js "^0.12.0"
|
||||||
|
|
||||||
ohif-cornerstone-extension@0.0.17:
|
ohif-cornerstone-extension@^0.0.20:
|
||||||
version "0.0.17"
|
version "0.0.20"
|
||||||
resolved "https://registry.yarnpkg.com/ohif-cornerstone-extension/-/ohif-cornerstone-extension-0.0.17.tgz#58c182d3227d328c5a17966b5e7c40b513920704"
|
resolved "https://registry.yarnpkg.com/ohif-cornerstone-extension/-/ohif-cornerstone-extension-0.0.20.tgz#831da61160338ba30b09d6454876d3d7b318445b"
|
||||||
integrity sha512-tT6rbirsCyMDgYPzJXjNhk7zT9KN/mJaKPfp3TVcNIgN1EAARQROU/5shaLUa6DA8M3QDQyKVIVKu+39i6ijVg==
|
integrity sha512-m/qmBFcV3vJ6+ma0UHXHqMN0Nz1Zw9I47T6zgnvz7ZwxJ3h8aQfUjVPGtRcuB2snna4c4NmEHaxoEGRR0bFdIg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.2.0"
|
"@babel/runtime" "^7.2.0"
|
||||||
classnames "^2.2.6"
|
classnames "^2.2.6"
|
||||||
lodash.throttle "^4.1.1"
|
lodash.throttle "^4.1.1"
|
||||||
react-cornerstone-viewport "^0.1.16"
|
react-cornerstone-viewport "^0.1.20"
|
||||||
|
|
||||||
ohif-dicom-html-extension@^0.0.2:
|
ohif-dicom-html-extension@^0.0.2:
|
||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
@ -7851,10 +7851,10 @@ ohif-dicom-microscopy-extension@^0.0.5:
|
|||||||
classnames "^2.2.6"
|
classnames "^2.2.6"
|
||||||
dicom-microscopy-viewer "^0.2.0"
|
dicom-microscopy-viewer "^0.2.0"
|
||||||
|
|
||||||
ohif-dicom-pdf-extension@^0.0.5:
|
ohif-dicom-pdf-extension@^0.0.6:
|
||||||
version "0.0.5"
|
version "0.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/ohif-dicom-pdf-extension/-/ohif-dicom-pdf-extension-0.0.5.tgz#8d2b453aa9d1df736f5c54818f7ee682f60f4c32"
|
resolved "https://registry.yarnpkg.com/ohif-dicom-pdf-extension/-/ohif-dicom-pdf-extension-0.0.6.tgz#5c1c1bf955d160dda01c36c4ed899d8e65384d63"
|
||||||
integrity sha512-YlMgh25hJ+p9e/Uzgg0Wx3deutUKaPd1t/PtL8gIHD+3/k3hgmTsz8nYsQ7xKGSXGpl56d/r9PrRpKF9n8nLSw==
|
integrity sha512-MRBDnC78itsos3c8QMKjgaFp8tmXyGIq5qVLREr//osqCYirhWQbCFJv73eYR5+bRCdJfUMMpvnDSChFIhcT6A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.2.0"
|
"@babel/runtime" "^7.2.0"
|
||||||
classnames "^2.2.6"
|
classnames "^2.2.6"
|
||||||
@ -9440,10 +9440,10 @@ react-bootstrap-modal@^4.2.0:
|
|||||||
react-overlays "^0.8.0"
|
react-overlays "^0.8.0"
|
||||||
react-transition-group "^2.0.0"
|
react-transition-group "^2.0.0"
|
||||||
|
|
||||||
react-cornerstone-viewport@^0.1.16:
|
react-cornerstone-viewport@^0.1.20:
|
||||||
version "0.1.16"
|
version "0.1.20"
|
||||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.16.tgz#b1db13a3160ee10ffa9bfd91a6a0247f008170e2"
|
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.20.tgz#90e369a48e3f47dd5da69d42f0c8ee7e87e81543"
|
||||||
integrity sha512-hMEWoA3oDuurJ0AWZDH/hw1jPD7yY3EbaguE0CFusXdHsclCa7GjZXZb9EPqiAw8bF8vBIty7s96dwkqSFSLdw==
|
integrity sha512-SbaSjCAVFpQoUUXZ6d5F5QwKrP66zRJ4mN7JXPGyiL6+/m0jGkaBVci6pftkth66Lu5HRlCZUS8nh0plONPUtA==
|
||||||
dependencies:
|
dependencies:
|
||||||
lodash.debounce "^4.0.8"
|
lodash.debounce "^4.0.8"
|
||||||
moment "^2.23.0"
|
moment "^2.23.0"
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 3773fd4899eb8faf24a128f6a4a43f6e6e5762ee
|
Subproject commit 05f58a4be2d7f90671d71a2c5cf96a2f08bb219d
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit 6294f3c78f085b7501136964e194cc82e995b15d
|
Subproject commit 3fe82ecec15dc3e1843a00b0d88da8f3f7e161c4
|
||||||
1
Packages-react/react-vtkjs-viewport
Submodule
1
Packages-react/react-vtkjs-viewport
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 8d1a0b11e5e565f779f12082d24ca8f9daa0b051
|
||||||
Loading…
Reference in New Issue
Block a user