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 { toolType } from './definitions';
|
||||||
import createNewMeasurement from './createNewMeasurement';
|
import createNewMeasurement from './createNewMeasurement';
|
||||||
import mouseMoveCallback from './mouseMoveCallback';
|
import mouseMoveCallback from './mouseMoveCallback';
|
||||||
import mouseDownCallback from './mouseDownCallback';
|
import mouseDownCallback from './mouseDownCallback';
|
||||||
|
import doubleClickCallback from './doubleClickCallback';
|
||||||
|
import updatePerpendicularLineHandles from './updatePerpendicularLineHandles';
|
||||||
|
|
||||||
export default function(mouseEventData) {
|
export default function(mouseEventData) {
|
||||||
const element = mouseEventData.element;
|
const { element } = mouseEventData;
|
||||||
const $element = $(element);
|
const $element = $(element);
|
||||||
|
|
||||||
// LT-29 Disable Target Measurements when pixel spacing is not available
|
// LT-29 Disable Target Measurements when pixel spacing is not available
|
||||||
@ -21,9 +23,7 @@ export default function(mouseEventData) {
|
|||||||
const measurementData = createNewMeasurement(mouseEventData);
|
const measurementData = createNewMeasurement(mouseEventData);
|
||||||
measurementData.viewport = cornerstone.getViewport(element);
|
measurementData.viewport = cornerstone.getViewport(element);
|
||||||
|
|
||||||
const eventData = {
|
const eventData = { mouseButtonMask: mouseEventData.which };
|
||||||
mouseButtonMask: mouseEventData.which
|
|
||||||
};
|
|
||||||
|
|
||||||
const tool = cornerstoneTools[toolType];
|
const tool = cornerstoneTools[toolType];
|
||||||
const config = tool.getConfiguration();
|
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
|
// associate this data with this imageId so we can render it and manipulate it
|
||||||
cornerstoneTools.addToolState(element, toolType, measurementData);
|
cornerstoneTools.addToolState(element, toolType, measurementData);
|
||||||
|
|
||||||
// since we are dragging to another place to drop the end point, we can just activate
|
const disableDefaultHandlers = () => {
|
||||||
// the end point and let the moveHandle move it for us.
|
// since we are dragging to another place to drop the end point, we can just activate
|
||||||
$element.off('CornerstoneToolsMouseMove', mouseMoveCallback);
|
// the end point and let the moveHandle move it for us.
|
||||||
$element.off('CornerstoneToolsMouseDown', mouseDownCallback);
|
$element.off('CornerstoneToolsMouseMove', mouseMoveCallback);
|
||||||
$element.off('CornerstoneToolsMouseDownActivate', mouseDownActivateCallback);
|
$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;
|
let cancelled = false;
|
||||||
const cancelAction = () => {
|
const cancelAction = () => {
|
||||||
@ -59,6 +69,17 @@ export default function(mouseEventData) {
|
|||||||
// Bind a one-time event listener for the Esc key
|
// Bind a one-time event listener for the Esc key
|
||||||
$element.one('keydown', keyDownHandler);
|
$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
|
// Keep the current image and create a handler for new rendered images
|
||||||
const currentImage = cornerstone.getImage(element);
|
const currentImage = cornerstone.getImage(element);
|
||||||
const currentViewport = cornerstone.getViewport(element);
|
const currentViewport = cornerstone.getViewport(element);
|
||||||
@ -103,6 +124,9 @@ export default function(mouseEventData) {
|
|||||||
// Unbind the Esc keydown hook
|
// Unbind the Esc keydown hook
|
||||||
$element.off('keydown', keyDownHandler);
|
$element.off('keydown', keyDownHandler);
|
||||||
|
|
||||||
|
// Unbind the mouse down hook
|
||||||
|
$element.off('mousedown', mousedownHandler);
|
||||||
|
|
||||||
// Unbind the event listener for image rendering
|
// Unbind the event listener for image rendering
|
||||||
$element.off('CornerstoneImageRendered', imageRenderedHandler);
|
$element.off('CornerstoneImageRendered', imageRenderedHandler);
|
||||||
|
|
||||||
@ -113,9 +137,17 @@ export default function(mouseEventData) {
|
|||||||
// perpendicular line is not connected to long-line
|
// perpendicular line is not connected to long-line
|
||||||
perpendicularStart.locked = false;
|
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('CornerstoneToolsMouseMove', eventData, mouseMoveCallback);
|
||||||
$element.on('CornerstoneToolsMouseDown', eventData, mouseDownCallback);
|
$element.on('CornerstoneToolsMouseDown', eventData, mouseDownCallback);
|
||||||
$element.on('CornerstoneToolsMouseDownActivate', eventData, mouseDownActivateCallback);
|
$element.on('CornerstoneToolsMouseDownActivate', eventData, mouseDownActivateCallback);
|
||||||
|
$element.on('CornerstoneToolsMouseDoubleClick', eventData, doubleClickCallback);
|
||||||
|
|
||||||
cornerstone.updateImage(element);
|
cornerstone.updateImage(element);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||||
import { toolType } from './definitions';
|
import { toolType } from './definitions';
|
||||||
import createNewMeasurement from './createNewMeasurement';
|
import createNewMeasurement from './createNewMeasurement';
|
||||||
|
import updatePerpendicularLineHandles from './updatePerpendicularLineHandles';
|
||||||
|
|
||||||
export default function(touchEventData) {
|
export default function(touchEventData) {
|
||||||
const element = { touchEventData };
|
const element = { touchEventData };
|
||||||
@ -28,6 +29,11 @@ export default function(touchEventData) {
|
|||||||
$element.off('CornerstoneToolsTap', tapCallback);
|
$element.off('CornerstoneToolsTap', tapCallback);
|
||||||
$element.off('CornerstoneToolsDragStartActive', touchDownActivateCallback);
|
$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);
|
cornerstone.updateImage(element);
|
||||||
const { end, perpendicularStart } = handles;
|
const { end, perpendicularStart } = handles;
|
||||||
cornerstoneTools.moveNewHandleTouch(touchEventData, toolType, measurementData, end, () => {
|
cornerstoneTools.moveNewHandleTouch(touchEventData, toolType, measurementData, end, () => {
|
||||||
@ -42,6 +48,10 @@ export default function(touchEventData) {
|
|||||||
// perpendicular line is not connected to long-line
|
// perpendicular line is not connected to long-line
|
||||||
perpendicularStart.locked = false;
|
perpendicularStart.locked = false;
|
||||||
|
|
||||||
|
// Unbind the handlers to update perpendicular line
|
||||||
|
$element.off('CornerstoneToolsTouchDrag', updateHandler);
|
||||||
|
$element.off('CornerstoneToolsTouchEnd', updateHandler);
|
||||||
|
|
||||||
$element.on('CornerstoneToolsTouchDrag', touchMoveHandle);
|
$element.on('CornerstoneToolsTouchDrag', touchMoveHandle);
|
||||||
$element.on('CornerstoneToolsTap', tapCallback);
|
$element.on('CornerstoneToolsTap', tapCallback);
|
||||||
$element.on('CornerstoneToolsDragStartActive', touchDownActivateCallback);
|
$element.on('CornerstoneToolsDragStartActive', touchDownActivateCallback);
|
||||||
|
|||||||
@ -25,7 +25,8 @@ export default function(mouseEventData) {
|
|||||||
end: getHandle(x, y, 1, { active: true }),
|
end: getHandle(x, y, 1, { active: true }),
|
||||||
perpendicularStart: getHandle(x, y, 2, { locked: true }),
|
perpendicularStart: getHandle(x, y, 2, { locked: true }),
|
||||||
perpendicularEnd: getHandle(x, y, 3),
|
perpendicularEnd: getHandle(x, y, 3),
|
||||||
textBox: getHandle(x - 50, y - 70, 4, {
|
textBox: getHandle(x - 50, y - 70, null, {
|
||||||
|
highlight: false,
|
||||||
movesIndependently: false,
|
movesIndependently: false,
|
||||||
drawnIndependently: true,
|
drawnIndependently: true,
|
||||||
allowedOutsideImage: 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 { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||||
import { toolType, distanceThreshold } from './definitions';
|
import { toolType, distanceThreshold } from './definitions';
|
||||||
import mouseMoveCallback from './mouseMoveCallback';
|
import mouseMoveCallback from './mouseMoveCallback';
|
||||||
@ -98,7 +100,7 @@ export default function(event, eventData) {
|
|||||||
|
|
||||||
unselectAllHandles(data.handles);
|
unselectAllHandles(data.handles);
|
||||||
handle.moving = true;
|
handle.moving = true;
|
||||||
moveHandle(eventData, toolType, data, handle, handleDoneMove);
|
moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle));
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
/* jshint -W083 */
|
||||||
|
|
||||||
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
||||||
import { toolType } from './definitions';
|
import { toolType } from './definitions';
|
||||||
import pointNearTool from './pointNearTool';
|
import pointNearTool from './pointNearTool';
|
||||||
|
|||||||
@ -1,48 +1,11 @@
|
|||||||
import { cornerstone } from 'meteor/ohif:cornerstone';
|
import { cornerstone } from 'meteor/ohif:cornerstone';
|
||||||
|
|
||||||
// draw perpendicular line
|
// draw perpendicular line
|
||||||
export default function(context, eventData, element, data, color, lineWidth) {
|
export default function(context, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw perpendicular line
|
// Draw perpendicular line
|
||||||
const perpendicularStartCanvas = cornerstone.pixelToCanvas(element, data.handles.perpendicularStart);
|
const { perpendicularStart, perpendicularEnd } = data.handles;
|
||||||
const perpendicularEndCanvas = cornerstone.pixelToCanvas(element, data.handles.perpendicularEnd);
|
const perpendicularStartCanvas = cornerstone.pixelToCanvas(element, perpendicularStart);
|
||||||
|
const perpendicularEndCanvas = cornerstone.pixelToCanvas(element, perpendicularEnd);
|
||||||
|
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.strokeStyle = color;
|
context.strokeStyle = color;
|
||||||
@ -50,5 +13,4 @@ export default function(context, eventData, element, data, color, lineWidth) {
|
|||||||
context.moveTo(perpendicularStartCanvas.x, perpendicularStartCanvas.y);
|
context.moveTo(perpendicularStartCanvas.x, perpendicularStartCanvas.y);
|
||||||
context.lineTo(perpendicularEndCanvas.x, perpendicularEndCanvas.y);
|
context.lineTo(perpendicularEndCanvas.x, perpendicularEndCanvas.y);
|
||||||
context.stroke();
|
context.stroke();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { cornerstone, cornerstoneMath, cornerstoneTools } from 'meteor/ohif:corn
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
import { toolType } from '../definitions';
|
import { toolType } from '../definitions';
|
||||||
import drawHandles from './drawHandles';
|
import drawHandles from './drawHandles';
|
||||||
|
import updatePerpendicularLineHandles from '../updatePerpendicularLineHandles';
|
||||||
import drawPerpendicularLine from './drawPerpendicularLine';
|
import drawPerpendicularLine from './drawPerpendicularLine';
|
||||||
import drawSelectedMarker from './drawSelectedMarker';
|
import drawSelectedMarker from './drawSelectedMarker';
|
||||||
|
|
||||||
@ -59,7 +60,8 @@ export default function(event, eventData) {
|
|||||||
context.stroke();
|
context.stroke();
|
||||||
|
|
||||||
// Draw perpendicular line
|
// Draw perpendicular line
|
||||||
drawPerpendicularLine(context, eventData, element, data, color, strokeWidth);
|
updatePerpendicularLineHandles(eventData, data);
|
||||||
|
drawPerpendicularLine(context, element, data, color, strokeWidth);
|
||||||
|
|
||||||
// Draw the handles
|
// Draw the handles
|
||||||
const handlesColor = color;
|
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