Adapting Viewers to the new cornerstone structure

This commit is contained in:
Bruno Alves de Faria 2018-02-15 14:46:36 -02:00
parent 99b88f08b3
commit dc767e5c83
19 changed files with 82 additions and 70 deletions

View File

@ -227,8 +227,8 @@ Template.viewer.onCreated(() => {
firstMeasurementActivated = true;
});
instance.measurementModifiedHandler = _.throttle((event, instance, eventData) => {
OHIF.measurements.MeasurementHandlers.onModified(event, instance, eventData);
instance.measurementModifiedHandler = _.throttle((event, instance) => {
OHIF.measurements.MeasurementHandlers.onModified(event, instance);
}, 300);
});
@ -363,16 +363,16 @@ Template.viewer.helpers({
});
Template.viewer.events({
'CornerstoneToolsMeasurementAdded .imageViewerViewport'(event, instance, eventData) {
OHIF.measurements.MeasurementHandlers.onAdded(event, instance, eventData);
'CornerstoneToolsMeasurementAdded .imageViewerViewport'(event, instance) {
OHIF.measurements.MeasurementHandlers.onAdded(event, instance);
},
'CornerstoneToolsMeasurementModified .imageViewerViewport'(event, instance, eventData) {
instance.measurementModifiedHandler(event, instance, eventData);
'CornerstoneToolsMeasurementModified .imageViewerViewport'(event, instance) {
instance.measurementModifiedHandler(event, instance);
},
'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance, eventData) {
OHIF.measurements.MeasurementHandlers.onRemoved(event, instance, eventData);
'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance) {
OHIF.measurements.MeasurementHandlers.onRemoved(event, instance);
}
});

View File

@ -44,7 +44,7 @@ export default function(mouseEventData) {
disableDefaultHandlers();
// Update the perpendicular line handles position
const updateHandler = (event, eventData) => updatePerpendicularLineHandles(eventData, measurementData);
const updateHandler = event => updatePerpendicularLineHandles(event.detail, measurementData);
$element.on('CornerstoneToolsMouseDrag', updateHandler);
$element.on('CornerstoneToolsMouseUp', updateHandler);
@ -95,7 +95,7 @@ export default function(mouseEventData) {
};
// Bind the event listener for image rendering
$element.on('CornerstoneImageRendered', imageRenderedHandler);
$element.on('cornerstoneimagerendered', imageRenderedHandler);
// Bind the tool deactivation and enlargement handlers
$element.on('CornerstoneToolsToolDeactivated', cancelAction);
@ -128,7 +128,7 @@ export default function(mouseEventData) {
$element.off('mousedown', mousedownHandler);
// Unbind the event listener for image rendering
$element.off('CornerstoneImageRendered', imageRenderedHandler);
$element.off('cornerstoneimagerendered', imageRenderedHandler);
// Unbind the tool deactivation and enlargement handlers
$element.off('CornerstoneToolsToolDeactivated', cancelAction);

View File

@ -30,7 +30,7 @@ export default function(touchEventData) {
$element.off('CornerstoneToolsDragStartActive', touchDownActivateCallback);
// Update the perpendicular line handles position
const updateHandler = (event, eventData) => updatePerpendicularLineHandles(eventData, measurementData);
const updateHandler = event => updatePerpendicularLineHandles(event.detail, measurementData);
$element.on('CornerstoneToolsTouchDrag', updateHandler);
$element.on('CornerstoneToolsTouchEnd', updateHandler);

View File

@ -2,7 +2,8 @@ import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
import { toolType } from './definitions';
import pointNearTool from './pointNearTool';
export default function (event, eventData) {
export default function (event) {
const eventData = event.detail;
const { element } = eventData.element;
function doneCallback(data, deleteTool) {

View File

@ -38,10 +38,12 @@ const setHandlesMovingState = (handles, state) => {
};
// mouseDowCallback is used to restrict behaviour of perpendicular-line
export default function(event, eventData) {
export default function(event) {
const eventData = event.detail;
let data;
const element = eventData.element;
const $element = $(element);
const options = cornerstoneTools.getToolOptions(toolType, element);
// Add an event listener to clear the selected state when a measurement is activated
const activateEventKey = 'ViewerMeasurementsActivated';
@ -75,7 +77,7 @@ export default function(event, eventData) {
$element.on('CornerstoneToolsMouseMove', eventData, mouseMoveCallback);
}
if (cornerstoneTools.isMouseButtonEnabled(eventData.which, event.data.mouseButtonMask)) {
if (cornerstoneTools.isMouseButtonEnabled(eventData.which, options.mouseButtonMask)) {
const coords = eventData.startPoints.canvas;
const toolData = cornerstoneTools.getToolState(event.currentTarget, toolType);

View File

@ -24,7 +24,8 @@ const handleActivator = (element, handles, canvasPoint, distanceThreshold=6) =>
};
// mouseMoveCallback is used to hide handles when mouse is away
export default function (event, eventData) {
export default function (event) {
const eventData = event.detail;
cornerstoneTools.toolCoordinates.setCoords(eventData);
// if a mouse button is down, do nothing
if (eventData.which !== 0) {

View File

@ -9,7 +9,8 @@ export default function (mouseEventData, toolType, data, handle, doneMovingCallb
y: handle.y - mouseEventData.currentPoints.image.y
};
const mouseDragCallback = (event, eventData) => {
const mouseDragCallback = event => {
const eventData = event.detail;
handle.active = true;
if (handle.index === undefined || handle.index === null) {
@ -51,13 +52,13 @@ export default function (mouseEventData, toolType, data, handle, doneMovingCallb
};
// Bind the event listener for image rendering
$element.on('CornerstoneImageRendered', imageRenderedHandler);
$element.on('cornerstoneimagerendered', imageRenderedHandler);
const mouseUpCallback = () => {
$element.off('CornerstoneToolsMouseDrag', mouseDragCallback);
$element.off('CornerstoneToolsMouseUp', mouseUpCallback);
$element.off('CornerstoneToolsMouseClick', mouseUpCallback);
$element.off('CornerstoneImageRendered', imageRenderedHandler);
$element.off('cornerstoneimagerendered', imageRenderedHandler);
cornerstone.updateImage(element);
if (typeof doneMovingCallback === 'function') {

View File

@ -6,7 +6,8 @@ import updatePerpendicularLineHandles from '../updatePerpendicularLineHandles';
import drawPerpendicularLine from './drawPerpendicularLine';
import drawSelectedMarker from './drawSelectedMarker';
export default function(event, eventData) {
export default function(event) {
const eventData = event.detail;
const { element, canvasContext } = eventData;
// if we have no toolData for this element, return immediately as there is nothing to do

View File

@ -78,7 +78,8 @@ function getNearbyToolData(element, coords) {
return pointNearTool ? nearbyTool : undefined;
}
function keyDownCallback(event, eventData) {
function keyDownCallback(event) {
const eventData = event.detail;
const keyCode = eventData.which;
// Stop here if the locked flag is set to true

View File

@ -142,7 +142,7 @@ function addNewMeasurement(mouseEventData) {
};
// Bind the event listener for image rendering
$element.on('CornerstoneImageRendered', imageRenderedHandler);
$element.on('cornerstoneimagerendered', imageRenderedHandler);
// Bind the tool deactivation and enlargement handlers
$element.on('CornerstoneToolsToolDeactivated', cancelAction);
@ -165,7 +165,7 @@ function addNewMeasurement(mouseEventData) {
$element.off('mousedown', mousedownHandler);
// Unbind the event listener for image rendering
$element.off('CornerstoneImageRendered', imageRenderedHandler);
$element.off('cornerstoneimagerendered', imageRenderedHandler);
// Unbind the tool deactivation and enlargement handlers
$element.off('CornerstoneToolsToolDeactivated', cancelAction);
@ -252,7 +252,8 @@ function pointNearTool(element, data, coords) {
}
///////// BEGIN IMAGE RENDERING ///////
function onImageRendered(e, eventData) {
function onImageRendered(e) {
const eventData = e.detail;
var element = eventData.element;
// if we have no toolData for this element, return immediately as there is nothing to do
@ -399,7 +400,8 @@ function addNewMeasurementTouch(touchEventData) {
});
}
function doubleClickCallback(e, eventData) {
function doubleClickCallback(e) {
const eventData = e.detail;
var element = eventData.element;
var data;

View File

@ -116,7 +116,7 @@ function createQualitativeTargetTool(toolType, responseText='') {
};
// Bind the event listener for image rendering
$element.on('CornerstoneImageRendered', imageRenderedHandler);
$element.on('cornerstoneimagerendered', imageRenderedHandler);
// Bind the tool deactivation and enlargement handlers
$element.on('CornerstoneToolsToolDeactivated', cancelAction);
@ -139,7 +139,7 @@ function createQualitativeTargetTool(toolType, responseText='') {
$element.off('mousedown', mousedownHandler);
// Unbind the event listener for image rendering
$element.off('CornerstoneImageRendered', imageRenderedHandler);
$element.off('cornerstoneimagerendered', imageRenderedHandler);
// Unbind the tool deactivation and enlargement handlers
$element.off('CornerstoneToolsToolDeactivated', cancelAction);
@ -261,7 +261,8 @@ function createQualitativeTargetTool(toolType, responseText='') {
}
///////// BEGIN IMAGE RENDERING ///////
function onImageRendered(e, eventData) {
function onImageRendered(e) {
const eventData = e.detail;
var element = eventData.element;
// if we have no toolData for this element, return immediately as there is nothing to do
@ -416,7 +417,8 @@ function createQualitativeTargetTool(toolType, responseText='') {
});
}
function doubleClickCallback(e, eventData) {
function doubleClickCallback(e) {
const eventData = e.detail;
var element = eventData.element;
var data;

View File

@ -144,7 +144,8 @@ function computeScaleBounds(eventData, canvasSize, imageSize, horizontalReductio
};
}
function onImageRendered(e, eventData) {
function onImageRendered(e) {
const eventData = e.detail;
// Check whether pixel spacing is defined
if (!eventData.image.rowPixelSpacing || !eventData.image.columnPixelSpacing) {
@ -219,7 +220,7 @@ function onImageRendered(e, eventData) {
function disable(element) {
// TODO: displayTool does not have cornerstone.updateImage(element) method to hide tool
$(element).off('CornerstoneImageRendered', onImageRendered);
$(element).off('cornerstoneimagerendered', onImageRendered);
cornerstone.updateImage(element);
}

View File

@ -14,7 +14,8 @@ const MeasurementHandlers = {
handleSingleMeasurementRemoved,
handleChildMeasurementRemoved,
onAdded(event, instance, eventData) {
onAdded(event, instance) {
const eventData = event.detail;
const { toolType } = eventData;
const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType);
const params = {
@ -34,7 +35,8 @@ const MeasurementHandlers = {
}
},
onModified(event, instance, eventData) {
onModified(event, instance) {
const eventData = event.detail;
const { toolType } = eventData;
const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType);
const params = {
@ -54,7 +56,8 @@ const MeasurementHandlers = {
}
},
onRemoved(e, instance, eventData) {
onRemoved(e, instance) {
const eventData = event.detail;
const { toolType } = eventData;
const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType);
const params = {

View File

@ -66,7 +66,7 @@ OHIF.measurements.getImageDataUrl = ({
};
// Wait for image rendering to get its data URL
$(element).one('CornerstoneImageRendered', () => {
$(element).one('cornerstoneimagerendered', () => {
if (measurement && alwaysVisibleText) {
rearrangeTextBox(image, measurement, element).then(() => renderedCallback());
} else {
@ -143,7 +143,7 @@ const rearrangeTextBox = (image, measurement, element) => new Promise((resolve,
textBox.boundingBox.top = intersection.y - y0;
Object.assign(textBox, intersection);
cornerstone.updateImage(element);
$(element).one('CornerstoneImageRendered', () => resolve());
$(element).one('cornerstoneimagerendered', () => resolve());
} else {
resolve();
}

View File

@ -11,7 +11,7 @@ function renderIntoViewport(measurementData, enabledElement, viewportIndex) {
return new Promise((resolve, reject) => {
const renderedCallback = element => {
activateMeasurements(element, measurementData);
$(element).one('CornerstoneImageRendered', () => resolve());
$(element).one('cornerstoneimagerendered', () => resolve());
};
// Find the study by studyInstanceUid and render the display set

View File

@ -79,9 +79,10 @@ Template.imageDownloadDialog.onRendered(() => {
};
instance.updateViewportPreview = () => {
instance.$viewportElement.one('CornerstoneImageRendered', (event, enabledElement) => {
instance.$viewportElement.one('cornerstoneimagerendered', event => {
// Wait for the tools to handle CornerstoneImageRendered event
Tracker.afterFlush(() => {
const enabledElement = cornerstone.getEnabledElement(event.currentTarget);
const formData = instance.form.value();
const image = instance.viewportPreview;
const type = 'image/' + formData.type;

View File

@ -1,6 +1,6 @@
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { OHIF } from 'meteor/ohif:core';
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
import { toolManager } from '../../../lib/toolManager';
const toolTypes = ['length', 'simpleAngle', 'probe', 'ellipticalRoi', 'rectangleRoi', 'arrowAnnotate'];
@ -14,33 +14,31 @@ const TypeToLabelMap = {
};
let dropdownItems = [{
actionType: 'Delete',
action: ({nearbyToolData, eventData}) => {
const element = eventData.element
action: ({ nearbyToolData, eventData }) => {
const element = eventData.element;
cornerstoneTools.removeToolState(element, nearbyToolData.toolType, nearbyToolData.tool);
cornerstone.updateImage(element);
}
}];
let timer = 0;
const getTypeText = function(toolData, actionType) {
const toolType = toolData.toolType;
let message = `${TypeToLabelMap[toolType]}`;
if (toolType === 'arrowAnnotate') {
message = `${message} "${toolData.tool.text}"`
message = `${message} "${toolData.tool.text}"`;
}
return `${actionType} ${message}`;
};
const createDropdown = function (event, eventData, isTouchEvent = false) {
const createDropdown = function(event, isTouchEvent = false) {
const eventData = event.detail;
const nearbyToolData = toolManager.getNearbyToolData(eventData.element, eventData.currentPoints.canvas, toolTypes);
// Annotate tools for touch events already have a press handle to edit it, has a better UX for deleting it
if (isTouchEvent && nearbyToolData.toolType === 'arrowAnnotate') {
return;
}
if (isTouchEvent && nearbyToolData.toolType === 'arrowAnnotate') return;
if (nearbyToolData) {
dropdownItems.forEach(function(item) {
@ -59,13 +57,13 @@ const createDropdown = function (event, eventData, isTouchEvent = false) {
};
Template.viewerMain.events({
'CornerstoneToolsMouseClick .imageViewerViewport'(event, instance, eventData) {
'CornerstoneToolsMouseClick .imageViewerViewport'(event, instance) {
if (event.which === 3) {
createDropdown(event, eventData);
createDropdown(event);
}
},
'CornerstoneToolsTouchPress .imageViewerViewport'(event, instance, eventData) {
createDropdown(event, eventData, true);
'CornerstoneToolsTouchPress .imageViewerViewport'(event, instance) {
createDropdown(event, true);
}
});
});

View File

@ -130,9 +130,7 @@ export class StackImagePositionOffsetSynchronizer {
}
elementDisabledHandler(context) {
return (e, eventData) => {
context.removeViewportByElement(eventData.element);
};
return e => context.removeViewportByElement(e.detail.element);
}
getViewportByIndexes(viewportIndexes) {

View File

@ -1,6 +1,7 @@
import { $ } from 'meteor/jquery';
import { Session } from 'meteor/session';
import { OHIF } from 'meteor/ohif:core';
import { cornerstone, cornerstoneWADOImageLoader } from 'meteor/ohif:cornerstone';
class BaseLoadingListener {
constructor(stack, options) {
@ -127,7 +128,8 @@ class DICOMFileLoadingListener extends BaseLoadingListener {
$(cornerstone.events).off(imageLoadProgressEventName);
}
_imageLoadProgressEventHandle(e, eventData) {
_imageLoadProgressEventHandle(e) {
const eventData = e.detail;
const dataSetUrl = this._convertImageIdToDataSetUrl(eventData.imageId);
const bytesDiff = eventData.loaded - this._lastLoaded;
@ -204,9 +206,9 @@ class StackLoadingListener extends BaseLoadingListener {
_createArray(length, defaultValue) {
// `new Array(length)` is an anti-pattern in javascript because its
// funny API. Otherwise I would go for `new Array(length).fill(false)`
const array = new Array();
const array = [];
for(let i = 0; i < length; i++) {
for (let i = 0; i < length; i++) {
array[i] = defaultValue;
}
@ -214,7 +216,7 @@ class StackLoadingListener extends BaseLoadingListener {
}
_checkCachedData() {
const imageIds = this.stack.imageIds;
// const imageIds = this.stack.imageIds;
// TODO: No way to check status of Promise.
/*for(let i = 0; i < imageIds.length; i++) {
@ -264,7 +266,7 @@ class StackLoadingListener extends BaseLoadingListener {
}
// Add one more frame to the stats
if(loaded) {
if (loaded) {
this._addStatsData(1);
}
@ -274,14 +276,12 @@ class StackLoadingListener extends BaseLoadingListener {
this._updateProgress();
}
_imageLoadedEventHandle(e, eventData) {
const imageId = eventData.image.imageId;
this._updateFrameStatus(imageId, true);
_imageLoadedEventHandle(e) {
this._updateFrameStatus(e.detail.image.imageId, true);
}
_imageCachePromiseRemovedEventHandle(e, eventData) {
const imageId = eventData.imageId;
this._updateFrameStatus(imageId, false);
_imageCachePromiseRemovedEventHandle(e) {
this._updateFrameStatus(e.detail.imageId, false);
}
_updateProgress() {
@ -307,13 +307,13 @@ class StackLoadingListener extends BaseLoadingListener {
const displaySetInstanceUid = this.stack.displaySetInstanceUid;
let progressBar = '[';
for(let i = 0; i < totalFramesCount; i++) {
for (let i = 0; i < totalFramesCount; i++) {
const ch = this.framesStatus[i] ? '|' : '.';
progressBar += `${ch}`;
}
progressBar += ']';
console.log(`${displaySetInstanceUid}: ${progressBar}`);
OHIF.log.info(`${displaySetInstanceUid}: ${progressBar}`);
}
}
@ -326,7 +326,7 @@ class StudyLoadingListener {
const displaySetInstanceUid = stack.displaySetInstanceUid;
if (!this.listeners[displaySetInstanceUid]) {
listener = this._createListener(stack, stackMetaData);
const listener = this._createListener(stack, stackMetaData);
if (listener) {
this.listeners[displaySetInstanceUid] = listener;
}
@ -389,7 +389,7 @@ class StudyLoadingListener {
// Singleton
static getInstance() {
if(!StudyLoadingListener._instance) {
if (!StudyLoadingListener._instance) {
StudyLoadingListener._instance = new StudyLoadingListener();
}