277 lines
9.3 KiB
JavaScript
277 lines
9.3 KiB
JavaScript
import { Session } from 'meteor/session';
|
|
import { OHIF } from 'ohif-core';
|
|
import { cornerstone, cornerstoneTools } from 'meteor/ohif:cornerstone';
|
|
|
|
let activeTool;
|
|
let tools = {};
|
|
let initialized = false;
|
|
let defaultTool = {
|
|
left: 'wwwc',
|
|
right: 'zoom',
|
|
middle: 'pan'
|
|
};
|
|
|
|
const defaultToolConfig = {
|
|
shadow: false,
|
|
shadowColor: '#000000',
|
|
shadowOffsetX: 0,
|
|
shadowOffsetY: 0,
|
|
drawHandlesOnHover: true
|
|
};
|
|
|
|
const buttonNum = {
|
|
'left': 1,
|
|
'right': 2,
|
|
'middle': 4
|
|
};
|
|
|
|
/**
|
|
* Exported "toolManager" Singleton
|
|
*/
|
|
export const toolManager = {
|
|
init() {
|
|
// if a default tool is globally defined, make it the default tool...
|
|
if (OHIF.viewer.defaultTool) {
|
|
toolManager.setDefaultTool(OHIF.viewer.defaultTool.left);
|
|
toolManager.setDefaultTool(OHIF.viewer.defaultTool.right, 'right');
|
|
toolManager.setDefaultTool(OHIF.viewer.defaultTool.middle, 'middle');
|
|
}
|
|
|
|
cornerstoneTools.init();
|
|
|
|
tools = {
|
|
length: 'LengthTool',
|
|
angle: 'AngleTool',
|
|
annotate: 'ArrowAnnotateTool',
|
|
wwwc: 'WwwcTool',
|
|
zoom: 'ZoomTool',
|
|
pan: 'PanTool',
|
|
dragProbe: 'DragProbeTool',
|
|
magnify: 'MagnifyTool',
|
|
crosshairs: 'CrosshairsTool',
|
|
stackScroll: 'StackScrollTool',
|
|
ellipticalRoi: 'EllipticalRoiTool',
|
|
rectangleRoi: 'RectangleRoiTool',
|
|
wwwcRegion: 'WwwcRegionTool',
|
|
zoomTouchPinch: 'ZoomTouchPinchTool',
|
|
panMultiTouch: 'PanMultiTouchTool',
|
|
stackScrollMouseWheel: 'StackScrollMouseWheelTool',
|
|
referenceLines: 'ReferenceLinesTool'
|
|
};
|
|
|
|
const { textStyle, toolStyle, toolColors } = cornerstoneTools;
|
|
|
|
// Set text box background color
|
|
textStyle.setBackgroundColor('transparent');
|
|
|
|
// Set the tool font and font size
|
|
// context.font = "[style] [variant] [weight] [size]/[line height] [font family]";
|
|
const fontFamily = 'Roboto, OpenSans, HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif';
|
|
textStyle.setFont('15px ' + fontFamily);
|
|
|
|
// Set the tool width
|
|
toolStyle.setToolWidth(2);
|
|
|
|
// Set color for inactive tools
|
|
toolColors.setToolColor('rgb(255, 255, 0)'); // yellow
|
|
|
|
// Set color for active tools
|
|
toolColors.setActiveColor('rgb(50, 205, 50)'); // limegreen
|
|
|
|
initialized = true;
|
|
},
|
|
/**
|
|
* This function searches an object to return the keys that contain a specific value
|
|
*
|
|
* @param object {object} The object to be searched
|
|
* @param value The value to be found
|
|
*
|
|
* @returns {array} The keys for which the object has the specified value
|
|
*/
|
|
getKeysByValue(object, value) {
|
|
// http://stackoverflow.com/questions/9907419/javascript-object-get-key-by-value
|
|
return Object.keys(object).filter(key => object[key] === value);
|
|
},
|
|
|
|
getMouseButtonMask(button) {
|
|
return buttonNum[button] || undefined;
|
|
},
|
|
|
|
configureLoadProcess() {
|
|
// Whenever CornerstoneImageLoadProgress is fired, identify which viewports
|
|
// the "in-progress" image is to be displayed in. Then pass the percent complete
|
|
// via the Meteor Session to the other templates to be displayed in the relevant viewports.
|
|
|
|
function handleLoadProgress (e) {
|
|
const eventData = e.detail;
|
|
const viewportIndices = toolManager.getKeysByValue(window.ViewportLoading, eventData.imageId);
|
|
viewportIndices.forEach(viewportIndex => {
|
|
Session.set('CornerstoneLoadProgress' + viewportIndex, eventData.percentComplete);
|
|
});
|
|
|
|
const encodedId = OHIF.string.encodeId(eventData.imageId);
|
|
Session.set('CornerstoneThumbnailLoadProgress' + encodedId, eventData.percentComplete);
|
|
}
|
|
|
|
cornerstone.events.removeEventListener('cornerstoneimageloadprogress', handleLoadProgress);
|
|
cornerstone.events.addEventListener('cornerstoneimageloadprogress', handleLoadProgress);
|
|
},
|
|
|
|
getTools() {
|
|
return Object.keys(tools);
|
|
},
|
|
|
|
setActiveTool(toolName, button = 'left') {
|
|
// Using setActiveTool with no arguments activates the default tools for all buttons
|
|
if (!toolName) {
|
|
toolManager.setActiveTool(toolManager.getDefaultTool());
|
|
toolManager.setActiveTool(toolManager.getDefaultTool('right'), 'right');
|
|
toolManager.setActiveTool(toolManager.getDefaultTool('middle'), 'middle');
|
|
return;
|
|
}
|
|
|
|
let options = {};
|
|
const mouseButtonMask = toolManager.getMouseButtonMask(button);
|
|
if (mouseButtonMask) {
|
|
options = {
|
|
mouseButtonMask
|
|
}
|
|
}
|
|
|
|
// Set active tools for the other buttons than this one
|
|
switch(button) {
|
|
case 'left':
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('right'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('right')
|
|
});
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('middle'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('middle')
|
|
});
|
|
break;
|
|
case 'right':
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('left'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('left')
|
|
});
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('middle'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('middle')
|
|
});
|
|
break;
|
|
case 'middle':
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('left'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('left')
|
|
});
|
|
cornerstoneTools.setToolActive(toolManager.getActiveTool('right'), {
|
|
mouseButtonMask: toolManager.getMouseButtonMask('right')
|
|
});
|
|
break;
|
|
}
|
|
|
|
cornerstoneTools.setToolActive(toolName, options);
|
|
activeTool[button] = toolName;
|
|
},
|
|
|
|
instantiateTools(element) {
|
|
// Instantiate all cornerstone tools for the given element
|
|
Object.keys(tools).forEach(toolName => {
|
|
const apiTool = cornerstoneTools[tools[toolName]];
|
|
if (apiTool) {
|
|
cornerstoneTools.addToolForElement(element, apiTool, {
|
|
name: toolName,
|
|
configuration: defaultToolConfig
|
|
});
|
|
|
|
// Set all tools (except the active tools) passive by default in order to render the external data if exists
|
|
if (!activeTool || !Object.values(activeTool).includes(toolName)) {
|
|
cornerstoneTools.setToolPassive(toolName);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Activate pinch zoom
|
|
cornerstoneTools.setToolActive('zoomTouchPinch', {
|
|
mouseButtonMask: 0,
|
|
isTouchActive: true
|
|
});
|
|
|
|
// Activate two-finger pan
|
|
cornerstoneTools.setToolActive('panMultiTouch', {
|
|
mouseButtonMask: 0,
|
|
isTouchActive: true
|
|
});
|
|
|
|
// Activate mouse wheel and three (or more) finger stack scroll
|
|
cornerstoneTools.setToolActive('stackScrollMouseWheel', {
|
|
mouseButtonMask: 0,
|
|
isTouchActive: true
|
|
});
|
|
},
|
|
|
|
removeToolsForElement(element) {
|
|
Object.keys(tools).forEach(toolName => {
|
|
cornerstoneTools.removeToolForElement(element, toolName);
|
|
});
|
|
},
|
|
|
|
getNearbyToolData(element, coords, toolTypes) {
|
|
let pointNearTool = false;
|
|
const nearbyTool = {};
|
|
|
|
const toolTypesToCheck = toolTypes || this.getTools();
|
|
toolTypesToCheck.forEach(toolType => {
|
|
const toolData = cornerstoneTools.getToolState(element, toolType);
|
|
if (!toolData) {
|
|
return;
|
|
}
|
|
|
|
for (let i = 0; i < toolData.data.length; i++) {
|
|
const data = toolData.data[i];
|
|
const tool = cornerstoneTools.getToolForElement(element, toolType);
|
|
if (tool && typeof tool.pointNearTool === 'function' && tool.pointNearTool(element, data, coords)) {
|
|
pointNearTool = true;
|
|
nearbyTool.tool = data;
|
|
nearbyTool.index = i;
|
|
nearbyTool.toolType = toolType;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pointNearTool === true) {
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return pointNearTool ? nearbyTool : undefined;
|
|
},
|
|
|
|
getActiveTool(button = 'left') {
|
|
if (!initialized) {
|
|
toolManager.init();
|
|
}
|
|
|
|
// If activeTool is not defined, we should set as defaultTool
|
|
if (!activeTool) {
|
|
activeTool = defaultTool;
|
|
}
|
|
|
|
return activeTool[button];
|
|
},
|
|
|
|
setDefaultTool(tool, button = 'left') {
|
|
defaultTool[button] = tool;
|
|
},
|
|
|
|
getDefaultTool(button = 'left') {
|
|
return defaultTool[button];
|
|
},
|
|
|
|
activateCommandButton(button) {
|
|
// TODO: Do we need this?
|
|
},
|
|
|
|
deactivateCommandButton(button) {
|
|
// TODO: Do we need this?
|
|
}
|
|
};
|
|
|
|
toolManager.init();
|