From 888c337f84b23494e9f557b842178ea22bcbbcab Mon Sep 17 00:00:00 2001 From: Bruno Alves de Faria Date: Fri, 25 Nov 2016 11:20:12 -0200 Subject: [PATCH] LT-40: Recalculating text call-outs position when creating measurments without dragging --- Packages/ohif-core/client/lib/cornerstone.js | 226 +++++++++--------- .../client/compatibility/bidirectionalTool.js | 5 +- .../client/compatibility/nonTargetTool.js | 7 +- .../measurementLocationDialog.js | 2 + 4 files changed, 119 insertions(+), 121 deletions(-) diff --git a/Packages/ohif-core/client/lib/cornerstone.js b/Packages/ohif-core/client/lib/cornerstone.js index 6dcb95ec8..dfba6b81c 100644 --- a/Packages/ohif-core/client/lib/cornerstone.js +++ b/Packages/ohif-core/client/lib/cornerstone.js @@ -28,7 +28,12 @@ OHIF.cornerstone.pixelToPage = (element, position) => { return result; }; -OHIF.cornerstone.repositionTextBoxWhileDragging = (eventData, measurementData) => { +OHIF.cornerstone.repositionTextBox = (eventData, measurementData) => { + // Stop here if it's not a measurement creating + if (!measurementData.isCreating) { + return; + } + const element = eventData.element; const enabledElement = cornerstone.getEnabledElement(element); const $element = $(element); @@ -96,124 +101,111 @@ OHIF.cornerstone.repositionTextBoxWhileDragging = (eventData, measurementData) = }; }; - const modifiedCallback = () => { - const handles = measurementData.handles; - const textBox = handles.textBox; + const handles = measurementData.handles; + const textBox = handles.textBox; - const $canvas = $(enabledElement.canvas); - const canvasWidth = $canvas.outerWidth(); - const canvasHeight = $canvas.outerHeight(); - const offset = $canvas.offset(); - const canvasDimensions = { - x: canvasWidth, - y: canvasHeight - }; - - const bounds = {}; - bounds.x = textBox.boundingBox.width; - bounds.y = textBox.boundingBox.height; - - const getHandlePosition = key => _.pick(handles[key], ['x', 'y']); - const start = getHandlePosition('start'); - const end = getHandlePosition('end'); - - const tool = {}; - tool.x = calculateAxisCenter('x', start, end); - tool.y = calculateAxisCenter('y', start, end); - - let limits = {}; - limits.x = image.width; - limits.y = image.height; - - let { directions, cornerAxis } = getRenderingInformation(limits, tool); - - const availableAreas = getAvailableBlankAreas(enabledElement, bounds.x, bounds.y); - const tempDirections = _.clone(directions); - let tempCornerAxis = cornerAxis; - let foundPlace = false; - let current = 0; - while (current < 4) { - if (availableAreas[tempCornerAxis + tempDirections[tempCornerAxis]]) { - foundPlace = true; - break; - } - - // Invert the direction for the next iteration - tempDirections[tempCornerAxis] *= -1; - - // Invert the tempCornerAxis - tempCornerAxis = tempCornerAxis === 'x' ? 'y' : 'x'; - - current++; - } - - let cornerAxisPosition; - if (foundPlace) { - _.extend(directions, tempDirections); - cornerAxis = tempCornerAxis; - cornerAxisPosition = directions[cornerAxis] < 0 ? 0 : limits[cornerAxis]; - } else { - _.extend(limits, canvasDimensions); - - const toolPositionOnCanvas = cornerstone.pixelToCanvas(element, tool); - const renderingInformation = getRenderingInformation(limits, toolPositionOnCanvas); - directions = renderingInformation.directions; - cornerAxis = renderingInformation.cornerAxis; - - const position = { - x: directions.x < 0 ? offset.left : offset.left + canvasWidth, - y: directions.y < 0 ? offset.top : offset.top + canvasHeight - }; - - const pixelPosition = cornerstone.pageToPixel(element, position.x, position.y); - cornerAxisPosition = pixelPosition[cornerAxis]; - } - - const toolAxis = cornerAxis === 'x' ? 'y' : 'x'; - const boxSize = getTextBoxSizeInPixels(element, bounds); - - textBox[cornerAxis] = cornerAxisPosition; - textBox[toolAxis] = tool[toolAxis] - (boxSize[toolAxis] / 2); - - // Adjust the text box position reducing its size from the corner axis - const isDirectionPositive = directions[cornerAxis] > 0; - if ((foundPlace && !isDirectionPositive) || (!foundPlace && isDirectionPositive)) { - textBox[cornerAxis] -= boxSize[cornerAxis]; - } - - // Preventing the text box from partially going outside the canvas area - const topLeft = cornerstone.pixelToCanvas(element, textBox); - const bottomRight = { - x: topLeft.x + bounds.x, - y: topLeft.y + bounds.y - }; - const canvasBorders = { - x0: offset.left, - y0: offset.top, - x1: offset.left + canvasWidth, - y1: offset.top + canvasHeight - }; - if (topLeft[toolAxis] < 0) { - const x = canvasBorders.x0; - const y = canvasBorders.y0; - const pixelPosition = cornerstone.pageToPixel(element, x, y); - textBox[toolAxis] = pixelPosition[toolAxis]; - } else if (bottomRight[toolAxis] > canvasDimensions[toolAxis]) { - const x = canvasBorders.x1 - bounds.x; - const y = canvasBorders.y1 - bounds.y; - const pixelPosition = cornerstone.pageToPixel(element, x, y); - textBox[toolAxis] = pixelPosition[toolAxis]; - } + const $canvas = $(enabledElement.canvas); + const canvasWidth = $canvas.outerWidth(); + const canvasHeight = $canvas.outerHeight(); + const offset = $canvas.offset(); + const canvasDimensions = { + x: canvasWidth, + y: canvasHeight }; - const mouseUpCallback = () => { - $element.off('CornerstoneToolsMeasurementModified', modifiedCallback); + const bounds = {}; + bounds.x = textBox.boundingBox.width; + bounds.y = textBox.boundingBox.height; + + const getHandlePosition = key => _.pick(handles[key], ['x', 'y']); + const start = getHandlePosition('start'); + const end = getHandlePosition('end'); + + const tool = {}; + tool.x = calculateAxisCenter('x', start, end); + tool.y = calculateAxisCenter('y', start, end); + + let limits = {}; + limits.x = image.width; + limits.y = image.height; + + let { directions, cornerAxis } = getRenderingInformation(limits, tool); + + const availableAreas = getAvailableBlankAreas(enabledElement, bounds.x, bounds.y); + const tempDirections = _.clone(directions); + let tempCornerAxis = cornerAxis; + let foundPlace = false; + let current = 0; + while (current < 4) { + if (availableAreas[tempCornerAxis + tempDirections[tempCornerAxis]]) { + foundPlace = true; + break; + } + + // Invert the direction for the next iteration + tempDirections[tempCornerAxis] *= -1; + + // Invert the tempCornerAxis + tempCornerAxis = tempCornerAxis === 'x' ? 'y' : 'x'; + + current++; + } + + let cornerAxisPosition; + if (foundPlace) { + _.extend(directions, tempDirections); + cornerAxis = tempCornerAxis; + cornerAxisPosition = directions[cornerAxis] < 0 ? 0 : limits[cornerAxis]; + } else { + _.extend(limits, canvasDimensions); + + const toolPositionOnCanvas = cornerstone.pixelToCanvas(element, tool); + const renderingInformation = getRenderingInformation(limits, toolPositionOnCanvas); + directions = renderingInformation.directions; + cornerAxis = renderingInformation.cornerAxis; + + const position = { + x: directions.x < 0 ? offset.left : offset.left + canvasWidth, + y: directions.y < 0 ? offset.top : offset.top + canvasHeight + }; + + const pixelPosition = cornerstone.pageToPixel(element, position.x, position.y); + cornerAxisPosition = pixelPosition[cornerAxis]; + } + + const toolAxis = cornerAxis === 'x' ? 'y' : 'x'; + const boxSize = getTextBoxSizeInPixels(element, bounds); + + textBox[cornerAxis] = cornerAxisPosition; + textBox[toolAxis] = tool[toolAxis] - (boxSize[toolAxis] / 2); + + // Adjust the text box position reducing its size from the corner axis + const isDirectionPositive = directions[cornerAxis] > 0; + if ((foundPlace && !isDirectionPositive) || (!foundPlace && isDirectionPositive)) { + textBox[cornerAxis] -= boxSize[cornerAxis]; + } + + // Preventing the text box from partially going outside the canvas area + const topLeft = cornerstone.pixelToCanvas(element, textBox); + const bottomRight = { + x: topLeft.x + bounds.x, + y: topLeft.y + bounds.y }; - - $element.one('CornerstoneToolsMouseDrag', () => { - $element.on('CornerstoneToolsMeasurementModified', modifiedCallback); - }); - - // Using mouseup because sometimes the CornerstoneToolsMouseUp event is not triggered - $element.one('mouseup', mouseUpCallback); + const canvasBorders = { + x0: offset.left, + y0: offset.top, + x1: offset.left + canvasWidth, + y1: offset.top + canvasHeight + }; + if (topLeft[toolAxis] < 0) { + const x = canvasBorders.x0; + const y = canvasBorders.y0; + const pixelPosition = cornerstone.pageToPixel(element, x, y); + textBox[toolAxis] = pixelPosition[toolAxis]; + } else if (bottomRight[toolAxis] > canvasDimensions[toolAxis]) { + const x = canvasBorders.x1 - bounds.x; + const y = canvasBorders.y1 - bounds.y; + const pixelPosition = cornerstone.pageToPixel(element, x, y); + textBox[toolAxis] = pixelPosition[toolAxis]; + } }; diff --git a/Packages/ohif-lesiontracker/client/compatibility/bidirectionalTool.js b/Packages/ohif-lesiontracker/client/compatibility/bidirectionalTool.js index 97c6f110c..53e0c6429 100644 --- a/Packages/ohif-lesiontracker/client/compatibility/bidirectionalTool.js +++ b/Packages/ohif-lesiontracker/client/compatibility/bidirectionalTool.js @@ -44,6 +44,7 @@ import { OHIF } from 'meteor/ohif:core'; function createNewMeasurement(mouseEventData) { // Create the measurement data for this tool with the end handle activated const measurementData = { + isCreating: true, visible: true, active: true, handles: { @@ -99,8 +100,6 @@ import { OHIF } from 'meteor/ohif:core'; toolType: 'bidirectional' }; - OHIF.cornerstone.repositionTextBoxWhileDragging(mouseEventData, measurementData); - return measurementData; } @@ -1040,6 +1039,8 @@ import { OHIF } from 'meteor/ohif:core'; data.handles.textBox.boundingBox = boundingBox; + OHIF.cornerstone.repositionTextBox(eventData, data); + // Draw linked line as dashed var link = { start: {}, diff --git a/Packages/ohif-lesiontracker/client/compatibility/nonTargetTool.js b/Packages/ohif-lesiontracker/client/compatibility/nonTargetTool.js index e8590a939..879a6ad6e 100644 --- a/Packages/ohif-lesiontracker/client/compatibility/nonTargetTool.js +++ b/Packages/ohif-lesiontracker/client/compatibility/nonTargetTool.js @@ -38,6 +38,8 @@ import { toolManager } from 'meteor/ohif:viewerbase'; return; } + delete measurementData.isCreating; + OHIF.ui.showFormDialog('dialogNonTargetMeasurement', { position: getPosition(eventData), title: 'Select Lesion Location', @@ -142,6 +144,7 @@ import { toolManager } from 'meteor/ohif:viewerbase'; // create the measurement data for this tool with the end handle activated var measurementData = { + isCreating: true, visible: true, active: true, handles: { @@ -178,8 +181,6 @@ import { toolManager } from 'meteor/ohif:viewerbase'; toolType: 'nonTarget' }; - OHIF.cornerstone.repositionTextBoxWhileDragging(mouseEventData, measurementData); - return measurementData; } ///////// END ACTIVE TOOL /////// @@ -255,6 +256,8 @@ import { toolManager } from 'meteor/ohif:viewerbase'; var boundingBox = cornerstoneTools.drawTextBox(context, 'Non-Target ' + data.measurementNumber, canvasTextLocation.x, canvasTextLocation.y, color); data.handles.textBox.boundingBox = boundingBox; + OHIF.cornerstone.repositionTextBox(eventData, data); + // Draw linked line as dashed var link = { start: {}, diff --git a/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js b/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js index ef3eb4132..1fb976eb3 100644 --- a/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js +++ b/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js @@ -40,6 +40,8 @@ Template.measurementLocationDialog.onCreated(() => { const timepointApi = instance.data.timepointApi; const toggleLabel = (measurementData, eventData, doneCallback) => { + delete measurementData.isCreating; + if (OHIF.lesiontracker.removeMeasurementIfInvalid(measurementData, eventData)) { return; }