Fixing issues with bidirectional tool and measure flow

This commit is contained in:
Bruno Alves de Faria 2018-02-20 06:53:25 -03:00
parent 797b2f5588
commit 00a76a6ca5
10 changed files with 85 additions and 75 deletions

View File

@ -19,7 +19,7 @@ Meteor.startup(() => {
OHIF.viewer.stackImagePositionOffsetSynchronizer = new OHIF.viewerbase.StackImagePositionOffsetSynchronizer(); OHIF.viewer.stackImagePositionOffsetSynchronizer = new OHIF.viewerbase.StackImagePositionOffsetSynchronizer();
// Create the synchronizer used to update reference lines // Create the synchronizer used to update reference lines
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('CornerstoneNewImage', cornerstoneTools.updateImageSynchronizer); OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider; OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider;
@ -373,7 +373,7 @@ Template.viewer.events({
instance.measurementModifiedHandler(originalEvent, instance); instance.measurementModifiedHandler(originalEvent, instance);
}, },
'cornerstonetoolsmeasurementremoved .imageViewerViewport'(event, instance) { 'cornerstonemeasurementremoved .imageViewerViewport'(event, instance) {
const originalEvent = event.originalEvent; const originalEvent = event.originalEvent;
OHIF.measurements.MeasurementHandlers.onRemoved(originalEvent, instance); OHIF.measurements.MeasurementHandlers.onRemoved(originalEvent, instance);
} }

View File

@ -67,7 +67,7 @@ Meteor.startup(() => {
OHIF.viewer.stackImagePositionOffsetSynchronizer = new OHIF.viewerbase.StackImagePositionOffsetSynchronizer(); OHIF.viewer.stackImagePositionOffsetSynchronizer = new OHIF.viewerbase.StackImagePositionOffsetSynchronizer();
// Create the synchronizer used to update reference lines // Create the synchronizer used to update reference lines
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('CornerstoneNewImage', cornerstoneTools.updateImageSynchronizer); OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider; OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider;

View File

@ -21,7 +21,7 @@ const unselectAllHandles = handles => {
// Clear the bidirectional tool's selection for all tool handles // Clear the bidirectional tool's selection for all tool handles
const clearBidirectionalSelection = event => { const clearBidirectionalSelection = event => {
let imageNeedsUpdate = false; let imageNeedsUpdate = false;
const toolData = cornerstoneTools.getToolState(event.currentTarget, 'bidirectional'); const toolData = cornerstoneTools.getToolState(event.target, 'bidirectional');
if (!toolData) return; if (!toolData) return;
toolData.data.forEach(data => { toolData.data.forEach(data => {
const unselectResult = unselectAllHandles(data.handles); const unselectResult = unselectAllHandles(data.handles);
@ -37,7 +37,7 @@ const setHandlesMovingState = (handles, state) => {
}); });
}; };
// mouseDowCallback is used to restrict behaviour of perpendicular-line // mouseDownCallback is used to restrict behaviour of perpendicular-line
export default function(event) { export default function(event) {
const eventData = event.detail; const eventData = event.detail;
let data; let data;
@ -45,6 +45,8 @@ export default function(event) {
const $element = $(element); const $element = $(element);
const options = cornerstoneTools.getToolOptions(toolType, element); const options = cornerstoneTools.getToolOptions(toolType, element);
if (!cornerstoneTools.isMouseButtonEnabled(eventData.which, options.mouseButtonMask)) return;
// Add an event listener to clear the selected state when a measurement is activated // Add an event listener to clear the selected state when a measurement is activated
const activateEventKey = 'ViewerMeasurementsActivated'; const activateEventKey = 'ViewerMeasurementsActivated';
$element.off(activateEventKey).on(activateEventKey, () => clearBidirectionalSelection(event)); $element.off(activateEventKey).on(activateEventKey, () => clearBidirectionalSelection(event));
@ -74,72 +76,71 @@ export default function(event) {
} }
cornerstone.updateImage(element); cornerstone.updateImage(element);
element.removeEventListener('cornerstonetoolsmousemove', mouseMoveCallback); element.addEventListener('cornerstonetoolsmousemove', mouseMoveCallback);
} }
if (cornerstoneTools.isMouseButtonEnabled(eventData.which, options.mouseButtonMask)) { const coords = eventData.startPoints.canvas;
const coords = eventData.startPoints.canvas; const toolData = cornerstoneTools.getToolState(event.currentTarget, toolType);
const toolData = cornerstoneTools.getToolState(event.currentTarget, toolType);
// now check to see if there is a handle we can move if (!toolData) return;
if (toolData) {
for (let i = 0; i < toolData.data.length; i++) {
data = toolData.data[i];
const handle = cornerstoneTools.getHandleNearImagePoint(
element,
data.handles,
coords,
distanceThreshold
);
if (handle) { // now check to see if there is a handle we can move
// Hide the cursor to improve precision while resizing the line or set to move for (let i = 0; i < toolData.data.length; i++) {
// if dragging text box data = toolData.data[i];
$element.css('cursor', handle.hasBoundingBox ? 'move' : 'none'); const handleParams = [element, data.handles, coords, distanceThreshold];
const handle = cornerstoneTools.getHandleNearImagePoint(...handleParams);
element.removeEventListener('cornerstonetoolsmousemove', mouseMoveCallback); if (handle) {
data.active = true; // Hide the cursor to improve precision while resizing the line or set to move
// if dragging text box
$element.css('cursor', handle.hasBoundingBox ? 'move' : 'none');
unselectAllHandles(data.handles); element.removeEventListener('cornerstonetoolsmousemove', mouseMoveCallback);
handle.moving = true; data.active = true;
moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle));
event.stopImmediatePropagation(); unselectAllHandles(data.handles);
return false; handle.moving = true;
} moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle));
} event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
return;
} }
}
// Now check to see if there is a line we can move // Now check to see if there is a line we can move
// Now check to see if we have a tool that we can move // Now check to see if we have a tool that we can move
if (toolData) { const opt = {
const options = { deleteIfHandleOutsideImage: true,
deleteIfHandleOutsideImage: true, preventHandleOutsideImage: false
preventHandleOutsideImage: false };
};
const getDoneMovingCallback = handles => () => { const getDoneMovingCallback = handles => () => {
setHandlesMovingState(handles, false); setHandlesMovingState(handles, false);
handleDoneMove(); handleDoneMove();
}; };
for (let i = 0; i < toolData.data.length; i++) { for (let i = 0; i < toolData.data.length; i++) {
data = toolData.data[i]; data = toolData.data[i];
if (pointNearTool(element, data, coords)) { if (pointNearTool(element, data, coords)) {
// Set the cursor to move // Set the cursor to move
$element.css('cursor', 'move'); $element.css('cursor', 'move');
element.removeEventListener('cornerstonetoolsmousemove', mouseMoveCallback); element.removeEventListener('cornerstonetoolsmousemove', mouseMoveCallback);
data.active = true; data.active = true;
unselectAllHandles(data.handles); unselectAllHandles(data.handles);
setHandlesMovingState(data.handles, true); setHandlesMovingState(data.handles, true);
const doneMovingCallback = getDoneMovingCallback(data.handles); const doneMovingCallback = getDoneMovingCallback(data.handles);
cornerstoneTools.moveAllHandles(event, data, toolData, toolType, options, doneMovingCallback); const allHandlesParams = [event, data, toolData, toolType, opt, doneMovingCallback];
event.stopImmediatePropagation(); cornerstoneTools.moveAllHandles(...allHandlesParams);
return false; event.stopImmediatePropagation();
} event.stopPropagation();
} event.preventDefault();
return;
} }
} }
} }

