Fixing issues with bidirectional tool
This commit is contained in:
parent
0acdff0bc5
commit
475580b2f9
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,13 @@
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
import { cornerstone, cornerstoneTools, cornerstoneMath } from 'meteor/ohif:cornerstone';
|
||||
import { toolType } from './definitions';
|
||||
import createNewMeasurement from './createNewMeasurement';
|
||||
import mouseMoveCallback from './mouseMoveCallback';
|
||||
import mouseDownCallback from './mouseDownCallback';
|
||||
import doubleClickCallback from './doubleClickCallback';
|
||||
import updatePerpendicularLineHandles from './updatePerpendicularLineHandles';
|
||||
|
||||
export default function(mouseEventData) {
|
||||
const element = mouseEventData.element;
|
||||
const { element } = mouseEventData;
|
||||
const $element = $(element);
|
||||
|
||||
// LT-29 Disable Target Measurements when pixel spacing is not available
|
||||
@ -21,9 +23,7 @@ export default function(mouseEventData) {
|
||||
const measurementData = createNewMeasurement(mouseEventData);
|
||||
measurementData.viewport = cornerstone.getViewport(element);
|
||||
|
||||
const eventData = {
|
||||
mouseButtonMask: mouseEventData.which
|
||||
};
|
||||
const eventData = { mouseButtonMask: mouseEventData.which };
|
||||
|
||||
const tool = cornerstoneTools[toolType];
|
||||
const config = tool.getConfiguration();
|
||||
@ -32,11 +32,21 @@ export default function(mouseEventData) {
|
||||
// associate this data with this imageId so we can render it and manipulate it
|
||||
cornerstoneTools.addToolState(element, toolType, measurementData);
|
||||
|
||||
// since we are dragging to another place to drop the end point, we can just activate
|
||||
// the end point and let the moveHandle move it for us.
|
||||
$element.off('CornerstoneToolsMouseMove', mouseMoveCallback);
|
||||
$element.off('CornerstoneToolsMouseDown', mouseDownCallback);
|
||||
$element.off('CornerstoneToolsMouseDownActivate', mouseDownActivateCallback);
|
||||
const disableDefaultHandlers = () => {
|
||||
// since we are dragging to another place to drop the end point, we can just activate
|
||||
// the end point and let the moveHandle move it for us.
|
||||
$element.off('CornerstoneToolsMouseMove', mouseMoveCallback);
|
||||
$element.off('CornerstoneToolsMouseDown', mouseDownCallback);
|
||||
$element.off('CornerstoneToolsMouseDownActivate', mouseDownActivateCallback);
|
||||
$element.off('CornerstoneToolsMouseDoubleClick', doubleClickCallback);
|
||||
};
|
||||
|
||||
disableDefaultHandlers();
|
||||
|
||||
// Update the perpendicular line handles position
|
||||
const updateHandler = (event, eventData) => updatePerpendicularLineHandles(eventData, measurementData);
|
||||
$element.on('CornerstoneToolsMouseDrag', updateHandler);
|
||||
$element.on('CornerstoneToolsMouseUp', updateHandler);
|
||||
|
||||
let cancelled = false;
|
||||
const cancelAction = () => {
|
||||
@ -59,6 +69,17 @@ export default function(mouseEventData) {
|
||||
// Bind a one-time event listener for the Esc key
|
||||
$element.one('keydown', keyDownHandler);
|
||||
|
||||
// Bind a mousedown handler to cancel the measurement if it's zero-sized
|
||||
const mousedownHandler = () => {
|
||||
const { start, end } = measurementData.handles;
|
||||
if (!cornerstoneMath.point.distance(start, end)) {
|
||||
cancelAction();
|
||||
}
|
||||
};
|
||||
|
||||
// Bind a one-time event listener for mouse down
|
||||
$element.one('mousedown', mousedownHandler);
|
||||
|
||||
// Keep the current image and create a handler for new rendered images
|
||||
const currentImage = cornerstone.getImage(element);
|
||||
const currentViewport = cornerstone.getViewport(element);
|
||||
@ -103,6 +124,9 @@ export default function(mouseEventData) {
|
||||
// Unbind the Esc keydown hook
|
||||
$element.off('keydown', keyDownHandler);
|
||||
|
||||
// Unbind the mouse down hook
|
||||
$element.off('mousedown', mousedownHandler);
|
||||
|
||||
// Unbind the event listener for image rendering
|
||||
$element.off('CornerstoneImageRendered', imageRenderedHandler);
|
||||
|
||||
@ -113,9 +137,17 @@ export default function(mouseEventData) {
|
||||
// perpendicular line is not connected to long-line
|
||||
perpendicularStart.locked = false;
|
||||
|
||||
// Unbind the handlers to update perpendicular line
|
||||
$element.off('CornerstoneToolsMouseDrag', updateHandler);
|
||||
$element.off('CornerstoneToolsMouseUp', updateHandler);
|
||||
|
||||
// Disable the default handlers and re-enable again
|
||||
disableDefaultHandlers();
|
||||
$element.on('CornerstoneToolsMouseMove', eventData, mouseMoveCallback);
|
||||
$element.on('CornerstoneToolsMouseDown', eventData, mouseDownCallback);
|
||||
$element.on('CornerstoneToolsMouseDownActivate', eventData, mouseDownActivateCallback);
|
||||
$element.on('CornerstoneToolsMouseDoubleClick', eventData, doubleClickCallback);
|
||||
|
||||
cornerstone.updateImage(element);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
import { toolType } from './definitions';
|
||||
import createNewMeasurement from './createNewMeasurement';
|
||||
import updatePerpendicularLineHandles from './updatePerpendicularLineHandles';
|
||||
|
||||
export default function(touchEventData) {
|
||||
const element = { touchEventData };
|
||||
@ -28,6 +29,11 @@ export default function(touchEventData) {
|
||||
$element.off('CornerstoneToolsTap', tapCallback);
|
||||
$element.off('CornerstoneToolsDragStartActive', touchDownActivateCallback);
|
||||
|
||||
// Update the perpendicular line handles position
|
||||
const updateHandler = (event, eventData) => updatePerpendicularLineHandles(eventData, measurementData);
|
||||
$element.on('CornerstoneToolsTouchDrag', updateHandler);
|
||||
$element.on('CornerstoneToolsTouchEnd', updateHandler);
|
||||
|
||||
cornerstone.updateImage(element);
|
||||
const { end, perpendicularStart } = handles;
|
||||
cornerstoneTools.moveNewHandleTouch(touchEventData, toolType, measurementData, end, () => {
|
||||
@ -42,6 +48,10 @@ export default function(touchEventData) {
|
||||
// perpendicular line is not connected to long-line
|
||||
perpendicularStart.locked = false;
|
||||
|
||||
// Unbind the handlers to update perpendicular line
|
||||
$element.off('CornerstoneToolsTouchDrag', updateHandler);
|
||||
$element.off('CornerstoneToolsTouchEnd', updateHandler);
|
||||
|
||||
$element.on('CornerstoneToolsTouchDrag', touchMoveHandle);
|
||||
$element.on('CornerstoneToolsTap', tapCallback);
|
||||
$element.on('CornerstoneToolsDragStartActive', touchDownActivateCallback);
|
||||
|
||||
@ -25,7 +25,8 @@ export default function(mouseEventData) {
|
||||
end: getHandle(x, y, 1, { active: true }),
|
||||
perpendicularStart: getHandle(x, y, 2, { locked: true }),
|
||||
perpendicularEnd: getHandle(x, y, 3),
|
||||
textBox: getHandle(x - 50, y - 70, 4, {
|
||||
textBox: getHandle(x - 50, y - 70, null, {
|
||||
highlight: false,
|
||||
movesIndependently: false,
|
||||
drawnIndependently: true,
|
||||
allowedOutsideImage: true,
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
import { toolType } from './definitions';
|
||||
import pointNearTool from './pointNearTool';
|
||||
|
||||
export default function (event, eventData) {
|
||||
const { element } = eventData.element;
|
||||
|
||||
function doneCallback(data, deleteTool) {
|
||||
if (deleteTool === true) {
|
||||
cornerstoneTools.removeToolState(element, toolType, data);
|
||||
cornerstone.updateImage(element);
|
||||
}
|
||||
}
|
||||
|
||||
const buttonMask = event.data && event.data.mouseButtonMask;
|
||||
if (buttonMask && !cornerstoneTools.isMouseButtonEnabled(eventData.which, buttonMask)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const config = cornerstoneTools.bidirectional.getConfiguration();
|
||||
|
||||
const coords = eventData.currentPoints.canvas;
|
||||
const toolData = cornerstoneTools.getToolState(element, toolType);
|
||||
|
||||
// now check to see if there is a handle we can move
|
||||
if (!toolData) return;
|
||||
|
||||
let data;
|
||||
for (let i = 0; i < toolData.data.length; i++) {
|
||||
data = toolData.data[i];
|
||||
if (pointNearTool(element, data, coords)) {
|
||||
data.active = true;
|
||||
cornerstone.updateImage(element);
|
||||
// Allow relabelling via a callback
|
||||
config.changeMeasurementLocationCallback(data, eventData, doneCallback);
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
/* jshint -W083 */
|
||||
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
import { toolType, distanceThreshold } from './definitions';
|
||||
import mouseMoveCallback from './mouseMoveCallback';
|
||||
@ -98,7 +100,7 @@ export default function(event, eventData) {
|
||||
|
||||
unselectAllHandles(data.handles);
|
||||
handle.moving = true;
|
||||
moveHandle(eventData, toolType, data, handle, handleDoneMove);
|
||||
moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle));
|
||||
event.stopImmediatePropagation();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
/* jshint -W083 */
|
||||
|
||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||
import { toolType } from './definitions';
|
||||
import pointNearTool from './pointNearTool';
|
||||
|
||||
@ -1,48 +1,11 @@
|
||||
import { cornerstone } from 'meteor/ohif:cornerstone';
|
||||
|
||||
// draw perpendicular line
|
||||
export default function(context, eventData, element, data, color, lineWidth) {
|
||||
let startX, startY, endX, endY;
|
||||
|
||||
if (data.handles.start.x === data.handles.end.x &&
|
||||
data.handles.start.y === data.handles.end.y) {
|
||||
startX = data.handles.start.x;
|
||||
startY = data.handles.start.y;
|
||||
endX = data.handles.end.x;
|
||||
endY = data.handles.end.y;
|
||||
} else {
|
||||
// mid point of long-axis line
|
||||
const mid = {
|
||||
x: (data.handles.start.x + data.handles.end.x) / 2,
|
||||
y: (data.handles.start.y + data.handles.end.y) / 2
|
||||
};
|
||||
|
||||
// Length of long-axis
|
||||
const dx = (data.handles.start.x - data.handles.end.x) * (eventData.image.columnPixelSpacing || 1);
|
||||
const dy = (data.handles.start.y - data.handles.end.y) * (eventData.image.rowPixelSpacing || 1);
|
||||
const length = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
const vectorX = (data.handles.start.x - data.handles.end.x) / length;
|
||||
const vectorY = (data.handles.start.y - data.handles.end.y) / length;
|
||||
|
||||
const perpendicularLineLength = length / 2;
|
||||
|
||||
startX = mid.x + (perpendicularLineLength / 2) * vectorY;
|
||||
startY = mid.y - (perpendicularLineLength / 2) * vectorX;
|
||||
endX = mid.x - (perpendicularLineLength / 2) * vectorY;
|
||||
endY = mid.y + (perpendicularLineLength / 2) * vectorX;
|
||||
}
|
||||
|
||||
if (data.handles.perpendicularStart.locked) {
|
||||
data.handles.perpendicularStart.x = startX;
|
||||
data.handles.perpendicularStart.y = startY;
|
||||
data.handles.perpendicularEnd.x = endX;
|
||||
data.handles.perpendicularEnd.y = endY;
|
||||
}
|
||||
|
||||
export default function(context, element, data, color, lineWidth) {
|
||||
// Draw perpendicular line
|
||||
const perpendicularStartCanvas = cornerstone.pixelToCanvas(element, data.handles.perpendicularStart);
|
||||
const perpendicularEndCanvas = cornerstone.pixelToCanvas(element, data.handles.perpendicularEnd);
|
||||
const { perpendicularStart, perpendicularEnd } = data.handles;
|
||||
const perpendicularStartCanvas = cornerstone.pixelToCanvas(element, perpendicularStart);
|
||||
const perpendicularEndCanvas = cornerstone.pixelToCanvas(element, perpendicularEnd);
|
||||
|
||||
context.beginPath();
|
||||
context.strokeStyle = color;
|
||||
@ -50,5 +13,4 @@ export default function(context, eventData, element, data, color, lineWidth) {
|
||||
context.moveTo(perpendicularStartCanvas.x, perpendicularStartCanvas.y);
|
||||
context.lineTo(perpendicularEndCanvas.x, perpendicularEndCanvas.y);
|
||||
context.stroke();
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { cornerstone, cornerstoneMath, cornerstoneTools } from 'meteor/ohif:corn
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { toolType } from '../definitions';
|
||||
import drawHandles from './drawHandles';
|
||||
import updatePerpendicularLineHandles from '../updatePerpendicularLineHandles';
|
||||
import drawPerpendicularLine from './drawPerpendicularLine';
|
||||
import drawSelectedMarker from './drawSelectedMarker';
|
||||
|
||||
@ -59,7 +60,8 @@ export default function(event, eventData) {
|
||||
context.stroke();
|
||||
|
||||
// Draw perpendicular line
|
||||
drawPerpendicularLine(context, eventData, element, data, color, strokeWidth);
|
||||
updatePerpendicularLineHandles(eventData, data);
|
||||
drawPerpendicularLine(context, element, data, color, strokeWidth);
|
||||
|
||||
// Draw the handles
|
||||
const handlesColor = color;
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
// Update the perpendicular line handles
|
||||
export default function(eventData, data) {
|
||||
if (!data.handles.perpendicularStart.locked) return;
|
||||
|
||||
let startX, startY, endX, endY;
|
||||
|
||||
const { start, end } = data.handles;
|
||||
if (start.x === end.x && start.y === end.y) {
|
||||
startX = start.x;
|
||||
startY = start.y;
|
||||
endX = end.x;
|
||||
endY = end.y;
|
||||
} else {
|
||||
// mid point of long-axis line
|
||||
const mid = {
|
||||
x: (start.x + end.x) / 2,
|
||||
y: (start.y + end.y) / 2
|
||||
};
|
||||
|
||||
// Length of long-axis
|
||||
const dx = (start.x - end.x) * (eventData.image.columnPixelSpacing || 1);
|
||||
const dy = (start.y - end.y) * (eventData.image.rowPixelSpacing || 1);
|
||||
const length = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
const vectorX = (start.x - end.x) / length;
|
||||
const vectorY = (start.y - end.y) / length;
|
||||
|
||||
const perpendicularLineLength = length / 2;
|
||||
|
||||
startX = mid.x + (perpendicularLineLength / 2) * vectorY;
|
||||
startY = mid.y - (perpendicularLineLength / 2) * vectorX;
|
||||
endX = mid.x - (perpendicularLineLength / 2) * vectorY;
|
||||
endY = mid.y + (perpendicularLineLength / 2) * vectorX;
|
||||
}
|
||||
|
||||
data.handles.perpendicularStart.x = startX;
|
||||
data.handles.perpendicularStart.y = startY;
|
||||
data.handles.perpendicularEnd.x = endX;
|
||||
data.handles.perpendicularEnd.y = endY;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user