diff --git a/Packages/ohif-cornerstone/client/index.js b/Packages/ohif-cornerstone/client/index.js index 464571ff5..8580aa70a 100644 --- a/Packages/ohif-cornerstone/client/index.js +++ b/Packages/ohif-cornerstone/client/index.js @@ -1,6 +1,5 @@ import { OHIF } from '../namespace'; import './renderer.js'; -import './lib/cornerstoneToolsMouseInputOverrides.js'; import { MetadataProvider } from './lib/classes/MetadataProvider'; OHIF.cornerstone.metadataProvider = new MetadataProvider(); diff --git a/Packages/ohif-cornerstone/client/lib/cornerstoneToolsMouseInputOverrides.js b/Packages/ohif-cornerstone/client/lib/cornerstoneToolsMouseInputOverrides.js deleted file mode 100644 index 36c5500e7..000000000 --- a/Packages/ohif-cornerstone/client/lib/cornerstoneToolsMouseInputOverrides.js +++ /dev/null @@ -1,308 +0,0 @@ -// This override was included due to an issue with tools handles on Safari, Firefox and IE/Edge -// TODO: Remove this override after the pull-request is accepted and the new version of -// cornerstoneTools is updated on the ohif:cornerstone package. -// Pull request: https://github.com/chafey/cornerstoneTools/pull/230 - -import { cornerstone, cornerstoneTools, cornerstoneMath } from 'meteor/ohif:cornerstone'; -const { copyPoints, pauseEvent } = cornerstoneTools; - -let isClickEvent = true; -let preventClickTimeout; -const clickDelay = 200; - -function getEventWhich (event) { - if (typeof event.buttons !== 'number') { - return event.which; - } - - if (event.buttons === 0) { - return 0; - } else if (event.buttons % 2 === 1) { - return 1; - } else if (event.buttons % 4 === 2) { - return 3; - } else if (event.buttons % 8 === 4) { - return 2; - } - - return 0; -} - -function preventClickHandler () { - isClickEvent = false; -} - -function activateMouseDown (mouseEventDetail) { - $(mouseEventDetail.element).trigger('CornerstoneToolsMouseDownActivate', mouseEventDetail); -} - -function mouseDoubleClick (e) { - const element = e.currentTarget; - const eventType = 'CornerstoneToolsMouseDoubleClick'; - - const startPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - startPoints.canvas = cornerstone.pixelToCanvas(element, startPoints.image); - - const lastPoints = copyPoints(startPoints); - const eventData = { - event: e, - which: getEventWhich(e), - viewport: cornerstone.getViewport(element), - image: cornerstone.getEnabledElement(element).image, - element, - startPoints, - lastPoints, - currentPoints: startPoints, - deltaPoints: { - x: 0, - y: 0 - }, - type: eventType - }; - - const event = $.Event(eventType, eventData); - - $(eventData.element).trigger(event, eventData); -} - -function mouseDown (e) { - preventClickTimeout = setTimeout(preventClickHandler, clickDelay); - - const element = e.currentTarget; - const eventType = 'CornerstoneToolsMouseDown'; - - // Prevent CornerstoneToolsMouseMove while mouse is down - $(element).off('mousemove', mouseMove); - - const startPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - startPoints.canvas = cornerstone.pixelToCanvas(element, startPoints.image); - - let lastPoints = copyPoints(startPoints); - const eventData = { - event: e, - which: getEventWhich(e), - viewport: cornerstone.getViewport(element), - image: cornerstone.getEnabledElement(element).image, - element, - startPoints, - lastPoints, - currentPoints: startPoints, - deltaPoints: { - x: 0, - y: 0 - }, - type: eventType - }; - - const event = $.Event(eventType, eventData); - - $(eventData.element).trigger(event, eventData); - - if (event.isImmediatePropagationStopped() === false) { - // No tools responded to this event, give the active tool a chance - if (activateMouseDown(eventData) === true) { - return pauseEvent(e); - } - } - - const whichMouseButton = getEventWhich(e); - - function onMouseMove (e) { - // Calculate our current points in page and image coordinates - const eventType = 'CornerstoneToolsMouseDrag'; - const currentPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - currentPoints.canvas = cornerstone.pixelToCanvas(element, currentPoints.image); - - // Calculate delta values in page and image coordinates - const deltaPoints = { - page: cornerstoneMath.point.subtract(currentPoints.page, lastPoints.page), - image: cornerstoneMath.point.subtract(currentPoints.image, lastPoints.image), - client: cornerstoneMath.point.subtract(currentPoints.client, lastPoints.client), - canvas: cornerstoneMath.point.subtract(currentPoints.canvas, lastPoints.canvas) - }; - - const eventData = { - which: whichMouseButton, - viewport: cornerstone.getViewport(element), - image: cornerstone.getEnabledElement(element).image, - element, - startPoints, - lastPoints, - currentPoints, - deltaPoints, - type: eventType, - ctrlKey: e.ctrlKey, - metaKey: e.metaKey, - shiftKey: e.shiftKey - }; - - $(eventData.element).trigger(eventType, eventData); - - // Update the last points - lastPoints = copyPoints(currentPoints); - - // Prevent left click selection of DOM elements - return pauseEvent(e); - } - - // Hook mouseup so we can unbind our event listeners - // When they stop dragging - function onMouseUp (e) { - // Cancel the timeout preventing the click event from triggering - clearTimeout(preventClickTimeout); - - let eventType = 'CornerstoneToolsMouseUp'; - - if (isClickEvent) { - eventType = 'CornerstoneToolsMouseClick'; - } - - // Calculate our current points in page and image coordinates - const currentPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - currentPoints.canvas = cornerstone.pixelToCanvas(element, currentPoints.image); - - // Calculate delta values in page and image coordinates - const deltaPoints = { - page: cornerstoneMath.point.subtract(currentPoints.page, lastPoints.page), - image: cornerstoneMath.point.subtract(currentPoints.image, lastPoints.image), - client: cornerstoneMath.point.subtract(currentPoints.client, lastPoints.client), - canvas: cornerstoneMath.point.subtract(currentPoints.canvas, lastPoints.canvas) - }; - - const eventData = { - event: e, - which: whichMouseButton, - viewport: cornerstone.getViewport(element), - image: cornerstone.getEnabledElement(element).image, - element, - startPoints, - lastPoints, - currentPoints, - deltaPoints, - type: eventType - }; - - const event = $.Event(eventType, eventData); - - $(eventData.element).trigger(event, eventData); - - $(document).off('mousemove', onMouseMove); - $(document).off('mouseup', onMouseUp); - - $(eventData.element).on('mousemove', mouseMove); - - isClickEvent = true; - } - - $(document).on('mousemove', onMouseMove); - $(document).on('mouseup', onMouseUp); - - return pauseEvent(e); -} - -function mouseMove (e) { - const element = e.currentTarget; - const eventType = 'CornerstoneToolsMouseMove'; - - const startPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - startPoints.canvas = cornerstone.pixelToCanvas(element, startPoints.image); - - let lastPoints = copyPoints(startPoints); - - const whichMouseButton = getEventWhich(e); - - // Calculate our current points in page and image coordinates - const currentPoints = { - page: cornerstoneMath.point.pageToPoint(e), - image: cornerstone.pageToPixel(element, e.pageX, e.pageY), - client: { - x: e.clientX, - y: e.clientY - } - }; - - currentPoints.canvas = cornerstone.pixelToCanvas(element, currentPoints.image); - - // Calculate delta values in page and image coordinates - const deltaPoints = { - page: cornerstoneMath.point.subtract(currentPoints.page, lastPoints.page), - image: cornerstoneMath.point.subtract(currentPoints.image, lastPoints.image), - client: cornerstoneMath.point.subtract(currentPoints.client, lastPoints.client), - canvas: cornerstoneMath.point.subtract(currentPoints.canvas, lastPoints.canvas) - }; - - const eventData = { - which: whichMouseButton, - viewport: cornerstone.getViewport(element), - image: cornerstone.getEnabledElement(element).image, - element, - startPoints, - lastPoints, - currentPoints, - deltaPoints, - type: eventType - }; - - $(element).trigger(eventType, eventData); - - // Update the last points - lastPoints = copyPoints(currentPoints); -} - -function disable (element) { - $(element).off('mousedown', mouseDown); - $(element).off('mousemove', mouseMove); - $(element).off('dblclick', mouseDoubleClick); -} - -function enable (element) { - // Prevent handlers from being attached multiple times - disable(element); - - $(element).on('mousedown', mouseDown); - $(element).on('mousemove', mouseMove); - $(element).on('dblclick', mouseDoubleClick); -} - -cornerstoneTools.mouseInput.enable = enable; -cornerstoneTools.mouseInput.disable = disable; diff --git a/Packages/ohif-cornerstone/main.js b/Packages/ohif-cornerstone/main.js index 25ce1ddda..ae444fb6b 100644 --- a/Packages/ohif-cornerstone/main.js +++ b/Packages/ohif-cornerstone/main.js @@ -13,7 +13,6 @@ import * as cornerstoneTools from 'cornerstone-tools'; import * as cornerstoneMath from 'cornerstone-math'; import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'; import * as dicomParser from 'dicom-parser'; -import { $ } from 'meteor/jquery'; import Hammer from 'hammerjs'; import './client/'; // which is actually: import './client/index.js'; @@ -22,11 +21,11 @@ import './client/'; // which is actually: import './client/index.js'; // WADO Image Loader and Tools libraries // // Note: You would also need to do this with Cornerstone Web Image Loader -cornerstone.external.$ = $; -cornerstoneTools.external.$ = $; cornerstoneTools.external.Hammer = Hammer; cornerstoneTools.external.cornerstone = cornerstone; +cornerstoneTools.external.cornerstoneMath = cornerstoneMath; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; +cornerstoneWADOImageLoader.external.dicomParser = dicomParser; export { cornerstone, diff --git a/Packages/ohif-cornerstone/package.js b/Packages/ohif-cornerstone/package.js index 8942a2dd7..0802073b1 100644 --- a/Packages/ohif-cornerstone/package.js +++ b/Packages/ohif-cornerstone/package.js @@ -6,19 +6,17 @@ Package.describe({ Npm.depends({ hammerjs: '2.0.8', - 'jquery-hammerjs': '2.0.0', - 'cornerstone-core': '1.1.2', - 'cornerstone-tools': '1.0.3', + 'cornerstone-core': '2.0.0', + 'cornerstone-tools': '2.0.0', 'cornerstone-math': '0.1.6', 'dicom-parser': '1.7.6', - 'cornerstone-wado-image-loader': '1.0.1' + 'cornerstone-wado-image-loader': '2.0.0' }); Package.onUse(function(api) { api.versionsFrom('1.5'); api.use('ecmascript'); - api.use('jquery'); api.use('ohif:core'); api.addAssets('public/js/cornerstoneWADOImageLoaderCodecs.es5.js', 'client'); diff --git a/Packages/ohif-viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js b/Packages/ohif-viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js index c1bd6af14..e78189293 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js +++ b/Packages/ohif-viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js @@ -273,7 +273,9 @@ const loadDisplaySetIntoViewport = (data, templateData) => { // Define a function to run whenever the Cornerstone viewport is rendered // (e.g. following a change of window or zoom) - const onImageRendered = (event, eventData) => { + const onImageRendered = (event) => { + const eventData = event.detail; + // Attention: Adding OHIF.log.info in this function may decrease the performance // since this callback function is called multiple times (eg: when a tool is // enabled/disabled -> cornerstone[toolName].tool.enable) @@ -298,15 +300,17 @@ const loadDisplaySetIntoViewport = (data, templateData) => { }; // Attach the onImageRendered callback to the CornerstoneImageRendered event - $element.off('CornerstoneImageRendered', onImageRendered); - $element.on('CornerstoneImageRendered', onImageRendered); + element.removeEventListener('cornerstoneimagerendered', onImageRendered); + element.addEventListener('cornerstoneimagerendered', onImageRendered); // Set a random value for the Session variable in order to trigger an overlay update Session.set('CornerstoneImageRendered' + viewportIndex, Math.random()); // Define a function to run whenever the Cornerstone viewport changes images // (e.g. during scrolling) - const onNewImage = (event, eventData) => { + const onNewImage = (event) => { + const eventData = event.detail; + // Attention: Adding OHIF.log.info in this function may decrease the performance // since this callback function is called multiple times (eg: when a tool is // enabled/disabled -> cornerstone[toolName].tool.enable) @@ -349,13 +353,13 @@ const loadDisplaySetIntoViewport = (data, templateData) => { }; // Attach the onNewImage callback to the CornerstoneNewImage event - $element.off('CornerstoneNewImage', onNewImage); - $element.on('CornerstoneNewImage', onNewImage); + element.removeEventListener('cornerstonenewimage', onNewImage); + element.addEventListener('cornerstonenewimage', onNewImage); // Set a random value for the Session variable in order to trigger an overlay update Session.set('CornerstoneNewImage' + viewportIndex, Math.random()); - const onStackScroll = (e, eventData) => { + const onStackScroll = () => { // Attention: Adding OHIF.log.info in this function may decrease the performance // since this callback function is called multiple times (eg: when a tool is // enabled/disabled -> cornerstone[toolName].tool.enable) @@ -364,9 +368,9 @@ const loadDisplaySetIntoViewport = (data, templateData) => { Session.set('CornerstoneNewImage' + viewportIndex, Math.random()); }; - $element.off('CornerstoneStackScroll', onStackScroll); + element.removeEventListener('cornerstonestackscroll', onStackScroll); if (stack.imageIds.length > 1) { - $element.on('CornerstoneStackScroll', onStackScroll); + element.addEventListener('cornerstonestackscroll', onStackScroll); } // Define a function to trigger an event whenever a new viewport is being used @@ -578,14 +582,14 @@ Template.imageViewerViewport.onRendered(function() { setDisplaySet(data, displaySetInstanceUid, templateData); // Double click event handlers to handle viewport enlargement - this.$element.on('CornerstoneToolsMouseDoubleClick CornerstoneToolsDoubleTap', event => { + function doubleClickHandler (event) { const { layoutManager } = OHIF.viewerbase; const $viewports = $('.imageViewerViewport'); - this.$element.trigger('ohif.viewer.viewport.toggleEnlargement'); + $element.trigger('ohif.viewer.viewport.toggleEnlargement'); // Get the double clicked viewport index - const viewportIndex = $('.imageViewerViewport').index(event.currentTarget); + const viewportIndex = $viewports.index(event.currentTarget); // Stop here if there's only one viewport if (!layoutManager.isZoomed && $viewports.length <= 1) return; @@ -608,6 +612,12 @@ Template.imageViewerViewport.onRendered(function() { const element = $('.imageViewerViewport').get(viewportIndexToZoom); setActiveViewport(element); }); + } + + const doubleClickEvents = ['cornerstonetoolsmousedoubleclick', 'cornerstonetoolsdoubletap']; + doubleClickEvents.forEach(eventType => { + element.removeEventListener(eventType, doubleClickHandler); + element.addEventListener(eventType, doubleClickHandler); }); }); diff --git a/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js b/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js index f2bf54bd5..5ad98e9e0 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js +++ b/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js @@ -216,14 +216,16 @@ class StackLoadingListener extends BaseLoadingListener { _checkCachedData() { const imageIds = this.stack.imageIds; - for(let i = 0; i < imageIds.length; i++) { + // TODO: No way to check status of Promise. + /*for(let i = 0; i < imageIds.length; i++) { const imageId = imageIds[i]; + const imagePromise = cornerstone.imageCache.getImagePromise(imageId); if (imagePromise && (imagePromise.state() === 'resolved')) { this._updateFrameStatus(imageId, true); } - } + }*/ } _getImageLoadedEventName() { diff --git a/Packages/ohif-viewerbase/client/lib/classes/StudyPrefetcher.js b/Packages/ohif-viewerbase/client/lib/classes/StudyPrefetcher.js index 9a1777b76..5b3a28ce8 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/StudyPrefetcher.js +++ b/Packages/ohif-viewerbase/client/lib/classes/StudyPrefetcher.js @@ -10,16 +10,17 @@ import { getImageId } from '../getImageId.js'; export class StudyPrefetcher { constructor(studies) { - this.studies = []; + this.studies = studies || []; this.prefetchDisplaySetsTimeout = 300; this.lastActiveViewportElement = null; + this.cacheFullHandlerBound = _.bind(this.cacheFullHandler, this); - $(cornerstone.events).on('CornerstoneImageCacheFull.StudyPrefetcher', _.bind(this.cacheFullHandler, this)); + cornerstone.events.addEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound); } destroy() { this.stopPrefetching(); - $(cornerstone.events).off('CornerstoneImageCacheFull.StudyPrefetcher'); + cornerstone.events.removeEventListener('cornerstoneimagecachefull.StudyPrefetcher', this.cacheFullHandlerBound); } static getInstance() { @@ -99,19 +100,22 @@ export class StudyPrefetcher { } attachActiveViewportListeners(activeViewportElement) { - const newImageHandler = () => { + function newImageHandler() { // It needs to be called asynchronously because cornerstone does it at the same way. // All instance urls to be prefetched will be removed again if we add them before // Cornerstone callback (see stackPrefetch.onImageUpdated). - this.prefetchDisplaySetsAsync(); - }; + StudyPrefetcher.prefetchDisplaySetsAsync(); + } - $(this.lastActiveViewportElement).off('CornerstoneNewImage.StudyPrefetcher'); - $(activeViewportElement).off('CornerstoneNewImage.StudyPrefetcher'); + if (this.lastActiveViewportElement) { + this.lastActiveViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); + } + + activeViewportElement.removeEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); // Cornerstone will not attach an event listener if the element doesn't have a stack if (this.hasStack(activeViewportElement)) { - $(activeViewportElement).on('CornerstoneNewImage.StudyPrefetcher', newImageHandler); + activeViewportElement.addEventListener('cornerstonenewimage.StudyPrefetcher', newImageHandler); } this.lastActiveViewportElement = activeViewportElement; @@ -303,8 +307,8 @@ export class StudyPrefetcher { } isImageCached(imageId) { - const imagePromise = cornerstone.imageCache.getImagePromise(imageId); - return imagePromise && (imagePromise.state() === 'resolved'); + const image = cornerstone.imageCache.imageCache[imageId]; + return image && image.sizeInBytes; } cacheFullHandler() { diff --git a/Packages/ohif-viewerbase/client/lib/toolManager.js b/Packages/ohif-viewerbase/client/lib/toolManager.js index 064c139b8..0f79d174d 100644 --- a/Packages/ohif-viewerbase/client/lib/toolManager.js +++ b/Packages/ohif-viewerbase/client/lib/toolManager.js @@ -246,18 +246,23 @@ export const toolManager = { }, configureLoadProcess() { - // Whenever the CornerstoneImageLoadProgress is fired, identify which viewports + // 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. - $(cornerstone.events).on('CornerstoneImageLoadProgress', (e, eventData) => { - viewportIndices = this.getKeysByValue(window.ViewportLoading, eventData.imageId); + + 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); }, setGestures(newGestures) { diff --git a/Packages/ohif-viewerbase/client/lib/viewportUtils.js b/Packages/ohif-viewerbase/client/lib/viewportUtils.js index 2d21ece3c..cac489bec 100644 --- a/Packages/ohif-viewerbase/client/lib/viewportUtils.js +++ b/Packages/ohif-viewerbase/client/lib/viewportUtils.js @@ -360,7 +360,9 @@ const isStackScrollLinkingActive = () => { }; // Create an event listener to update playing state when a clip stops playing -$(window).on('CornerstoneToolsClipStopped', () => Session.set('UpdateCINE', Math.random())); +window.addEventListener('cornerstonetoolsclipstopped', () => { + Session.set('UpdateCINE', Math.random()); +}); /** * Export functions inside viewportUtils namespace.