From da3101be939a0515c3da2e5afe6a224a11b0ac57 Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Wed, 9 Dec 2015 15:48:24 +0100 Subject: [PATCH] Added hotkey support to viewerbase --- LesionTracker/client/components/viewer.js | 4 +- .../client/compatibility/jquery.hotkeys.js | 204 +++++++ .../basic/hidingPanel/hidingPanel.html | 0 .../basic/hidingPanel/hidingPanel.js | 0 .../basic/hidingPanel/hidingPanel.styl | 0 .../components/basic/layout/layout.html | 0 .../components/basic/layout/layout.styl | 0 .../basic/loadingText/loadingText.html | 0 .../basic/loadingText/loadingText.styl | 0 .../components/basic/login/login.html | 0 .../components/basic/notFound/notFound.html | 0 .../removableBackdrop/removableBackdrop.html | 0 .../removableBackdrop/removableBackdrop.styl | 0 .../imageThumbnail/imageThumbnail.html | 0 .../imageThumbnail/imageThumbnail.js | 0 .../imageThumbnail/imageThumbnail.styl | 0 .../studyBrowser/studyBrowser.html | 0 .../studyBrowser/studyBrowser/studyBrowser.js | 0 .../studyBrowser/studyBrowser.styl | 0 .../thumbnailEntry/thumbnailEntry.html | 0 .../thumbnailEntry/thumbnailEntry.js | 0 .../thumbnailEntry/thumbnailEntry.styl | 0 .../studyBrowser/thumbnails/thumbnails.html | 0 .../studyBrowser/thumbnails/thumbnails.js | 0 .../hangingProtocolButtons.html | 0 .../hangingProtocolButtons.js | 0 .../imageViewerViewport.html | 0 .../imageViewerViewport.js | 10 +- .../imageViewerViewport.styl | 0 .../imageViewerViewports.html | 0 .../imageViewerViewports.js | 0 .../imageViewerViewports.styl | 0 .../viewer/layoutButton/layoutButton.html | 0 .../viewer/layoutChooser/layoutChooser.html | 0 .../viewer/layoutChooser/layoutChooser.js | 0 .../viewer/layoutChooser/layoutChooser.styl | 0 .../loadingIndicator/loadingIndicator.html | 0 .../loadingIndicator/loadingIndicator.js | 0 .../loadingIndicator/loadingIndicator.styl | 0 .../viewer/playClipButton/playClipButton.html | 0 .../viewer/playClipButton/playClipButton.js | 13 +- .../simpleToolbarButton.html | 0 .../components/viewer/toolbar/toolbar.html | 0 .../components/viewer/toolbar/toolbar.js | 0 .../components/viewer/toolbar/toolbar.styl | 0 .../viewportOrientationMarkers.html | 0 .../viewportOrientationMarkers.js | 0 .../viewportOrientationMarkers.styl | 0 .../viewportOverlay/viewportOverlay.html | 0 .../viewer/viewportOverlay/viewportOverlay.js | 0 .../viewportOverlay/viewportOverlay.styl | 0 Packages/viewerbase/lib/WLPresets.js | 21 + Packages/viewerbase/lib/enableHotkeys.js | 574 ++++++++++++++++++ Packages/viewerbase/lib/setActiveViewport.js | 20 + .../viewerbase/lib/switchToImageByIndex.js | 13 + .../viewerbase/lib/switchToImageRelative.js | 13 + Packages/viewerbase/lib/toolManager.js | 17 +- Packages/viewerbase/lib/viewportFunctions.js | 68 +++ Packages/viewerbase/package.js | 116 ++-- 59 files changed, 1002 insertions(+), 71 deletions(-) create mode 100644 Packages/viewerbase/client/compatibility/jquery.hotkeys.js rename Packages/viewerbase/{ => client}/components/basic/hidingPanel/hidingPanel.html (100%) rename Packages/viewerbase/{ => client}/components/basic/hidingPanel/hidingPanel.js (100%) rename Packages/viewerbase/{ => client}/components/basic/hidingPanel/hidingPanel.styl (100%) rename Packages/viewerbase/{ => client}/components/basic/layout/layout.html (100%) rename Packages/viewerbase/{ => client}/components/basic/layout/layout.styl (100%) rename Packages/viewerbase/{ => client}/components/basic/loadingText/loadingText.html (100%) rename Packages/viewerbase/{ => client}/components/basic/loadingText/loadingText.styl (100%) rename Packages/viewerbase/{ => client}/components/basic/login/login.html (100%) rename Packages/viewerbase/{ => client}/components/basic/notFound/notFound.html (100%) rename Packages/viewerbase/{ => client}/components/basic/removableBackdrop/removableBackdrop.html (100%) rename Packages/viewerbase/{ => client}/components/basic/removableBackdrop/removableBackdrop.styl (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/imageThumbnail/imageThumbnail.html (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/imageThumbnail/imageThumbnail.js (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/imageThumbnail/imageThumbnail.styl (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/studyBrowser/studyBrowser.html (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/studyBrowser/studyBrowser.js (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/studyBrowser/studyBrowser.styl (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/thumbnailEntry/thumbnailEntry.html (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/thumbnailEntry/thumbnailEntry.js (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/thumbnails/thumbnails.html (100%) rename Packages/viewerbase/{ => client}/components/studyBrowser/thumbnails/thumbnails.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewport/imageViewerViewport.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewport/imageViewerViewport.js (98%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewport/imageViewerViewport.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewports/imageViewerViewports.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewports/imageViewerViewports.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/imageViewerViewports/imageViewerViewports.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/layoutButton/layoutButton.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/layoutChooser/layoutChooser.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/layoutChooser/layoutChooser.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/layoutChooser/layoutChooser.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/loadingIndicator/loadingIndicator.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/loadingIndicator/loadingIndicator.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/loadingIndicator/loadingIndicator.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/playClipButton/playClipButton.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/playClipButton/playClipButton.js (83%) rename Packages/viewerbase/{ => client}/components/viewer/simpleToolbarButton/simpleToolbarButton.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/toolbar/toolbar.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/toolbar/toolbar.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/toolbar/toolbar.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOverlay/viewportOverlay.html (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOverlay/viewportOverlay.js (100%) rename Packages/viewerbase/{ => client}/components/viewer/viewportOverlay/viewportOverlay.styl (100%) create mode 100644 Packages/viewerbase/lib/WLPresets.js create mode 100644 Packages/viewerbase/lib/enableHotkeys.js create mode 100644 Packages/viewerbase/lib/setActiveViewport.js create mode 100644 Packages/viewerbase/lib/switchToImageByIndex.js create mode 100644 Packages/viewerbase/lib/switchToImageRelative.js create mode 100644 Packages/viewerbase/lib/viewportFunctions.js diff --git a/LesionTracker/client/components/viewer.js b/LesionTracker/client/components/viewer.js index 43b4d63b7..0a25fdb9c 100644 --- a/LesionTracker/client/components/viewer.js +++ b/LesionTracker/client/components/viewer.js @@ -17,13 +17,15 @@ function resizeViewports() { } Template.viewer.onCreated(function() { + enableHotkeys(); + var self = this; var firstMeasurementsActivated = false; log.info("viewer onCreated"); - OHIF = { + OHIF = OHIF || { viewer: {} }; diff --git a/Packages/viewerbase/client/compatibility/jquery.hotkeys.js b/Packages/viewerbase/client/compatibility/jquery.hotkeys.js new file mode 100644 index 000000000..b791f4529 --- /dev/null +++ b/Packages/viewerbase/client/compatibility/jquery.hotkeys.js @@ -0,0 +1,204 @@ +/*jslint browser: true*/ +/*jslint jquery: true*/ + +/* + * jQuery Hotkeys Plugin + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Based upon the plugin by Tzury Bar Yochay: + * https://github.com/tzuryby/jquery.hotkeys + * + * Original idea by: + * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ + */ + +/* + * One small change is: now keys are passed by object { keys: '...' } + * Might be useful, when you want to pass some other data to your handler + */ + +(function(jQuery) { + + jQuery.hotkeys = { + version: "0.8", + + specialKeys: { + 8: "backspace", + 9: "tab", + 10: "return", + 13: "return", + 16: "shift", + 17: "ctrl", + 18: "alt", + 19: "pause", + 20: "capslock", + 27: "esc", + 32: "space", + 33: "pageup", + 34: "pagedown", + 35: "end", + 36: "home", + 37: "left", + 38: "up", + 39: "right", + 40: "down", + 45: "insert", + 46: "del", + 59: ";", + 61: "=", + 96: "0", + 97: "1", + 98: "2", + 99: "3", + 100: "4", + 101: "5", + 102: "6", + 103: "7", + 104: "8", + 105: "9", + 106: "*", + 107: "+", + 109: "-", + 110: ".", + 111: "/", + 112: "f1", + 113: "f2", + 114: "f3", + 115: "f4", + 116: "f5", + 117: "f6", + 118: "f7", + 119: "f8", + 120: "f9", + 121: "f10", + 122: "f11", + 123: "f12", + 144: "numlock", + 145: "scroll", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'" + }, + + shiftNums: { + "`": "~", + "1": "!", + "2": "@", + "3": "#", + "4": "$", + "5": "%", + "6": "^", + "7": "&", + "8": "*", + "9": "(", + "0": ")", + "-": "_", + "=": "+", + ";": ": ", + "'": "\"", + ",": "<", + ".": ">", + "/": "?", + "\\": "|" + }, + + // excludes: button, checkbox, file, hidden, image, password, radio, reset, search, submit, url + textAcceptingInputTypes: [ + "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", + "datetime-local", "search", "color", "tel"], + + // default input types not to bind to unless bound directly + textInputTypes: /textarea|input|select/i, + + options: { + filterInputAcceptingElements: true, + filterTextInputs: true, + filterContentEditable: true + } + }; + + function keyHandler(handleObj) { + if (typeof handleObj.data === "string") { + handleObj.data = { + keys: handleObj.data + }; + } + + // Only care when a possible input has been specified + if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string") { + return; + } + + var origHandler = handleObj.handler, + keys = handleObj.data.keys.toLowerCase().split(" "); + + handleObj.handler = function(event) { + // Don't fire in text-accepting inputs that we didn't directly bind to + if (this !== event.target && + (jQuery.hotkeys.options.filterInputAcceptingElements && + jQuery.hotkeys.textInputTypes.test(event.target.nodeName) || + (jQuery.hotkeys.options.filterContentEditable && jQuery(event.target).attr('contenteditable')) || + (jQuery.hotkeys.options.filterTextInputs && + jQuery.inArray(event.target.type, jQuery.hotkeys.textAcceptingInputTypes) > -1))) { + return; + } + + var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which], + character = String.fromCharCode(event.which).toLowerCase(), + modif = "", + possible = {}; + + jQuery.each(["alt", "ctrl", "shift"], function(index, specialKey) { + + if (event[specialKey + 'Key'] && special !== specialKey) { + modif += specialKey + '+'; + } + }); + + // metaKey is triggered off ctrlKey erronously + if (event.metaKey && !event.ctrlKey && special !== "meta") { + modif += "meta+"; + } + + if (event.metaKey && special !== "meta" && modif.indexOf("alt+ctrl+shift+") > -1) { + modif = modif.replace("alt+ctrl+shift+", "hyper+"); + } + + if (special) { + possible[modif + special] = true; + } + else { + possible[modif + character] = true; + possible[modif + jQuery.hotkeys.shiftNums[character]] = true; + + // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" + if (modif === "shift+") { + possible[jQuery.hotkeys.shiftNums[character]] = true; + } + } + + for (var i = 0, l = keys.length; i < l; i++) { + if (possible[keys[i]]) { + return origHandler.apply(this, arguments); + } + } + }; + } + + jQuery.each(["keydown", "keyup", "keypress"], function() { + jQuery.event.special[this] = { + add: keyHandler + }; + }); + +})(jQuery || this.jQuery || window.jQuery); \ No newline at end of file diff --git a/Packages/viewerbase/components/basic/hidingPanel/hidingPanel.html b/Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.html similarity index 100% rename from Packages/viewerbase/components/basic/hidingPanel/hidingPanel.html rename to Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.html diff --git a/Packages/viewerbase/components/basic/hidingPanel/hidingPanel.js b/Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.js similarity index 100% rename from Packages/viewerbase/components/basic/hidingPanel/hidingPanel.js rename to Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.js diff --git a/Packages/viewerbase/components/basic/hidingPanel/hidingPanel.styl b/Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.styl similarity index 100% rename from Packages/viewerbase/components/basic/hidingPanel/hidingPanel.styl rename to Packages/viewerbase/client/components/basic/hidingPanel/hidingPanel.styl diff --git a/Packages/viewerbase/components/basic/layout/layout.html b/Packages/viewerbase/client/components/basic/layout/layout.html similarity index 100% rename from Packages/viewerbase/components/basic/layout/layout.html rename to Packages/viewerbase/client/components/basic/layout/layout.html diff --git a/Packages/viewerbase/components/basic/layout/layout.styl b/Packages/viewerbase/client/components/basic/layout/layout.styl similarity index 100% rename from Packages/viewerbase/components/basic/layout/layout.styl rename to Packages/viewerbase/client/components/basic/layout/layout.styl diff --git a/Packages/viewerbase/components/basic/loadingText/loadingText.html b/Packages/viewerbase/client/components/basic/loadingText/loadingText.html similarity index 100% rename from Packages/viewerbase/components/basic/loadingText/loadingText.html rename to Packages/viewerbase/client/components/basic/loadingText/loadingText.html diff --git a/Packages/viewerbase/components/basic/loadingText/loadingText.styl b/Packages/viewerbase/client/components/basic/loadingText/loadingText.styl similarity index 100% rename from Packages/viewerbase/components/basic/loadingText/loadingText.styl rename to Packages/viewerbase/client/components/basic/loadingText/loadingText.styl diff --git a/Packages/viewerbase/components/basic/login/login.html b/Packages/viewerbase/client/components/basic/login/login.html similarity index 100% rename from Packages/viewerbase/components/basic/login/login.html rename to Packages/viewerbase/client/components/basic/login/login.html diff --git a/Packages/viewerbase/components/basic/notFound/notFound.html b/Packages/viewerbase/client/components/basic/notFound/notFound.html similarity index 100% rename from Packages/viewerbase/components/basic/notFound/notFound.html rename to Packages/viewerbase/client/components/basic/notFound/notFound.html diff --git a/Packages/viewerbase/components/basic/removableBackdrop/removableBackdrop.html b/Packages/viewerbase/client/components/basic/removableBackdrop/removableBackdrop.html similarity index 100% rename from Packages/viewerbase/components/basic/removableBackdrop/removableBackdrop.html rename to Packages/viewerbase/client/components/basic/removableBackdrop/removableBackdrop.html diff --git a/Packages/viewerbase/components/basic/removableBackdrop/removableBackdrop.styl b/Packages/viewerbase/client/components/basic/removableBackdrop/removableBackdrop.styl similarity index 100% rename from Packages/viewerbase/components/basic/removableBackdrop/removableBackdrop.styl rename to Packages/viewerbase/client/components/basic/removableBackdrop/removableBackdrop.styl diff --git a/Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.html b/Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.html similarity index 100% rename from Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.html rename to Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.html diff --git a/Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.js b/Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.js similarity index 100% rename from Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.js rename to Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.js diff --git a/Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.styl b/Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.styl similarity index 100% rename from Packages/viewerbase/components/studyBrowser/imageThumbnail/imageThumbnail.styl rename to Packages/viewerbase/client/components/studyBrowser/imageThumbnail/imageThumbnail.styl diff --git a/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.html b/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html similarity index 100% rename from Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.html rename to Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html diff --git a/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js b/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.js similarity index 100% rename from Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js rename to Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.js diff --git a/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.styl b/Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.styl similarity index 100% rename from Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.styl rename to Packages/viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.styl diff --git a/Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.html b/Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.html similarity index 100% rename from Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.html rename to Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.html diff --git a/Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.js b/Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js similarity index 100% rename from Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.js rename to Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js diff --git a/Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl b/Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl similarity index 100% rename from Packages/viewerbase/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl rename to Packages/viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl diff --git a/Packages/viewerbase/components/studyBrowser/thumbnails/thumbnails.html b/Packages/viewerbase/client/components/studyBrowser/thumbnails/thumbnails.html similarity index 100% rename from Packages/viewerbase/components/studyBrowser/thumbnails/thumbnails.html rename to Packages/viewerbase/client/components/studyBrowser/thumbnails/thumbnails.html diff --git a/Packages/viewerbase/components/studyBrowser/thumbnails/thumbnails.js b/Packages/viewerbase/client/components/studyBrowser/thumbnails/thumbnails.js similarity index 100% rename from Packages/viewerbase/components/studyBrowser/thumbnails/thumbnails.js rename to Packages/viewerbase/client/components/studyBrowser/thumbnails/thumbnails.js diff --git a/Packages/viewerbase/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html b/Packages/viewerbase/client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html similarity index 100% rename from Packages/viewerbase/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html rename to Packages/viewerbase/client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html diff --git a/Packages/viewerbase/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js b/Packages/viewerbase/client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js similarity index 100% rename from Packages/viewerbase/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js rename to Packages/viewerbase/client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js diff --git a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.html b/Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.html similarity index 100% rename from Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.html rename to Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.html diff --git a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js b/Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js similarity index 98% rename from Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js rename to Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js index 79473065b..7c1ad0f42 100644 --- a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js +++ b/Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.js @@ -154,7 +154,7 @@ function loadSeriesIntoViewport(data, templateData) { // Use the tool manager to enable the currently active tool for this // newly rendered element var activeTool = toolManager.getActiveTool(); - toolManager.setActiveTool(activeTool, element); + toolManager.setActiveTool(activeTool, [element]); // Define a function to run whenever the Cornerstone viewport is rendered // (e.g. following a change of window or zoom) @@ -527,14 +527,6 @@ Template.imageViewerViewport.onDestroyed(function() { Template.imageViewerViewport.events({ 'ActivateViewport .imageViewerViewport': function(e) { log.info("imageViewerViewport ActivateViewport"); - - // When an ActivateViewport event is fired, update the Meteor Session - // with the viewport index that it was fired from. - Session.set("activeViewport", e.viewportIndex); - - // Add the 'active' class to the parent container to highlight the active viewport - $('#imageViewerViewports .viewportContainer').removeClass('active'); - setActiveViewport(e.currentTarget); } }); \ No newline at end of file diff --git a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.styl b/Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.styl similarity index 100% rename from Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.styl rename to Packages/viewerbase/client/components/viewer/imageViewerViewport/imageViewerViewport.styl diff --git a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html b/Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.html similarity index 100% rename from Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html rename to Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.html diff --git a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js b/Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.js similarity index 100% rename from Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js rename to Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.js diff --git a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.styl b/Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.styl similarity index 100% rename from Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.styl rename to Packages/viewerbase/client/components/viewer/imageViewerViewports/imageViewerViewports.styl diff --git a/Packages/viewerbase/components/viewer/layoutButton/layoutButton.html b/Packages/viewerbase/client/components/viewer/layoutButton/layoutButton.html similarity index 100% rename from Packages/viewerbase/components/viewer/layoutButton/layoutButton.html rename to Packages/viewerbase/client/components/viewer/layoutButton/layoutButton.html diff --git a/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.html b/Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.html similarity index 100% rename from Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.html rename to Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.html diff --git a/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js b/Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.js similarity index 100% rename from Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js rename to Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.js diff --git a/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.styl b/Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.styl similarity index 100% rename from Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.styl rename to Packages/viewerbase/client/components/viewer/layoutChooser/layoutChooser.styl diff --git a/Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.html b/Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.html similarity index 100% rename from Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.html rename to Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.html diff --git a/Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.js b/Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.js similarity index 100% rename from Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.js rename to Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.js diff --git a/Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.styl b/Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.styl similarity index 100% rename from Packages/viewerbase/components/viewer/loadingIndicator/loadingIndicator.styl rename to Packages/viewerbase/client/components/viewer/loadingIndicator/loadingIndicator.styl diff --git a/Packages/viewerbase/components/viewer/playClipButton/playClipButton.html b/Packages/viewerbase/client/components/viewer/playClipButton/playClipButton.html similarity index 100% rename from Packages/viewerbase/components/viewer/playClipButton/playClipButton.html rename to Packages/viewerbase/client/components/viewer/playClipButton/playClipButton.html diff --git a/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js b/Packages/viewerbase/client/components/viewer/playClipButton/playClipButton.js similarity index 83% rename from Packages/viewerbase/components/viewer/playClipButton/playClipButton.js rename to Packages/viewerbase/client/components/viewer/playClipButton/playClipButton.js index ff931bca1..a17ce1423 100644 --- a/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js +++ b/Packages/viewerbase/client/components/viewer/playClipButton/playClipButton.js @@ -1,4 +1,13 @@ toggleCinePlay = function(element) { + if (!element) { + var activeViewport = Session.get('activeViewport'); + element = $('.imageViewerViewport').get(activeViewport); + } + + if (!element) { + return; + } + var viewportIndex = $('.imageViewerViewport').index(element); var isPlaying = OHIF.viewer.isPlaying[viewportIndex] || false; if (isPlaying === true) { @@ -20,8 +29,6 @@ Template.playClipButton.helpers({ Template.playClipButton.events({ 'click #playClip': function() { - var activeViewport = Session.get('activeViewport'); - var element = $('.imageViewerViewport').get(activeViewport); - toggleCinePlay(element); + toggleCinePlay(); } }); \ No newline at end of file diff --git a/Packages/viewerbase/components/viewer/simpleToolbarButton/simpleToolbarButton.html b/Packages/viewerbase/client/components/viewer/simpleToolbarButton/simpleToolbarButton.html similarity index 100% rename from Packages/viewerbase/components/viewer/simpleToolbarButton/simpleToolbarButton.html rename to Packages/viewerbase/client/components/viewer/simpleToolbarButton/simpleToolbarButton.html diff --git a/Packages/viewerbase/components/viewer/toolbar/toolbar.html b/Packages/viewerbase/client/components/viewer/toolbar/toolbar.html similarity index 100% rename from Packages/viewerbase/components/viewer/toolbar/toolbar.html rename to Packages/viewerbase/client/components/viewer/toolbar/toolbar.html diff --git a/Packages/viewerbase/components/viewer/toolbar/toolbar.js b/Packages/viewerbase/client/components/viewer/toolbar/toolbar.js similarity index 100% rename from Packages/viewerbase/components/viewer/toolbar/toolbar.js rename to Packages/viewerbase/client/components/viewer/toolbar/toolbar.js diff --git a/Packages/viewerbase/components/viewer/toolbar/toolbar.styl b/Packages/viewerbase/client/components/viewer/toolbar/toolbar.styl similarity index 100% rename from Packages/viewerbase/components/viewer/toolbar/toolbar.styl rename to Packages/viewerbase/client/components/viewer/toolbar/toolbar.styl diff --git a/Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html b/Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html rename to Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html diff --git a/Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js b/Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js rename to Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js diff --git a/Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl b/Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl rename to Packages/viewerbase/client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl diff --git a/Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.html b/Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.html similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.html rename to Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.html diff --git a/Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.js b/Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.js similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.js rename to Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.js diff --git a/Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.styl b/Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.styl similarity index 100% rename from Packages/viewerbase/components/viewer/viewportOverlay/viewportOverlay.styl rename to Packages/viewerbase/client/components/viewer/viewportOverlay/viewportOverlay.styl diff --git a/Packages/viewerbase/lib/WLPresets.js b/Packages/viewerbase/lib/WLPresets.js new file mode 100644 index 000000000..da3a49af8 --- /dev/null +++ b/Packages/viewerbase/lib/WLPresets.js @@ -0,0 +1,21 @@ +applyWLPreset = function(presetName, element) { + var viewport = cornerstone.getViewport(element); + + if (presetName === 'Default') { + var enabledElement = cornerstone.getEnabledElement(element); + viewport.voi.windowWidth = enabledElement.image.windowWidth; + viewport.voi.windowCenter = enabledElement.image.windowCenter; + } else { + var preset = OHIF.viewer.wlPresets[presetName]; + viewport.voi.windowWidth = preset.ww; + viewport.voi.windowCenter = preset.wc; + } + + // Update the viewport + cornerstone.setViewport(element, viewport); +}; + +applyWLPresetToActiveElement = function(presetName) { + var element = getActiveViewportElement(); + applyWLPreset(presetName, element); +}; diff --git a/Packages/viewerbase/lib/enableHotkeys.js b/Packages/viewerbase/lib/enableHotkeys.js new file mode 100644 index 000000000..7584dc063 --- /dev/null +++ b/Packages/viewerbase/lib/enableHotkeys.js @@ -0,0 +1,574 @@ +OHIF = window.OHIF || {}; + +Meteor.startup(function() { + + if (!OHIF.viewer) { + OHIF.viewer = {}; + } + + OHIF.viewer.defaultHotkeys = { + defaultTool: "ESC", + angle: "A", + stackScroll: "S", + wwwcRegion: "R", + pan: "P", + magnify: "M", + length: "L", + scrollDown: "DOWN", + scrollUp: "UP", + nextPanel: "RIGHT", + previousPanel: "LEFT", + invert: "I", + flipV: "V", + flipH: "H", + wwwc: "W", + annotate: "T", + cineDialog: "C", + cinePlay: "SPACE", + rotateR: "F", + rotateL: "G", + toggleTools: 'TAB', + toggleOverlayTags: 'SHIFT', + WLPresetABD: ["NUMPAD1", "1"], + WLPresetBone: ["NUMPAD2", "2"], + WLPresetBrain: ["NUMPAD3", "3"], + WLPresetLiver: ["NUMPAD4", "4"], + WLPresetLung: ["NUMPAD5", "5"], + WLPresetMediastinum: ["NUMPAD6", "6"], + WLPresetMRSoftTissue: ["NUMPAD7", "7"], + WLPresetMRSpine: ["NUMPAD8", "8"], + WLPresetSubdural: ["NUMPAD9", "9"] + }; + + // For now + OHIF.viewer.hotkeys = OHIF.viewer.defaultHotkeys; + + OHIF.viewer.defaultWLPresets = { + 'ABD' : {wc : 40, ww : 400}, + 'Bone' : {wc: 450, ww : 1800}, + 'Brain' : {wc : 36, ww : 90}, + 'Liver' : {wc : 40, ww : 250}, + 'Lung' : {wc : -400, ww : 1600}, + 'Mediastinum' : {wc : 50, ww : 450}, + 'MRSoftTissue' : {wc : 600, ww : 1200}, + 'MRSpine' : {wc : 400, ww : 600}, + 'Subdural' : {wc : 75, ww : 150} + }; + + // For now + OHIF.viewer.wlPresets = OHIF.viewer.defaultWLPresets; + + OHIF.viewer.globals = {}; + OHIF.viewer.globals.keyboardMap = [ + "", // [0] + "", // [1] + "", // [2] + "CANCEL", // [3] + "", // [4] + "", // [5] + "HELP", // [6] + "", // [7] + "BACK_SPACE", // [8] + "TAB", // [9] + "", // [10] + "", // [11] + "CLEAR", // [12] + "ENTER", // [13] + "ENTER_SPECIAL", // [14] + "", // [15] + "SHIFT", // [16] + "CONTROL", // [17] + "ALT", // [18] + "PAUSE", // [19] + "CAPS_LOCK", // [20] + "KANA", // [21] + "EISU", // [22] + "JUNJA", // [23] + "FINAL", // [24] + "HANJA", // [25] + "", // [26] + "ESCAPE", // [27] + "CONVERT", // [28] + "NONCONVERT", // [29] + "ACCEPT", // [30] + "MODECHANGE", // [31] + "SPACE", // [32] + "PAGE_UP", // [33] + "PAGE_DOWN", // [34] + "END", // [35] + "HOME", // [36] + "LEFT", // [37] + "UP", // [38] + "RIGHT", // [39] + "DOWN", // [40] + "SELECT", // [41] + "PRINT", // [42] + "EXECUTE", // [43] + "PRINTSCREEN", // [44] + "INSERT", // [45] + "DELETE", // [46] + "", // [47] + "0", // [48] + "1", // [49] + "2", // [50] + "3", // [51] + "4", // [52] + "5", // [53] + "6", // [54] + "7", // [55] + "8", // [56] + "9", // [57] + "COLON", // [58] + "SEMICOLON", // [59] + "LESS_THAN", // [60] + "EQUALS", // [61] + "GREATER_THAN", // [62] + "QUESTION_MARK", // [63] + "AT", // [64] + "A", // [65] + "B", // [66] + "C", // [67] + "D", // [68] + "E", // [69] + "F", // [70] + "G", // [71] + "H", // [72] + "I", // [73] + "J", // [74] + "K", // [75] + "L", // [76] + "M", // [77] + "N", // [78] + "O", // [79] + "P", // [80] + "Q", // [81] + "R", // [82] + "S", // [83] + "T", // [84] + "U", // [85] + "V", // [86] + "W", // [87] + "X", // [88] + "Y", // [89] + "Z", // [90] + "WIN", // [91] + "", // [92] + "CONTEXT_MENU", // [93] + "", // [94] + "SLEEP", // [95] + "NUMPAD0", // [96] + "NUMPAD1", // [97] + "NUMPAD2", // [98] + "NUMPAD3", // [99] + "NUMPAD4", // [100] + "NUMPAD5", // [101] + "NUMPAD6", // [102] + "NUMPAD7", // [103] + "NUMPAD8", // [104] + "NUMPAD9", // [105] + "MULTIPLY", // [106] + "ADD", // [107] + "SEPARATOR", // [108] + "SUBTRACT", // [109] + "DECIMAL", // [110] + "DIVIDE", // [111] + "F1", // [112] + "F2", // [113] + "F3", // [114] + "F4", // [115] + "F5", // [116] + "F6", // [117] + "F7", // [118] + "F8", // [119] + "F9", // [120] + "F10", // [121] + "F11", // [122] + "F12", // [123] + "F13", // [124] + "F14", // [125] + "F15", // [126] + "F16", // [127] + "F17", // [128] + "F18", // [129] + "F19", // [130] + "F20", // [131] + "F21", // [132] + "F22", // [133] + "F23", // [134] + "F24", // [135] + "", // [136] + "", // [137] + "", // [138] + "", // [139] + "", // [140] + "", // [141] + "", // [142] + "", // [143] + "NUM_LOCK", // [144] + "SCROLL_LOCK", // [145] + "WIN_OEM_FJ_JISHO", // [146] + "WIN_OEM_FJ_MASSHOU", // [147] + "WIN_OEM_FJ_TOUROKU", // [148] + "WIN_OEM_FJ_LOYA", // [149] + "WIN_OEM_FJ_ROYA", // [150] + "", // [151] + "", // [152] + "", // [153] + "", // [154] + "", // [155] + "", // [156] + "", // [157] + "", // [158] + "", // [159] + "CIRCUMFLEX", // [160] + "EXCLAMATION", // [161] + "DOUBLE_QUOTE", // [162] + "HASH", // [163] + "DOLLAR", // [164] + "PERCENT", // [165] + "AMPERSAND", // [166] + "UNDERSCORE", // [167] + "OPEN_PAREN", // [168] + "CLOSE_PAREN", // [169] + "ASTERISK", // [170] + "PLUS", // [171] + "PIPE", // [172] + "HYPHEN_MINUS", // [173] + "OPEN_CURLY_BRACKET", // [174] + "CLOSE_CURLY_BRACKET", // [175] + "TILDE", // [176] + "", // [177] + "", // [178] + "", // [179] + "", // [180] + "VOLUME_MUTE", // [181] + "VOLUME_DOWN", // [182] + "VOLUME_UP", // [183] + "", // [184] + "", // [185] + "SEMICOLON", // [186] + "EQUALS", // [187] + "COMMA", // [188] + "MINUS", // [189] + "PERIOD", // [190] + "SLASH", // [191] + "BACK_QUOTE", // [192] + "", // [193] + "", // [194] + "", // [195] + "", // [196] + "", // [197] + "", // [198] + "", // [199] + "", // [200] + "", // [201] + "", // [202] + "", // [203] + "", // [204] + "", // [205] + "", // [206] + "", // [207] + "", // [208] + "", // [209] + "", // [210] + "", // [211] + "", // [212] + "", // [213] + "", // [214] + "", // [215] + "", // [216] + "", // [217] + "", // [218] + "OPEN_BRACKET", // [219] + "BACK_SLASH", // [220] + "CLOSE_BRACKET", // [221] + "QUOTE", // [222] + "", // [223] + "META", // [224] + "ALTGR", // [225] + "", // [226] + "WIN_ICO_HELP", // [227] + "WIN_ICO_00", // [228] + "", // [229] + "WIN_ICO_CLEAR", // [230] + "", // [231] + "", // [232] + "WIN_OEM_RESET", // [233] + "WIN_OEM_JUMP", // [234] + "WIN_OEM_PA1", // [235] + "WIN_OEM_PA2", // [236] + "WIN_OEM_PA3", // [237] + "WIN_OEM_WSCTRL", // [238] + "WIN_OEM_CUSEL", // [239] + "WIN_OEM_ATTN", // [240] + "WIN_OEM_FINISH", // [241] + "WIN_OEM_COPY", // [242] + "WIN_OEM_AUTO", // [243] + "WIN_OEM_ENLW", // [244] + "WIN_OEM_BACKTAB", // [245] + "ATTN", // [246] + "CRSEL", // [247] + "EXSEL", // [248] + "EREOF", // [249] + "PLAY", // [250] + "ZOOM", // [251] + "", // [252] + "PA1", // [253] + "WIN_OEM_CLEAR", // [254] + "" // [255] + ]; + + OHIF.viewer.hotkeyFunctions = { + wwwc: function() { + toolManager.setActiveTool("wwwc"); + }, + angle: function() { + toolManager.setActiveTool("angle"); + }, + dragProbe: function() { + toolManager.setActiveTool("dragProbe"); + }, + ellipticalRoi: function() { + toolManager.setActiveTool("ellipticalRoi"); + }, + magnify: function() { + toolManager.setActiveTool("magnify"); + }, + annotate: function() { + toolManager.setActiveTool("annotate"); + }, + stackScroll: function() { + toolManager.setActiveTool("stackScroll"); + }, + pan: function() { + toolManager.setActiveTool("pan"); + }, + length: function() { + toolManager.setActiveTool("length"); + }, + spine: function() { + toolManager.setActiveTool("spine"); + }, + wwwcRegion: function() { + toolManager.setActiveTool("wwwcRegion"); + }, + zoomIn: function () { + var button = document.getElementById("zoomIn"); + flashButton(button); + zoomIn(); + }, + zoomOut: function () { + var button = document.getElementById("zoomOut"); + flashButton(button); + zoomOut(); + }, + zoomToFit: function () { + var button = document.getElementById("zoomToFit"); + flashButton(button); + zoomToFit(); + }, + scrollDown: function() { + var container = $('.viewportContainer.active'); + var button = container.find('#nextImage').get(0); + + if (!container.find('.imageViewerViewport').hasClass('empty')) { + flashButton(button); + switchToImageRelative(1); + } + }, + scrollFirstImage: function() { + var container = $('.viewportContainer.active'); + if (!container.find('.imageViewerViewport').hasClass('empty')) { + switchToImageByIndex(0); + } + }, + scrollLastImage: function() { + var container = $('.viewportContainer.active'); + if (!container.find('.imageViewerViewport').hasClass('empty')) { + switchToImageByIndex(-1); + } + }, + scrollUp: function() { + var container = $('.viewportContainer.active'); + if (!container.find('.imageViewerViewport').hasClass('empty')) { + var button = container.find('#prevImage').get(0); + flashButton(button); + switchToImageRelative(-1); + } + }, + nextPanel: function() { + nextActivePanel(); + }, + previousPanel: function() { + previousActivePanel(); + }, + invert: function() { + var button = document.getElementById("invert"); + flashButton(button); + invert(); + }, + flipV: function() { + var button = document.getElementById("flipV"); + flashButton(button); + flipV(); + }, + flipH: function() { + var button = document.getElementById("flipH"); + flashButton(button); + flipH(); + }, + rotateR: function() { + var button = document.getElementById("rotateR"); + flashButton(button); + rotateR(); + }, + rotateL: function() { + var button = document.getElementById("rotateL"); + flashButton(button); + rotateL(); + }, + cinePlay: function() { + toggleCinePlay(); + }, + defaultTool: function() { + var tool = toolManager.getDefaultTool(); + toolManager.setActiveTool(tool); + }, + toggleTools: function() { + //TODO= Write this function in toolManager? + console.log("Show/hide all tools"); + }, + toggleOverlayTags: function() { + var dicomTags = $('.imageViewerViewportOverlay .dicomTag'); + if (dicomTags.eq(0).css('display') === 'none') { + dicomTags.show(); + } else { + dicomTags.hide(); + } + } + }; +}); + +// Define a jQuery reverse function +$.fn.reverse = [].reverse; + +function previousActivePanel() { + log.info('nextActivePanel'); + var currentIndex = Session.get('activeViewport'); + currentIndex--; + + var viewports = $('.imageViewerViewport'); + var numViewports = viewports.length; + if (currentIndex < 0) { + currentIndex = numViewports - 1; + } + + var element = viewports.get(currentIndex); + if (!element) { + return; + } + + setActiveViewport(element); +} + + +function nextActivePanel() { + log.info('nextActivePanel'); + var currentIndex = Session.get('activeViewport'); + currentIndex++; + + var viewports = $('.imageViewerViewport'); + var numViewports = viewports.length; + if (currentIndex >= numViewports) { + currentIndex = 0; + } + + var element = viewports.get(currentIndex); + if (!element) { + return; + } + + setActiveViewport(element); +} + +function flashButton(button) { + if (!button) { + return; + } + + button.classList.add('active'); + setTimeout(function () { + button.classList.remove('active'); + }, 100); +} + +function setActiveViewportContainer(container) { + if (!container) { + return; + } + + var container = $(container); + container.addClass('active'); + + var element = container.find(".imageViewerViewport").get(0); + if (!element) { + return; + } + + var viewportIndex = $('.imageViewerViewport').index(element); + Session.set + + // Finally, enable stack prefetching and hide the reference lines from + // the newly activated viewport + enablePrefetchOnElement(element); + displayReferenceLines(element); +} + +function bindHotkey(hotkey, task) { + var hotkeyFunctions = OHIF.viewer.hotkeyFunctions; + + // Only bind defined, non-empty HotKeys + if (!hotkey || hotkey === "") { + return; + } + + var fn; + if (task.indexOf("WLPreset") > -1) { + var presetName = task.replace("WLPreset", ""); + fn = function() { + applyWLPresetToActiveElement(presetName); + }; + } else { + fn = hotkeyFunctions[task]; + } + + if (!fn) { + return; + } + + var hotKeyForBinding = hotkey.toLowerCase(); + + $(document).bind('keydown', hotKeyForBinding, fn); +} + +enableHotkeys = function() { + var viewerHotkeys = OHIF.viewer.hotkeys; + + $(document).unbind('keydown'); + + Object.keys(viewerHotkeys).forEach(function(task) { + var taskHotkeys = viewerHotkeys[task]; + if (!taskHotkeys || !taskHotkeys.length) { + return; + } + + if (taskHotkeys.constructor === Array) { + taskHotkeys.forEach(function(hotkey) { + bindHotkey(hotkey, task); + }); + } else { + // taskHotkeys represents a single key + bindHotkey(taskHotkeys, task); + } + }); +}; \ No newline at end of file diff --git a/Packages/viewerbase/lib/setActiveViewport.js b/Packages/viewerbase/lib/setActiveViewport.js new file mode 100644 index 000000000..eec71c761 --- /dev/null +++ b/Packages/viewerbase/lib/setActiveViewport.js @@ -0,0 +1,20 @@ +setActiveViewport = function(element) { + if (!element) { + return; + } + + var viewportIndex = $('.imageViewerViewport').index(element); + + // When an ActivateViewport event is fired, update the Meteor Session + // with the viewport index that it was fired from. + Session.set("activeViewport", viewportIndex); + + // Add the 'active' class to the parent container to highlight the active viewport + $('#imageViewerViewports .viewportContainer').removeClass('active'); + $(element).parents('.viewportContainer').addClass('active'); + + // Finally, enable stack prefetching and hide the reference lines from + // the newly activated viewport + enablePrefetchOnElement(element); + displayReferenceLines(element); +}; \ No newline at end of file diff --git a/Packages/viewerbase/lib/switchToImageByIndex.js b/Packages/viewerbase/lib/switchToImageByIndex.js new file mode 100644 index 000000000..4ecd232b3 --- /dev/null +++ b/Packages/viewerbase/lib/switchToImageByIndex.js @@ -0,0 +1,13 @@ +/** + * This function switches to an image given an element and the index of the image in the current stack + * Note: Negative indexing is supported: + * + * e.g. switchToImageByIndex(element, -1) to switch to the last image of the stack + * + * @param element + * @param {number} [newImageIdIndex] The image index in the stack to switch to. + */ +switchToImageByIndex = function(newImageIdIndex) { + var element = getActiveViewportElement(); + cornerstoneTools.scrollToIndex(element, newImageIdIndex); +}; diff --git a/Packages/viewerbase/lib/switchToImageRelative.js b/Packages/viewerbase/lib/switchToImageRelative.js new file mode 100644 index 000000000..5d1c3f636 --- /dev/null +++ b/Packages/viewerbase/lib/switchToImageRelative.js @@ -0,0 +1,13 @@ +/** + * This function switches to an image given an element and + * the relative distance from the current image in the stack + * + * e.g. switchToImageRelative(element, -1) to switch to currentImageIdIndex - 1 + * + * @param element + * @param {number} [distanceFromCurrentIndex] The image index in the stack to switch to. + */ +switchToImageRelative = function(distanceFromCurrentIndex) { + var element = getActiveViewportElement(); + cornerstoneTools.scroll(element, distanceFromCurrentIndex); +}; diff --git a/Packages/viewerbase/lib/toolManager.js b/Packages/viewerbase/lib/toolManager.js index f98107bc5..59dc00d6a 100644 --- a/Packages/viewerbase/lib/toolManager.js +++ b/Packages/viewerbase/lib/toolManager.js @@ -1,4 +1,5 @@ -var activeTool; +var activeTool = "wwwc"; +var defaultTool = "wwwc"; var alwaysEnabledTools = []; @@ -147,9 +148,15 @@ toolManager = { toolManager.init(); } + if (!elements || !elements.length) { + elements = $('.imageViewerViewport'); + } + $('#toolbar .btn-group button').removeClass('active'); var toolButton = document.getElementById(tool); - toolButton.classList.add('active'); + if (toolButton) { + toolButton.classList.add('active'); + } // Otherwise, set the active tool for all viewport elements $(elements).each(function(index, element) { @@ -159,14 +166,14 @@ toolManager = { }, getActiveTool: function() { if (!activeTool) { - activeTool = OHIF.viewer.defaultTool; + activeTool = defaultTool; } return activeTool; }, setDefaultTool: function(tool) { - OHIF.viewer.defaultTool = tool; + defaultTool = tool; }, getDefaultTool: function() { - return OHIF.viewer.defaultTool; + return defaultTool; } }; diff --git a/Packages/viewerbase/lib/viewportFunctions.js b/Packages/viewerbase/lib/viewportFunctions.js new file mode 100644 index 000000000..80106ed35 --- /dev/null +++ b/Packages/viewerbase/lib/viewportFunctions.js @@ -0,0 +1,68 @@ +getActiveViewportElement = function() { + var viewportIndex = Session.get("activeViewport"); + return $('.imageViewerViewport').get(viewportIndex); +}; + +zoomIn = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.scale += 0.15; + if (viewport.scale > 10.0) { + viewport.scale = 10.0; + } + cornerstone.setViewport(element, viewport); +}; + +zoomOut = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.scale -= 0.15; + if (viewport.scale < 0.05) { + viewport.scale = 0.05; + } + cornerstone.setViewport(element, viewport); +}; + +zoomToFit = function() { + var element = getActiveViewportElement(); + cornerstone.fitToWindow(element); +}; + +rotateL = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.rotation -= 90; + cornerstone.setViewport(element, viewport); + updateOrientationMarkers(element, viewport); +}; + +rotateR = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.rotation += 90; + cornerstone.setViewport(element, viewport); + updateOrientationMarkers(element, viewport); +}; + +invert = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.invert = (viewport.invert === false); + cornerstone.setViewport(element, viewport); +}; + +flipV = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.vflip = (viewport.vflip === false); + cornerstone.setViewport(element, viewport); + updateOrientationMarkers(element, viewport); +}; + +flipH = function() { + var element = getActiveViewportElement(); + var viewport = cornerstone.getViewport(element); + viewport.hflip = (viewport.hflip === false); + cornerstone.setViewport(element, viewport); + updateOrientationMarkers(element, viewport); +}; \ No newline at end of file diff --git a/Packages/viewerbase/package.js b/Packages/viewerbase/package.js index 6c4f2fe4d..1413606f1 100644 --- a/Packages/viewerbase/package.js +++ b/Packages/viewerbase/package.js @@ -22,83 +22,85 @@ Package.onUse(function (api) { api.addFiles('log.js', ['client', 'server']); + // TODO= Find a meteor package for this + api.addFiles('client/compatibility/jquery.hotkeys.js', 'client'); + // ---------- Components ---------- // Basic components - api.addFiles('components/basic/layout/layout.html', 'client'); - api.addFiles('components/basic/layout/layout.styl', 'client'); - api.addFiles('components/basic/login/login.html', 'client'); - api.addFiles('components/basic/notFound/notFound.html', 'client'); + api.addFiles('client/components/basic/layout/layout.html', 'client'); + api.addFiles('client/components/basic/layout/layout.styl', 'client'); + api.addFiles('client/components/basic/login/login.html', 'client'); + api.addFiles('client/components/basic/notFound/notFound.html', 'client'); - api.addFiles('components/basic/loadingText/loadingText.html', 'client'); - api.addFiles('components/basic/loadingText/loadingText.styl', 'client'); + api.addFiles('client/components/basic/loadingText/loadingText.html', 'client'); + api.addFiles('client/components/basic/loadingText/loadingText.styl', 'client'); - api.addFiles('components/basic/removableBackdrop/removableBackdrop.html', 'client'); - api.addFiles('components/basic/removableBackdrop/removableBackdrop.styl', 'client'); + api.addFiles('client/components/basic/removableBackdrop/removableBackdrop.html', 'client'); + api.addFiles('client/components/basic/removableBackdrop/removableBackdrop.styl', 'client'); - api.addFiles('components/basic/hidingPanel/hidingPanel.html', 'client'); - api.addFiles('components/basic/hidingPanel/hidingPanel.js', 'client'); - api.addFiles('components/basic/hidingPanel/hidingPanel.styl', 'client'); + api.addFiles('client/components/basic/hidingPanel/hidingPanel.html', 'client'); + api.addFiles('client/components/basic/hidingPanel/hidingPanel.js', 'client'); + api.addFiles('client/components/basic/hidingPanel/hidingPanel.styl', 'client'); // Study Browser components - api.addFiles('components/studyBrowser/studyBrowser/studyBrowser.html', 'client'); - api.addFiles('components/studyBrowser/studyBrowser/studyBrowser.js', 'client'); - api.addFiles('components/studyBrowser/studyBrowser/studyBrowser.styl', 'client'); + api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.html', 'client'); + api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.js', 'client'); + api.addFiles('client/components/studyBrowser/studyBrowser/studyBrowser.styl', 'client'); - api.addFiles('components/studyBrowser/thumbnailEntry/thumbnailEntry.html', 'client'); - api.addFiles('components/studyBrowser/thumbnailEntry/thumbnailEntry.js', 'client'); - api.addFiles('components/studyBrowser/thumbnailEntry/thumbnailEntry.styl', 'client'); + api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.html', 'client'); + api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js', 'client'); + api.addFiles('client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl', 'client'); - api.addFiles('components/studyBrowser/thumbnails/thumbnails.html', 'client'); - api.addFiles('components/studyBrowser/thumbnails/thumbnails.js', 'client'); + api.addFiles('client/components/studyBrowser/thumbnails/thumbnails.html', 'client'); + api.addFiles('client/components/studyBrowser/thumbnails/thumbnails.js', 'client'); - api.addFiles('components/studyBrowser/imageThumbnail/imageThumbnail.html', 'client'); - api.addFiles('components/studyBrowser/imageThumbnail/imageThumbnail.js', 'client'); - api.addFiles('components/studyBrowser/imageThumbnail/imageThumbnail.styl', 'client'); + api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.html', 'client'); + api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.js', 'client'); + api.addFiles('client/components/studyBrowser/imageThumbnail/imageThumbnail.styl', 'client'); // Viewer components - api.addFiles('components/viewer/imageViewerViewport/imageViewerViewport.html', 'client'); - api.addFiles('components/viewer/imageViewerViewport/imageViewerViewport.js', 'client'); - api.addFiles('components/viewer/imageViewerViewport/imageViewerViewport.styl', 'client'); + api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.html', 'client'); + api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.js', 'client'); + api.addFiles('client/components/viewer/imageViewerViewport/imageViewerViewport.styl', 'client'); - api.addFiles('components/viewer/imageViewerViewports/imageViewerViewports.html', 'client'); - api.addFiles('components/viewer/imageViewerViewports/imageViewerViewports.js', 'client'); - api.addFiles('components/viewer/imageViewerViewports/imageViewerViewports.styl', 'client'); + api.addFiles('client/components/viewer/imageViewerViewports/imageViewerViewports.html', 'client'); + api.addFiles('client/components/viewer/imageViewerViewports/imageViewerViewports.js', 'client'); + api.addFiles('client/components/viewer/imageViewerViewports/imageViewerViewports.styl', 'client'); - api.addFiles('components/viewer/loadingIndicator/loadingIndicator.html', 'client'); - api.addFiles('components/viewer/loadingIndicator/loadingIndicator.js', 'client'); - api.addFiles('components/viewer/loadingIndicator/loadingIndicator.styl', 'client'); + api.addFiles('client/components/viewer/loadingIndicator/loadingIndicator.html', 'client'); + api.addFiles('client/components/viewer/loadingIndicator/loadingIndicator.js', 'client'); + api.addFiles('client/components/viewer/loadingIndicator/loadingIndicator.styl', 'client'); - api.addFiles('components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html', 'client'); - api.addFiles('components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js', 'client'); - api.addFiles('components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl', 'client'); + api.addFiles('client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.html', 'client'); + api.addFiles('client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.js', 'client'); + api.addFiles('client/components/viewer/viewportOrientationMarkers/viewportOrientationMarkers.styl', 'client'); - api.addFiles('components/viewer/viewportOverlay/viewportOverlay.html', 'client'); - api.addFiles('components/viewer/viewportOverlay/viewportOverlay.js', 'client'); - api.addFiles('components/viewer/viewportOverlay/viewportOverlay.styl', 'client'); + api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.html', 'client'); + api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.js', 'client'); + api.addFiles('client/components/viewer/viewportOverlay/viewportOverlay.styl', 'client'); - api.addFiles('components/viewer/layoutChooser/layoutChooser.html', 'client'); - api.addFiles('components/viewer/layoutChooser/layoutChooser.js', 'client'); - api.addFiles('components/viewer/layoutChooser/layoutChooser.styl', 'client'); + api.addFiles('client/components/viewer/layoutChooser/layoutChooser.html', 'client'); + api.addFiles('client/components/viewer/layoutChooser/layoutChooser.js', 'client'); + api.addFiles('client/components/viewer/layoutChooser/layoutChooser.styl', 'client'); - api.addFiles('components/viewer/simpleToolbarButton/simpleToolbarButton.html', 'client'); + api.addFiles('client/components/viewer/simpleToolbarButton/simpleToolbarButton.html', 'client'); - api.addFiles('components/viewer/playClipButton/playClipButton.html', 'client'); - api.addFiles('components/viewer/playClipButton/playClipButton.js', 'client'); + api.addFiles('client/components/viewer/playClipButton/playClipButton.html', 'client'); + api.addFiles('client/components/viewer/playClipButton/playClipButton.js', 'client'); - api.addFiles('components/viewer/hangingProtocolButtons/hangingProtocolButtons.html', 'client'); - api.addFiles('components/viewer/hangingProtocolButtons/hangingProtocolButtons.js', 'client'); + api.addFiles('client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.html', 'client'); + api.addFiles('client/components/viewer/hangingProtocolButtons/hangingProtocolButtons.js', 'client'); - api.addFiles('components/viewer/layoutButton/layoutButton.html', 'client'); + api.addFiles('client/components/viewer/layoutButton/layoutButton.html', 'client'); - api.addFiles('components/viewer/toolbar/toolbar.html', 'client'); - api.addFiles('components/viewer/toolbar/toolbar.js', 'client'); - api.addFiles('components/viewer/toolbar/toolbar.styl', 'client'); + api.addFiles('client/components/viewer/toolbar/toolbar.html', 'client'); + api.addFiles('client/components/viewer/toolbar/toolbar.js', 'client'); + api.addFiles('client/components/viewer/toolbar/toolbar.styl', 'client'); // Library functions api.addFiles('lib/accountsConfig.js', 'client'); api.addFiles('lib/createStacks.js', 'client'); - api.addFiles('lib/encodeQueryData.js', ['client', 'server']); api.addFiles('lib/getImageId.js', 'client'); api.addFiles('lib/getWADORSImageId.js', 'client'); api.addFiles('lib/isTouchDevice.js', 'client'); @@ -110,15 +112,20 @@ Package.onUse(function (api) { api.addFiles('lib/enablePrefetchOnElement.js', 'client'); api.addFiles('lib/displayReferenceLines.js', 'client'); api.addFiles('lib/setActiveViewport.js', 'client'); - //api.addFiles('lib/switchToImageByIndex.js', 'client'); - //api.addFiles('lib/switchToImageRelative.js', 'client'); + api.addFiles('lib/switchToImageByIndex.js', 'client'); + api.addFiles('lib/switchToImageRelative.js', 'client'); + api.addFiles('lib/enableHotkeys.js', 'client'); + api.addFiles('lib/viewportFunctions.js', 'client'); + api.addFiles('lib/WLPresets.js', 'client'); + + api.addFiles('lib/encodeQueryData.js', 'server'); //api.export('accountsConfig', 'client'); + api.export('enableHotkeys', 'client'); api.export('enablePrefetchOnElement', 'client'); api.export('displayReferenceLines', 'client'); api.export('setActiveViewport', 'client'); api.export('createStacks', 'client'); - api.export('encodeQueryData', ['client', 'server']); api.export('getImageId', 'client'); api.export('getWADORSImageId', 'client'); api.export('isTouchDevice', 'client'); @@ -126,11 +133,14 @@ Package.onUse(function (api) { api.export('rerenderViewportWithNewSeries', 'client'); api.export('sortStudy', 'client'); api.export('updateOrientationMarkers', 'client'); + api.export('encodeQueryData', 'server'); // Viewer management objects api.export('toolManager', 'client'); api.export('WindowManager', 'client'); + // Global data object + api.export('OHIF', 'client'); // UI Helpers api.addFiles('lib/helpers/formatDA.js', 'client');