OHIF-110: creating the context-menu for measurements in the viewport for desktop and mobile. Coded action delete (#112)
This commit is contained in:
parent
af4b8b45f5
commit
bacfa24216
@ -105,11 +105,20 @@ OHIF.mixins.dropdown = new OHIF.Mixin({
|
|||||||
|
|
||||||
// Change the dropdown position if mouse event was given
|
// Change the dropdown position if mouse event was given
|
||||||
if (event) {
|
if (event) {
|
||||||
|
const originalEventTouches = event.originalEvent.touches;
|
||||||
const position = {
|
const position = {
|
||||||
left: event.clientX,
|
left: 0,
|
||||||
top: event.clientY
|
top: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (originalEventTouches && originalEventTouches.length > 0) {
|
||||||
|
position.left = originalEventTouches[0].pageX;
|
||||||
|
position.top = originalEventTouches[0].pageY;
|
||||||
|
} else {
|
||||||
|
position.left = event.clientX;
|
||||||
|
position.top = event.clientY
|
||||||
|
}
|
||||||
|
|
||||||
if (centered) {
|
if (centered) {
|
||||||
// Center the dropdown menu based on the event mouse position
|
// Center the dropdown menu based on the event mouse position
|
||||||
position.left -= $dropdownMenu.outerWidth() / 2;
|
position.left -= $dropdownMenu.outerWidth() / 2;
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
import { toolManager } from '../../../lib/toolManager';
|
||||||
|
|
||||||
|
const toolTypes = ['length', 'simpleAngle', 'probe', 'ellipticalRoi', 'rectangleRoi', 'arrowAnnotate'];
|
||||||
|
const TypeToLabelMap = {
|
||||||
|
length: 'Length',
|
||||||
|
simpleAngle: 'Angle',
|
||||||
|
probe: 'Probe',
|
||||||
|
ellipticalRoi: 'Elliptical ROI',
|
||||||
|
rectangleRoi: 'Rectangle ROI',
|
||||||
|
arrowAnnotate: 'Annotation'
|
||||||
|
};
|
||||||
|
let dropdownItems = [{
|
||||||
|
actionType: 'Delete',
|
||||||
|
action: ({nearbyToolData, eventData}) => {
|
||||||
|
const element = eventData.element
|
||||||
|
|
||||||
|
cornerstoneTools.removeToolState(element, nearbyToolData.toolType, nearbyToolData.tool);
|
||||||
|
cornerstone.updateImage(element);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
let timer = 0;
|
||||||
|
|
||||||
|
const getTypeText = function(toolData, actionType) {
|
||||||
|
const toolType = toolData.toolType;
|
||||||
|
let message = `${TypeToLabelMap[toolType]}`;
|
||||||
|
|
||||||
|
if (toolType === 'arrowAnnotate') {
|
||||||
|
message = `${message} "${toolData.tool.text}"`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${actionType} ${message}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createDropdown = function (event, eventData, isTouchEvent = false) {
|
||||||
|
const nearbyToolData = toolManager.getNearbyToolData(eventData.element, eventData.currentPoints.canvas, toolTypes);
|
||||||
|
|
||||||
|
// Annotate tools for touch events already have a press handle to edit it, has a better UX for deleting it
|
||||||
|
if (isTouchEvent && nearbyToolData.toolType === 'arrowAnnotate') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nearbyToolData) {
|
||||||
|
dropdownItems.forEach(function(item) {
|
||||||
|
item.params = {
|
||||||
|
eventData,
|
||||||
|
nearbyToolData
|
||||||
|
};
|
||||||
|
item.text = getTypeText(nearbyToolData, item.actionType);
|
||||||
|
});
|
||||||
|
|
||||||
|
OHIF.ui.showDropdown(dropdownItems, {
|
||||||
|
menuClasses: 'dropdown-menu-left',
|
||||||
|
event: eventData.event
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Template.viewerMain.events({
|
||||||
|
'CornerstoneToolsMouseClick .imageViewerViewport'(event, instance, eventData) {
|
||||||
|
if (event.which === 3) {
|
||||||
|
createDropdown(event, eventData);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'CornerstoneToolsTouchPress .imageViewerViewport'(event, instance, eventData) {
|
||||||
|
createDropdown(event, eventData, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -6,6 +6,7 @@ import { updateCrosshairsSynchronizer } from './updateCrosshairsSynchronizer';
|
|||||||
import { crosshairsSynchronizers } from './crosshairsSynchronizers';
|
import { crosshairsSynchronizers } from './crosshairsSynchronizers';
|
||||||
import { annotateTextUtils } from './annotateTextUtils';
|
import { annotateTextUtils } from './annotateTextUtils';
|
||||||
import { textMarkerUtils } from './textMarkerUtils';
|
import { textMarkerUtils } from './textMarkerUtils';
|
||||||
|
import { isTouchDevice } from './helpers/isTouchDevice';
|
||||||
|
|
||||||
let defaultTool = 'wwwc';
|
let defaultTool = 'wwwc';
|
||||||
let activeTool;
|
let activeTool;
|
||||||
@ -446,6 +447,51 @@ export const toolManager = {
|
|||||||
Session.set('ToolManagerActiveTool', tool);
|
Session.set('ToolManagerActiveTool', tool);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getNearbyToolData(element, coords, toolTypes) {
|
||||||
|
const allTools = this.getTools();
|
||||||
|
const touchDevice = isTouchDevice();
|
||||||
|
const nearbyTool = {};
|
||||||
|
let pointNearTool = false;
|
||||||
|
|
||||||
|
toolTypes.forEach(function(toolType) {
|
||||||
|
const toolData = cornerstoneTools.getToolState(element, toolType);
|
||||||
|
if (!toolData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolData.data.forEach(function(data, index) {
|
||||||
|
let toolInterfaceName = toolType;
|
||||||
|
let toolInterface;
|
||||||
|
|
||||||
|
// Edge cases where the tool is not the same as the typeName
|
||||||
|
if (toolType === 'simpleAngle') {
|
||||||
|
toolInterfaceName = 'angle';
|
||||||
|
} else if (toolType === 'arrowAnnotate') {
|
||||||
|
toolInterfaceName = 'annotate';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touchDevice) {
|
||||||
|
toolInterface = allTools[toolInterfaceName].touch;
|
||||||
|
} else {
|
||||||
|
toolInterface = allTools[toolInterfaceName].mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toolInterface.pointNearTool(element, data, coords)) {
|
||||||
|
pointNearTool = true;
|
||||||
|
nearbyTool.tool = data;
|
||||||
|
nearbyTool.index = index;
|
||||||
|
nearbyTool.toolType = toolType;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (pointNearTool) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return pointNearTool ? nearbyTool : undefined;
|
||||||
|
},
|
||||||
|
|
||||||
getActiveTool() {
|
getActiveTool() {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
toolManager.init();
|
toolManager.init();
|
||||||
|
|||||||
@ -146,6 +146,8 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('client/components/viewer/viewerMain/viewerMain.js', 'client');
|
api.addFiles('client/components/viewer/viewerMain/viewerMain.js', 'client');
|
||||||
api.addFiles('client/components/viewer/viewerMain/viewerMain.styl', 'client');
|
api.addFiles('client/components/viewer/viewerMain/viewerMain.styl', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/viewer/toolContextMenu/toolContextMenu.js', 'client');
|
||||||
|
|
||||||
api.addFiles('client/components/viewer/imageControls/imageControls.html', 'client');
|
api.addFiles('client/components/viewer/imageControls/imageControls.html', 'client');
|
||||||
api.addFiles('client/components/viewer/imageControls/imageControls.js', 'client');
|
api.addFiles('client/components/viewer/imageControls/imageControls.js', 'client');
|
||||||
api.addFiles('client/components/viewer/imageControls/imageControls.styl', 'client');
|
api.addFiles('client/components/viewer/imageControls/imageControls.styl', 'client');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user