View File

@ -6,7 +6,8 @@ import pointNearTool from './pointNearTool';
// Replaces the cornerstoneTools.handleActivator function by skiping the active handle comparison // Replaces the cornerstoneTools.handleActivator function by skiping the active handle comparison
const handleActivator = (element, handles, canvasPoint, distanceThreshold=6) => { const handleActivator = (element, handles, canvasPoint, distanceThreshold=6) => {
const nearbyHandle = cornerstoneTools.getHandleNearImagePoint(element, handles, canvasPoint, distanceThreshold); const getHandle = cornerstoneTools.getHandleNearImagePoint;
const nearbyHandle = getHandle(element, handles, canvasPoint, distanceThreshold);
let handleActivatorChanged = false; let handleActivatorChanged = false;
Object.keys(handles).forEach(handleKey => { Object.keys(handles).forEach(handleKey => {
@ -26,6 +27,7 @@ const handleActivator = (element, handles, canvasPoint, distanceThreshold=6) =>
// mouseMoveCallback is used to hide handles when mouse is away // mouseMoveCallback is used to hide handles when mouse is away
export default function (event) { export default function (event) {
const eventData = event.detail; const eventData = event.detail;
const { element } = eventData;
cornerstoneTools.toolCoordinates.setCoords(eventData); cornerstoneTools.toolCoordinates.setCoords(eventData);
// if a mouse button is down, do nothing // if a mouse button is down, do nothing
if (eventData.which !== 0) { if (eventData.which !== 0) {
@ -33,7 +35,7 @@ export default function (event) {
} }
// if we have no tool data for this element, do nothing // if we have no tool data for this element, do nothing
const toolData = cornerstoneTools.getToolState(eventData.element, toolType); const toolData = cornerstoneTools.getToolState(element, toolType);
if (!toolData) return; if (!toolData) return;
// We have tool data, search through all data and see if we can activate a handle // We have tool data, search through all data and see if we can activate a handle
@ -43,7 +45,7 @@ export default function (event) {
const coords = eventData.currentPoints.canvas; const coords = eventData.currentPoints.canvas;
const data = toolData.data[i]; const data = toolData.data[i];
const handleActivatorChanged = handleActivator(eventData.element, data.handles, coords); const handleActivatorChanged = handleActivator(element, data.handles, coords);
Object.keys(data.handles).forEach(handleKey => { Object.keys(data.handles).forEach(handleKey => {
if (handleKey === 'textBox') return; if (handleKey === 'textBox') return;
const handle = data.handles[handleKey]; const handle = data.handles[handleKey];
@ -54,7 +56,9 @@ export default function (event) {
imageNeedsUpdate = true; imageNeedsUpdate = true;
} }
if ((pointNearTool(eventData.element, data, coords) && !data.active) || (!pointNearTool(eventData.element, data, coords) && data.active)) { const nearToolAndInactive = pointNearTool(element, data, coords) && !data.active;
const notNearToolAndActive = !pointNearTool(element, data, coords) && data.active;
if (nearToolAndInactive || notNearToolAndActive) {
data.active = !data.active; data.active = !data.active;
imageNeedsUpdate = true; imageNeedsUpdate = true;
} }
@ -62,6 +66,6 @@ export default function (event) {
// Handle activation status changed, redraw the image // Handle activation status changed, redraw the image
if (imageNeedsUpdate === true) { if (imageNeedsUpdate === true) {
cornerstone.updateImage(eventData.element); cornerstone.updateImage(element);
} }
} }

View File

@ -3,7 +3,6 @@ import setHandlesPosition from './setHandlesPosition';
export default function (mouseEventData, toolType, data, handle, doneMovingCallback, preventHandleOutsideImage) { export default function (mouseEventData, toolType, data, handle, doneMovingCallback, preventHandleOutsideImage) {
const element = mouseEventData.element; const element = mouseEventData.element;
const $element = $(element);
const distanceFromTool = { const distanceFromTool = {
x: handle.x - mouseEventData.currentPoints.image.x, x: handle.x - mouseEventData.currentPoints.image.x,
y: handle.y - mouseEventData.currentPoints.image.y y: handle.y - mouseEventData.currentPoints.image.y
@ -32,11 +31,12 @@ export default function (mouseEventData, toolType, data, handle, doneMovingCallb
const eventType = 'cornerstonetoolsmeasurementmodified'; const eventType = 'cornerstonetoolsmeasurementmodified';
const modifiedEventData = { const modifiedEventData = {
toolType: toolType, toolType,
element: element, element,
measurementData: data measurementData: data
}; };
$element.trigger(eventType, modifiedEventData);
cornerstone.triggerEvent(element, eventType, modifiedEventData);
}; };
element.addEventListener('cornerstonetoolsmousedrag', mouseDragCallback); element.addEventListener('cornerstonetoolsmousedrag', mouseDragCallback);

View File

@ -106,8 +106,9 @@ export class MeasurementsLengthCriterion extends BaseCriterion {
let { longestDiameter, shortestDiameter } = measurement; let { longestDiameter, shortestDiameter } = measurement;
if (measurement.childToolsCount) { if (measurement.childToolsCount) {
longestDiameter = measurement.bidirectional.longestDiameter; const child = measurement.bidirectional;
shortestDiameter = measurement.bidirectional.shortestDiameter; longestDiameter = (child && child.longestDiameter) || 0;
shortestDiameter = (child && child.shortestDiameter) || 0;
} }
const { sliceThickness } = metadata; const { sliceThickness } = metadata;

View File

@ -8,7 +8,7 @@ export class StackImagePositionOffsetSynchronizer {
constructor() { constructor() {
this.active = false; this.active = false;
this.syncedViewports = []; this.syncedViewports = [];
this.synchronizer = new cornerstoneTools.Synchronizer('CornerstoneNewImage', cornerstoneTools.stackImagePositionOffsetSynchronizer); this.synchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.stackImagePositionOffsetSynchronizer);
} }
static get ELEMENT_DISABLED_EVENT() { static get ELEMENT_DISABLED_EVENT() {

View File

@ -3,6 +3,7 @@ import { Session } from 'meteor/session';
import { Random } from 'meteor/random'; import { Random } from 'meteor/random';
import { $ } from 'meteor/jquery'; import { $ } from 'meteor/jquery';
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
import { getFrameOfReferenceUID } from './getFrameOfReferenceUID'; import { getFrameOfReferenceUID } from './getFrameOfReferenceUID';
import { updateCrosshairsSynchronizer } from './updateCrosshairsSynchronizer'; import { updateCrosshairsSynchronizer } from './updateCrosshairsSynchronizer';
import { crosshairsSynchronizers } from './crosshairsSynchronizers'; import { crosshairsSynchronizers } from './crosshairsSynchronizers';
@ -344,18 +345,21 @@ export const toolManager = {
if (button === 'left') { if (button === 'left') {
newToolIdLeft = toolId; newToolIdLeft = toolId;
} }
const newCornerstoneToolLeft = tools[newToolIdLeft]; // left mouse tool is used for touch as well const newCornerstoneToolLeft = tools[newToolIdLeft]; // left mouse tool is used for touch as well
let newToolIdMiddle = activeTool.middle; let newToolIdMiddle = activeTool.middle;
if (button === 'middle') { if (button === 'middle') {
newToolIdMiddle = toolId; newToolIdMiddle = toolId;
} }
const newCornerstoneToolMiddle = cornerstoneTools[newToolIdMiddle]; const newCornerstoneToolMiddle = cornerstoneTools[newToolIdMiddle];
let newToolIdRight = activeTool.right; let newToolIdRight = activeTool.right;
if (button === 'right') { if (button === 'right') {
newToolIdRight = toolId; newToolIdRight = toolId;
} }
const newCornerstoneToolRight = cornerstoneTools[newToolIdRight]; const newCornerstoneToolRight = cornerstoneTools[newToolIdRight];
// Deactivate scroll wheel tools // Deactivate scroll wheel tools

View File

@ -21,7 +21,7 @@ import { crosshairsSynchronizers } from './crosshairsSynchronizers';
synchronizer.destroy(); synchronizer.destroy();
} else { } else {
// Create a new synchronizer // Create a new synchronizer
crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID] = new cornerstoneTools.Synchronizer("CornerstoneNewImage", cornerstoneTools.updateImageSynchronizer); crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID] = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
synchronizer = crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID]; synchronizer = crosshairsSynchronizers.synchronizers[currentFrameOfReferenceUID];
} }

View File

@ -12,7 +12,7 @@ Template.standaloneViewerMain.onCreated(() => {
window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler()); window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler());
// Create the synchronizer used to update reference lines // Create the synchronizer used to update reference lines
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('CornerstoneNewImage', cornerstoneTools.updateImageSynchronizer); OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider; OHIF.viewer.metadataProvider = OHIF.cornerstone.metadataProvider;
// Metadata configuration // Metadata configuration