PWV-138: Rendering handles and lines based on handles' state

This commit is contained in:
Bruno Alves de Faria 2017-09-12 17:55:30 -03:00
parent e330973c1e
commit 0888e08536

View File

@ -145,9 +145,6 @@ function addNewMeasurement(mouseEventData) {
// Bind a one-time event listener for the Esc key // Bind a one-time event listener for the Esc key
$(element).one('keydown', cancelCallback); $(element).one('keydown', cancelCallback);
// Make handle invisible while moving
measurementData.handles.end.drawnIndependently = true;
cornerstone.updateImage(element); cornerstone.updateImage(element);
cornerstoneTools.moveNewHandle(mouseEventData, toolType, measurementData, measurementData.handles.end, function() { cornerstoneTools.moveNewHandle(mouseEventData, toolType, measurementData, measurementData.handles.end, function() {
@ -165,9 +162,6 @@ function addNewMeasurement(mouseEventData) {
// perpendicular line is not connected to long-line // perpendicular line is not connected to long-line
measurementData.handles.perpendicularStart.locked = false; measurementData.handles.perpendicularStart.locked = false;
// Enable handle visibility again
measurementData.handles.end.drawnIndependently = false;
$(element).on('CornerstoneToolsMouseMove', eventData, mouseMoveCallback); $(element).on('CornerstoneToolsMouseMove', eventData, mouseMoveCallback);
$(element).on('CornerstoneToolsMouseDown', eventData, mouseDownCallback); $(element).on('CornerstoneToolsMouseDown', eventData, mouseDownCallback);
$(element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.bidirectional.mouseDownActivateCallback); $(element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.bidirectional.mouseDownActivateCallback);
@ -673,18 +667,59 @@ function setHandlesVisible (handles, isVisibile) {
}); });
}; };
// Clear the selected state for the given handles object
function unselectAllHandles(handles) { function unselectAllHandles(handles) {
let imageNeedsUpdate = false;
Object.keys(handles).forEach(handleKey => { Object.keys(handles).forEach(handleKey => {
if (handleKey === 'textBox') return; if (handleKey === 'textBox') return;
handles[handleKey].selected = false; handles[handleKey].selected = false;
imageNeedsUpdate = handles[handleKey].active || imageNeedsUpdate;
handles[handleKey].active = false; handles[handleKey].active = false;
}); });
return imageNeedsUpdate;
} }
// Clear the bidirectional tool's selection for all tool handles
function clearBidirectionalSelection(event) {
let imageNeedsUpdate = false;
const toolData = cornerstoneTools.getToolState(event.currentTarget, 'bidirectional');
if (!toolData) return;
toolData.data.forEach(data => {
data.selected = false;
imageNeedsUpdate = data.active || imageNeedsUpdate;
data.active = false;
const unselectResult = unselectAllHandles(data.handles);
imageNeedsUpdate = imageNeedsUpdate || unselectResult;
});
return imageNeedsUpdate;
}
// Replaces the cornerstoneTools.handleActivator function by skiping the active handle comparison
function handleActivator(element, handles, canvasPoint, distanceThreshold=6) {
const nearbyHandle = cornerstoneTools.getHandleNearImagePoint(element, handles, canvasPoint, distanceThreshold);
let handleActivatorChanged = false;
Object.keys(handles).forEach(handleKey => {
if (handleKey === 'textBox') return;
const handle = handles[handleKey];
const newActiveState = handle === nearbyHandle;
if (handle.active !== newActiveState) {
handleActivatorChanged = true;
}
handle.active = newActiveState;
});
return handleActivatorChanged;
}
// Add a proxy to cornerstoneTools.drawHandles function to change the handles' active state base on
// the hover, moving and selected states
function drawHandles(context, eventData, handles, color, options) { function drawHandles(context, eventData, handles, color, options) {
Object.keys(handles).forEach(handleKey => { Object.keys(handles).forEach(handleKey => {
if (handleKey === 'textBox') return; if (handleKey === 'textBox') return;
const handle = handles[handleKey]; const handle = handles[handleKey];
handle.drawnIndependently = handle.moving;
if (handle.selected) { if (handle.selected) {
handle.active = true; handle.active = true;
} else { } else {
@ -699,11 +734,6 @@ function drawHandles(context, eventData, handles, color, options) {
} }
function moveHandle(mouseEventData, toolType, data, handle, doneMovingCallback, preventHandleOutsideImage) { function moveHandle(mouseEventData, toolType, data, handle, doneMovingCallback, preventHandleOutsideImage) {
// Make handle invisible while moving
if (!handle.hasBoundingBox) {
handle.drawnIndependently = true;
}
var element = mouseEventData.element; var element = mouseEventData.element;
var distanceFromTool = { var distanceFromTool = {
x: handle.x - mouseEventData.currentPoints.image.x, x: handle.x - mouseEventData.currentPoints.image.x,
@ -742,10 +772,6 @@ function moveHandle(mouseEventData, toolType, data, handle, doneMovingCallback,
$(element).on('CornerstoneToolsMouseDrag', mouseDragCallback); $(element).on('CornerstoneToolsMouseDrag', mouseDragCallback);
function mouseUpCallback() { function mouseUpCallback() {
// Enable handle visibility again
if (!handle.hasBoundingBox) {
handle.drawnIndependently = false;
}
$(element).off('CornerstoneToolsMouseDrag', mouseDragCallback); $(element).off('CornerstoneToolsMouseDrag', mouseDragCallback);
$(element).off('CornerstoneToolsMouseUp', mouseUpCallback); $(element).off('CornerstoneToolsMouseUp', mouseUpCallback);
$(element).off('CornerstoneToolsMouseClick', mouseUpCallback); $(element).off('CornerstoneToolsMouseClick', mouseUpCallback);
@ -782,13 +808,13 @@ function mouseMoveCallback(e, eventData) {
var coords = eventData.currentPoints.canvas; var coords = eventData.currentPoints.canvas;
var data = toolData.data[i]; var data = toolData.data[i];
const handleActivatorChanged = cornerstoneTools.handleActivator(eventData.element, data.handles, coords); const handleActivatorChanged = handleActivator(eventData.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];
handle.hover = handle.active; handle.hover = handle.active;
}); });
if (handleActivatorChanged === true) { if (handleActivatorChanged) {
imageNeedsUpdate = true; imageNeedsUpdate = true;
} }
@ -809,6 +835,15 @@ function mouseDownCallback(e, eventData) {
var data; var data;
var element = eventData.element; var element = eventData.element;
// Clear selection on left mouse button click
let imageNeedsUpdate = false;
if (eventData.which === 1) {
const imageNeedsUpdate = clearBidirectionalSelection(e);
if (imageNeedsUpdate) {
cornerstone.updateImage(element);
}
}
function handleDoneMove(handle) { function handleDoneMove(handle) {
// Set the cursor back to its default // Set the cursor back to its default
$(element).css('cursor', ''); $(element).css('cursor', '');
@ -842,8 +877,8 @@ function mouseDownCallback(e, eventData) {
var distance = 6; var distance = 6;
var handle = cornerstoneTools.getHandleNearImagePoint(element, data.handles, coords, distance); var handle = cornerstoneTools.getHandleNearImagePoint(element, data.handles, coords, distance);
if (handle) { if (handle) {
// Hide the cursor to improve precision while resizing the line // Hide the cursor to improve precision while resizing the line or set to move if dragging text box
$(element).css('cursor', 'none'); $(element).css('cursor', handle.hasBoundingBox ? 'move' : 'none');
$(element).off('CornerstoneToolsMouseMove', mouseMoveCallback); $(element).off('CornerstoneToolsMouseMove', mouseMoveCallback);
data.active = true; data.active = true;
@ -851,7 +886,6 @@ function mouseDownCallback(e, eventData) {
unselectAllHandles(data.handles); unselectAllHandles(data.handles);
handle.moving = true; handle.moving = true;
handle.selected = true;
moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle)); moveHandle(eventData, toolType, data, handle, () => handleDoneMove(handle));
e.stopImmediatePropagation(); e.stopImmediatePropagation();
return false; return false;
@ -870,6 +904,9 @@ function mouseDownCallback(e, eventData) {
for (i = 0; i < toolData.data.length; i++) { for (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
$(element).css('cursor', 'move');
$(element).off('CornerstoneToolsMouseMove', mouseMoveCallback); $(element).off('CornerstoneToolsMouseMove', mouseMoveCallback);
data.active = true; data.active = true;
data.selected = true; data.selected = true;
@ -1039,8 +1076,9 @@ function onImageRendered(e, eventData) {
context.shadowOffsetY = config.shadowOffsetY || 1; context.shadowOffsetY = config.shadowOffsetY || 1;
} }
const activeColor = cornerstoneTools.toolColors.getActiveColor();
if (data.active) { if (data.active) {
color = cornerstoneTools.toolColors.getActiveColor(); color = activeColor;
} else { } else {
color = cornerstoneTools.toolColors.getToolColor(); color = cornerstoneTools.toolColors.getToolColor();
} }
@ -1050,18 +1088,27 @@ function onImageRendered(e, eventData) {
var handleEndCanvas = cornerstone.pixelToCanvas(element, data.handles.end); var handleEndCanvas = cornerstone.pixelToCanvas(element, data.handles.end);
var canvasTextLocation = cornerstone.pixelToCanvas(element, data.handles.textBox); var canvasTextLocation = cornerstone.pixelToCanvas(element, data.handles.textBox);
let lineColor;
if (!data.active && (data.handles.start.selected || data.handles.end.selected)) {
lineColor = activeColor;
}
context.beginPath(); context.beginPath();
context.strokeStyle = color; context.strokeStyle = lineColor || color;
context.lineWidth = strokeWidth; context.lineWidth = strokeWidth;
context.moveTo(handleStartCanvas.x, handleStartCanvas.y); context.moveTo(handleStartCanvas.x, handleStartCanvas.y);
context.lineTo(handleEndCanvas.x, handleEndCanvas.y); context.lineTo(handleEndCanvas.x, handleEndCanvas.y);
context.stroke(); context.stroke();
// Draw perpendicular line // Draw perpendicular line
drawPerpendicularLine(context, eventData, element, data, color, strokeWidth); let perpendicularColor;
if (!data.active && (data.handles.perpendicularStart.selected || data.handles.perpendicularEnd.selected)) {
perpendicularColor = activeColor;
}
drawPerpendicularLine(context, eventData, element, data, perpendicularColor || color, strokeWidth);
// Draw the handles // Draw the handles
drawHandles(context, eventData, data.handles, color, { drawHandlesIfActive: true }); const handlesColor = lineColor || perpendicularColor || color;
drawHandles(context, eventData, data.handles, handlesColor, { drawHandlesIfActive: true });
// Calculate the long axis length // Calculate the long axis length
var dx = (data.handles.start.x - data.handles.end.x) * (eventData.image.columnPixelSpacing || 1); var dx = (data.handles.start.x - data.handles.end.x) * (eventData.image.columnPixelSpacing || 1);