wip on react transition 4

This commit is contained in:
Erik Ziegler 2018-11-30 16:12:04 -05:00
parent 895fb01a02
commit 5568490819
22 changed files with 70 additions and 287 deletions

View File

@ -1,15 +1,5 @@
import { Viewerbase } from 'meteor/ohif:viewerbase';
Template.flexboxLayout.events({
'transitionend .sidebarMenu'(event) {
if (!event.target.classList.contains('sidebarMenu')) {
return;
}
window.ResizeViewportManager.handleResize();
}
});
Template.flexboxLayout.helpers({
leftSidebarOpen() {
return Template.instance().data.state.get('leftSidebar');

View File

@ -1,5 +0,0 @@
.CornerstoneViewport {
width: 100%;
height: 100%;
position: relative; /*Necessary so that the viewportOverlay is on top of the viewports */
}

View File

@ -1,20 +1,21 @@
import { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import cloneDeep from 'lodash.clonedeep';
import debounce from 'lodash.debounce';
//import * as cornerstone from 'cornerstone-core';
//import * as cornerstoneTools from 'cornerstone-tools';
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
//import './lib/initCornerstone.js';
import ImageScrollbar from './ImageScrollbar.js';
import ViewportOverlay from './ViewportOverlay.js';
import ToolContextMenu from './ToolContextMenu.js';
import LoadingIndicator from './LoadingIndicator/LoadingIndicator.js';
import './CornerstoneViewport.css';
import cloneDeep from 'lodash.clonedeep';
import debounce from 'lodash.debounce';
import {StackManager} from "../../lib/StackManager";
import ImageScrollbar from '../ImageScrollbar/ImageScrollbar.js';
import ViewportOverlay from '../ViewportOverlay/ViewportOverlay.js';
import ToolContextMenu from '../ToolContextMenu/ToolContextMenu.js';
import LoadingIndicator from '../LoadingIndicator/LoadingIndicator.js';
import ViewportOrientationMarkers from '../ViewportOrientationMarkers/ViewportOrientationMarkers.js';
import { StackManager } from "../../../lib/StackManager";
import './CornerstoneViewport.styl';
const EVENT_RESIZE = 'resize';
const loadIndicatorDelay = 45;
@ -92,6 +93,13 @@ class CornerstoneViewport extends Component {
//loadHandlerManager.setEndLoadHandler(this.doneLoadingHandler);
this.debouncedResize = debounce(() => {
try {
cornerstone.getEnabledElement(this.element);
} catch (error) {
console.error(error);
return;
}
cornerstone.resize(this.element, true);
this.setState({
@ -117,6 +125,9 @@ class CornerstoneViewport extends Component {
<div
className="CornerstoneViewport viewportElement"
onContextMenu={this.onContextMenu}
tabIndex='0'
unselectable='on'
onSelectStart='return false;'
ref={input => {
this.element = input;
}}
@ -129,6 +140,10 @@ class CornerstoneViewport extends Component {
imageId={this.state.imageId}
numImagesLoaded={this.state.numImagesLoaded}
/>
<ViewportOrientationMarkers/>
</div>
<div className='viewportInstructions'>
Please drag a stack here to view images.
</div>
{this.displayScrollbar && (
<ImageScrollbar
@ -191,8 +206,6 @@ class CornerstoneViewport extends Component {
this.setState({
viewport
});
debugger;
}
onNewImage() {
@ -451,8 +464,8 @@ class CornerstoneViewport extends Component {
isTouchActive: true
});
}
cornerstone.resize(this.element);
this.debouncedResize();
}
setActiveTool = activeTool => {

View File

@ -1,8 +1,9 @@
@import "{ohif:design}/app"
.imageViewerViewport
.CornerstoneViewport
width: 100%
height: 100%
position: relative;
background-color: black
// Prevent the blue outline in Chrome when a viewport is selected
@ -11,7 +12,7 @@
// Prevents the entire page from getting larger
// when the magnify tool is near the sides/corners of the page
overflow: hidden
.viewportInstructions
display: none
font-size: 13px
@ -26,12 +27,12 @@
left: 0
margin: auto
height: 20px
/* These are some good CSS settings for a circular magnifying glass
/* These are some good CSS settings for a circular magnifying glass
Try removing the border-radius to make a square magnifying glass */
.magnifyTool
border: 4px white solid
box-shadow: 2px 2px 10px #1e1e1e
border-radius: 50%
display: none
cursor: none
cursor: none

View File

@ -2,8 +2,7 @@
<div class='imageViewerViewport'
oncontextmenu='return false;'
unselectable='on'
onselectstart='return false;'
tabindex='0'>
onselectstart='return false;'>
</div>
<div class='viewportInstructions'>
Please drag a stack here to view images.

View File

@ -2,7 +2,7 @@ import { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { OHIF } from 'meteor/ohif:core';
import CornerstoneViewport from '../CornerstoneViewport.js';
import CornerstoneViewport from '../CornerstoneViewport/CornerstoneViewport.js';
import './GridLayout.styl';
const TOP_CLASS = 'top';

View File

@ -1,49 +0,0 @@
@value globals: "../GlobalStyles.css";
@value activeColor, imageSliderColor from globals;
.scroll {
position: absolute;
top: 0;
right: 0;
width: 15px;
height: 100%;
z-index: 2;
}
.scroll .scroll-holder {
position: relative;
height: 100%;
}
.scroll > .scroll-holder > .imageSlider {
transform: rotate(90deg);
transform-origin: top left;
position: absolute;
width: 100%; /* Note: This width does not have an effect. */
margin-left: 10px;
-webkit-appearance: none;
background-color: rgba(0, 0, 0, 0);
outline: none;
}
input.imageSlider:focus {
outline: none;
}
input.imageSlider::-moz-focus-outer {
border: none;
}
input.imageSlider::-webkit-slider-thumb {
cursor: -webkit-grab;
background: imageSliderColor;
-webkit-appearance: none;
width: 45px;
height: 20px;
border-radius: 10px;
}
input.imageSlider::-webkit-slider-thumb:active {
background: activeColor;
cursor: -webkit-grabbing;
}

View File

@ -1,13 +1,14 @@
import { Component } from 'react';
import React from 'react';
import './ImageScrollbar.css';
import PropTypes from 'prop-types';
import './ImageScrollbar.styl';
class ImageScrollbar extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
}
render() {
@ -27,6 +28,7 @@ class ImageScrollbar extends Component {
step="1"
value={this.props.value}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
/>
</div>
</div>
@ -37,6 +39,25 @@ class ImageScrollbar extends Component {
const intValue = parseInt(event.target.value, 10);
this.props.onInputCallback(intValue);
}
onKeyDown(event) {
// We don't allow direct keyboard up/down input on the
// image sliders since the natural direction is reversed (0 is at the top)
// Store the KeyCodes in an object for readability
const keys = {
DOWN: 40,
UP: 38
};
if (event.which === keys.DOWN) {
OHIF.commands.run('scrollDown');
event.preventDefault();
} else if (event.which === keys.UP) {
OHIF.commands.run('scrollUp');
event.preventDefault();
}
}
}
ImageScrollbar.propTypes = {

View File

@ -8,14 +8,14 @@ $imageSliderBorder = none
$imageSliderWidth = 12px
$imageSliderHeight = 39px
.imageControls
.scroll
height: 100%
padding: 5px
position: absolute
right: 0
top: 0
.scrollbar
.scroll-holder
height: calc(100% - 20px)
margin-top: 5px
position: relative

View File

@ -1,6 +1,5 @@
import { Component } from 'react';
import React from 'react';
import './ViewportOverlay.css';
/*import * as cornerstone from 'cornerstone-core';
import * as cornerstoneTools from 'cornerstone-tools';*/
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';

View File

@ -1,38 +0,0 @@
.ViewportOverlay {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
z-index: 2;
}
.ViewportOverlay .overlay-element {
position: absolute;
color: lightblue;
text-shadow: 1px 1px black;
}
.ViewportOverlay .overlay-element > span {
display: block;
}
.ViewportOverlay .top-right {
top: 10px;
right: 25px; /* room for scrollbar */
}
.ViewportOverlay .top-left {
top: 10px;
left: 10px;
}
.ViewportOverlay .bottom-right {
bottom: 10px;
right: 30px;
}
.ViewportOverlay .bottom-left {
bottom: 10px;
left: 10px;
}

View File

@ -1,7 +1,7 @@
import { Component } from 'react';
import React from 'react';
import './ViewportOverlay.css';
import PropTypes from 'prop-types';
import './ViewportOverlay.styl';
class ViewportOverlay extends Component {
render() {

View File

@ -8,40 +8,36 @@ $viewportTagPadding = 20px
.imageViewerViewportOverlay
theme('color', '$textSecondaryColor')
.dicomTag
.overlay-element
position: absolute
font-weight: 400
text-shadow: 1px 1px black
pointer-events: none
.topleft
.top-left
top: $viewportTagPadding
left: $viewportTagPadding
.topcenter
.top-center
top: $viewportTagPadding
padding-top: $viewportTagPadding
width: 100%
text-align: center
.topright
.top-right
top: $viewportTagPadding
right: $viewportTagPadding
text-align: right
.bottomleft
.bottom-left
bottom: $viewportTagPadding
left: $viewportTagPadding
.bottomright
.bottom-right
bottom: $viewportTagPadding
right: $viewportTagPadding
text-align: right
.priorIndicator
font-weight: bold
color: yellow
&.controlsVisible
.topright, .bottomright
right: "calc(%s + 19px)" % $viewportTagPadding

View File

@ -242,39 +242,4 @@ Template.viewportOverlay.helpers({
return stack.imageIds.length;
},
prior() {
// This helper is updated whenever a new image is displayed in the viewport
Session.get('CornerstoneNewImage' + this.viewportIndex);
if (!this.imageId) {
return;
}
// @TypeSafeStudies
// Make sure there are more than two studies loaded in the viewer
const viewportStudies = OHIF.viewer.Studies.all();
if (viewportStudies.length < 2) {
return;
}
// Here we sort the collection in ascending order by study date, so
// that we can obtain the oldest study as the first element of the array
//
// TODO= Find out if we should encode studyDate as a Date in the OHIF.viewer.Studies Collection
const viewportStudiesArray = _.sortBy(viewportStudies, function(study) {
return viewportOverlayUtils.formatDateTime(study.studyDate, study.studyTime);
});
// Get study data
const study = cornerstone.metaData.get('study', this.imageId);
if (!study) {
return;
}
const oldestStudy = viewportStudiesArray[0];
if (viewportOverlayUtils.formatDateTime(study.studyDate, study.studyTime) <= viewportOverlayUtils.formatDateTime(oldestStudy.studyDate, oldestStudy.studyTime)) {
return 'Prior';
}
}
});

View File

@ -4,7 +4,6 @@
<div class="topleft dicomTag">
<div>{{formatPN patientName}}</div>
<div>{{patientId}}</div>
<div class='priorIndicator'>{{prior}}</div>
</div>
<div class="topright dicomTag">
<div>{{studyDescription}}</div>
@ -33,7 +32,6 @@
<div class="topright dicomTag">
<div>{{formatPN patientName}}</div>
<div>{{patientId}}</div>
<div class='priorIndicator'>{{prior}}</div>
<div>{{studyDescription}}</div>
<div>{{formatDA studyDate}} {{formatTM studyTime}}</div>
</div>
@ -53,7 +51,6 @@
<div class="topleft dicomTag">
<div>{{formatPN patientName}}</div>
<div>{{patientId}}</div>
<div class='priorIndicator'>{{prior}}</div>
<div>{{studyDescription}}</div>
<div>{{formatDA studyDate}} {{formatTM studyTime}}</div>
</div>

View File

@ -1,7 +0,0 @@
<template name="imageControls">
<div class="imageControls">
<div class="scrollbar">
<input class="imageSlider" type="range" min="1" value="{{imageIndex}}" max="{{numImages}}"/>
</div>
</div>
</template>

View File

@ -1,83 +0,0 @@
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
import { setActiveViewport } from '../../../lib/setActiveViewport';
import { switchToImageByIndex } from '../../../lib/switchToImageByIndex';
import { Component } from 'react';
import React from 'react';
const slideTimeoutTime = 40;
let slideTimeout;
Template.imageControls.onRendered(() => {
const instance = Template.instance();
// Set the current imageSlider width to its parent's height
// (because webkit is stupid and can't style vertical sliders)
const $slider = instance.$('.imageSlider');
const $viewport = $slider.closest('.imageViewerViewportOverlay').siblings('.imageViewerViewport');
instance.handleResize = _.throttle(() => {
const viewportHeight = $viewport.height();
$slider.width(viewportHeight - 20);
}, 150);
instance.handleResize();
$(window).on('resize', instance.handleResize);
});
Template.imageControls.onDestroyed(() => {
const instance = Template.instance();
if (instance.handleResize) {
$(window).off('resize', instance.handleResize);
}
});
Template.imageControls.events({
'rescale .scrollbar'(event, instance) {
instance.handleResize();
},
'keydown input[type=range]'(event) {
// We don't allow direct keyboard up/down input on the
// image sliders since the natural direction is reversed (0 is at the top)
// Store the KeyCodes in an object for readability
const keys = {
DOWN: 40,
UP: 38
};
if (event.which === keys.DOWN) {
OHIF.commands.run('scrollDown');
event.preventDefault();
} else if (event.which === keys.UP) {
OHIF.commands.run('scrollUp');
event.preventDefault();
}
},
'input input[type=range], change input[type=range]'(event) {
// Note that we throttle requests to prevent the
// user's ultrafast scrolling from firing requests too quickly.
clearTimeout(slideTimeout);
slideTimeout = setTimeout(() => {
// Using the slider in an inactive viewport
// should cause that viewport to become active
const $slider = $(event.currentTarget);
const viewportContainer = $slider.parents('.viewportContainer');
setActiveViewport(viewportContainer);
// Subtract 1 here since the slider goes from 1 to N images
// But the stack indexing starts at 0
const newImageIdIndex = parseInt($slider.val(), 10) - 1;
switchToImageByIndex(newImageIdIndex);
}, slideTimeoutTime);
return false;
}
});

View File

@ -1,10 +1,11 @@
import ViewerMain from './ViewerMain/ViewerMain.js';
import GridLayout from './GridLayout/GridLayout.js';
import LoadingIndicator from './LoadingIndicator/LoadingIndicator.js';
import CornerstoneViewport from './CornerstoneViewport.js';
import ImageScrollbar from './ImageScrollbar.js';
import ToolContextMenu from './ToolContextMenu.js';
import ViewportOverlay from './ViewportOverlay.js';
import CornerstoneViewport from './CornerstoneViewport/CornerstoneViewport.js';
import ImageScrollbar from './ImageScrollbar/ImageScrollbar.js';
import ToolContextMenu from './ToolContextMenu/ToolContextMenu.js';
import ViewportOverlay from './ViewportOverlay/ViewportOverlay.js';
import ViewportOrientationMarkers from './ViewportOrientationMarkers/ViewportOrientationMarkers.js';
const viewer = {
ViewerMain,
@ -14,7 +15,6 @@ const viewer = {
ImageScrollbar,
ToolContextMenu,
ViewportOverlay,
test: 'test2'
};
export default viewer;

View File

@ -121,26 +121,10 @@ Package.onUse(function(api) {
api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.styl', 'client');
// Viewer components
api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.html', 'client');
api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.js', 'client');
api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.styl', 'client');
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.html', 'client');
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.js', 'client');
api.addFiles('client/components/viewer/annotationDialogs/annotationDialogs.styl', 'client');
api.addFiles('client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl', 'client');
api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.html', 'client');
api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.js', 'client');
api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.styl', 'client');
api.addFiles('client/components/viewer/toolContextMenu/toolContextMenu.js', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.html', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.js', 'client');
api.addFiles('client/components/viewer/imageControls/imageControls.styl', 'client');
api.addFiles('client/components/viewer/layoutButton/layoutButton.html', 'client');
api.addFiles('client/components/viewer/layoutButton/layoutButton.js', 'client');