From db46c153f0686c144f7ca6be7b640075053cb167 Mon Sep 17 00:00:00 2001 From: Ross Date: Sat, 4 Dec 2021 14:57:42 +0000 Subject: [PATCH] start allowing multiple viewer on single page --- dicomViewer.css | 2 +- dicomViewer.js | 190 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 157 insertions(+), 35 deletions(-) diff --git a/dicomViewer.css b/dicomViewer.css index 91a514a..b10c203 100644 --- a/dicomViewer.css +++ b/dicomViewer.css @@ -44,7 +44,7 @@ color: lightblue; } -.single-dicom-viewer { +.cornerstone-element { position: relative; height: 100%; } diff --git a/dicomViewer.js b/dicomViewer.js index 77b2de4..26e6e56 100644 --- a/dicomViewer.js +++ b/dicomViewer.js @@ -9,17 +9,22 @@ cornerstoneBase64ImageLoader.external.cornerstone = cornerstone; cornerstoneWebImageLoader.external.cornerstone = cornerstone; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; -cornerstoneTools.init(); +cornerstoneTools.init({keyboardEnabled: true}); let tool_state = {}; export function loadCornerstone(main_element, db, images, annotations_to_load, load_as_stack = false) { // canvas-panel holds the enabled elements and all tools / menus - main_element.append("
"); + const canvas_panel = $("
"); + main_element.append(canvas_panel); main_element[0].dataset.collapsed = "none"; - $(".canvas-panel").append($("
")); - $(".canvas-panel").append($(`
+ + + const cornerstone_element = $("
"); + const element = cornerstone_element.get(0); + canvas_panel.append(cornerstone_element); + canvas_panel.append($(`
close

DICOM Summary

@@ -309,10 +314,9 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
`)); - let single_dicom_viewer = main_element.find(".single-dicom-viewer").get(0); - //console.log(single_dicom_viewer); + //console.log(cornerstone_element); - $(".canvas-panel").append($(`
+ canvas_panel.append($(``)); @@ -398,7 +402,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l
`) ); - $(single_dicom_viewer).append( + cornerstone_element.append( $( "
Image of
wc: ww:
" ) @@ -422,10 +426,10 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l let button_id = e.target.id; let [ww, wc] = window_presets[button_id]; - let viewport = cornerstone.getViewport(single_dicom_viewer); + let viewport = cornerstone.getViewport(element); viewport.voi.windowWidth = parseFloat(ww); viewport.voi.windowCenter = parseFloat(wc); - cornerstone.setViewport(single_dicom_viewer, viewport); + cornerstone.setViewport(element, viewport); e.preventDefault(); e.stopPropagation(); @@ -486,7 +490,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l $("#dicom-window-panel").show(); $(e.target).removeClass("dicom-button-highlight"); } - resizeHandler(); + resizeHandler(element); //loadCornerstone(main_element, db, images, annotations_to_load, stack) }); @@ -529,7 +533,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l } async function load(images, annotations) { - //console.log("LOAD", images); + console.log("LOAD", images); let imageIds = []; for (let i = 0; i < images.length; i++) { let data_url = images[i]; @@ -597,7 +601,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { //console.log("LOAD and cache, then", image); - loadCornerstoneMainImage(single_dicom_viewer, image, stack, db, load_as_stack); + loadCornerstoneMainImage(element, image, stack, db, load_as_stack); }) .catch((err, err2) => { console.log(err); @@ -636,7 +640,7 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l "
" ); $("#image-thumbs").append(thumb); - $("#thumb-" + id).click(selectThumbClick).mousedown(stopEvent); + $("#thumb-" + id).click((evt) => { selectThumbClick(evt, element) }).mousedown(stopEvent); let image_url = images[id]; @@ -703,8 +707,124 @@ export function loadCornerstone(main_element, db, images, annotations_to_load, l } load(images, annotations); + + console.log(main_element) + + main_element.keydown((evt) => { keyDownHandler(evt, element)}); + main_element.keyup((evt) => { keyUpHandler(evt, element)}); } +function keyUpHandler(e, element) { + console.log("Key up", e, e.key) + if (e.key == "Control") { + registerPrimaryDicomInterface(element); + window.control_pressed = false; + } +} + +function keyDownHandler(e, element) { + //// Ignore our custom keybindings if we are currently in a field that + //// accepts some kind of input + //if ($("*:focus:not(disabled)").is("textarea, input")) { + // // unless a modifier key is pressed (not shift) + // if (e.altKey ? true : false || e.ctrlKey ? true : false) {} else { + // return; + // } + //} + console.log("Key down", e, e.key) + + if (e.key == "Control") { + if (window.control_pressed != true) { + window.control_pressed = true; + registerAltDicomInterface(e, element); + } + } + + var charCode = typeof e.which == "number" ? e.which : e.keyCode; + + function numberKeyPressed(e, x) { + if (e.altKey ? true : false) { + selectThumb(x, element); + e.preventDefault(); + } else {} + } + + switch (charCode) { + case 13: // Return + if (e.shiftKey ? true : false) { + //$(".next-button:last").click(); + } else { + //$(".check-button:last").click(); + } + break; + case 32: // Space + if (e.shiftKey ? true : false) { + //$(".previous-button:last").click(); + } else { + //$(".next-button:last").click(); + } + e.preventDefault(); // Needed to stop the default action (scroll) + break; + case 46: // . + //toggleFlagged(); + break; + + // Numbers 1-9 select the corresponding answer (if it exists) + // TODO: fix for multi question questions + case 49: // 1 + numberKeyPressed(e, 0); + break; + case 50: // 2 + numberKeyPressed(e, 1); + break; + case 51: // 3 + numberKeyPressed(e, 2); + break; + case 52: // 4 + numberKeyPressed(e, 3); + break; + case 53: // 5 + numberKeyPressed(e, 4); + break; + case 54: // 6 + numberKeyPressed(e, 5); + break; + case 55: // 7 + numberKeyPressed(e, 6); + break; + case 56: // 8 + numberKeyPressed(e, 7); + break; + case 57: // 9 + numberKeyPressed(e, 8); + break; + case 72: // H + previousQuestion(); + break; + case 76: // L + //nextQuestion(); + break; + + case 102: // f + //$("#filter-toggle").click(); + break; + case 103: // g + //$("#options").slideDown("slow"); + //$("#goto-question-input").focus(); + //e.preventDefault(); + break; + + // Vim like scrolling (incredibly important) + case 106: // j + //window.scrollBy(0, 25); + break; + case 107: // k + //window.scrollBy(0, -25); + break; + } +} + + function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { //dumpDataSet(image.data) //console.log("loadCornerstoneMainImage") @@ -725,9 +845,12 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { //console.log("enable element", element); cornerstone.enable(element); + element.tabIndex = 0; cornerstone.displayImage(element, image); + //cornerstoneTools.keyboardInput.enable(element); + cornerstoneTools.addStackStateManager(element, ["stack"]); cornerstoneTools.addToolState(element, "stack", stack); @@ -789,8 +912,8 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { //$("#middle-mouse-dicom").append(option); //$("#right-mouse-dicom").append(option); }); - $(".mouse-binding-select").on("change", function (e) { - changeMouseBinding(e, db); + $(".mouse-binding-select").on("change", function (evt) { + changeMouseBinding(evt, db, element); }); // Set default tools @@ -821,10 +944,11 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { "WwwcRegion" ); - loadPrimaryDicomInterface(db); + loadPrimaryDicomInterface(db, element); loadAltDicomInterface(db); element.addEventListener("cornerstoneimagerendered", onImageRendered); + //element.addEventListener("cornerstonetoolskeydown", keyDownHandler); //setDicomCanvasNonFullscreen(element); cornerstone.reset(element); @@ -846,9 +970,9 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { // .get(0) // .addEventListener("change", changeControlSelection); - resizeHandler(); + resizeHandler(element); - window.addEventListener("resize", resizeHandler); + window.addEventListener("resize", () => { resizeHandler(element)}); element.addEventListener( "contextmenu", function (e) { @@ -864,14 +988,13 @@ function loadCornerstoneMainImage(element, image, stack, db, load_as_stack) { }); } -function resizeHandler() { - let element = document.getElementsByClassName("single-dicom-viewer")[0]; +function resizeHandler(element) { let h = window.innerHeight - $("#header").height() - 16; $(element).height(h); cornerstone.resize(element, true); } -async function loadPrimaryDicomInterface(db) { +async function loadPrimaryDicomInterface(db, element) { const bindings = await dicom_settings_db.mouse_bindings.where({ mode: "0" }).toArray().catch((err) => { @@ -884,7 +1007,7 @@ async function loadPrimaryDicomInterface(db) { sel.value = b.tool; //sel.dispatchEvent(new Event("change")); }); - registerPrimaryDicomInterface(); + registerPrimaryDicomInterface(element); } async function loadAltDicomInterface(db) { @@ -945,16 +1068,16 @@ function stopEvent(evt) { evt.stopPropagation(); } -function selectThumbClick(evt) { +function selectThumbClick(evt, element) { let new_index = evt.currentTarget.dataset.id; - selectThumb(new_index); + selectThumb(new_index, element); evt.preventDefault(); } -export function registerPrimaryDicomInterface() { +export function registerPrimaryDicomInterface(element) { + console.log("reg primary") // Set mousetools based upon the selected options - let element = document.getElementsByClassName("single-dicom-viewer")[0]; let selections = $("#primary-mouse-binding select"); selections.each((i, option) => { cornerstoneTools.setToolActiveForElement(element, option.value, { @@ -963,11 +1086,12 @@ export function registerPrimaryDicomInterface() { }); } -export function registerAltDicomInterface(e) { +export function registerAltDicomInterface(e, element) { // Called when control is pressed // Set mousetools based upon the selected options - let element = document.getElementsByClassName("single-dicom-viewer")[0]; + //let element = document.getElementsByClassName("cornerstone-element")[0]; + console.log("reg alt", element) let selections = $("#secondary-mouse-binding select"); selections.each((i, option) => { cornerstoneTools.setToolActiveForElement(element, option.value, { @@ -976,8 +1100,8 @@ export function registerAltDicomInterface(e) { }); } -function changeMouseBinding(e, db) { - let select = e.currentTarget; +function changeMouseBinding(evt, db, element) { + let select = evt.currentTarget; let button = select.dataset.button; let mode = select.dataset.mode; let tool = select.value; @@ -985,7 +1109,6 @@ function changeMouseBinding(e, db) { // Directly activate primary tools (secondary will be activated when modifier // key is pressed if (mode == "0") { - let element = document.getElementsByClassName("single-dicom-viewer")[0]; cornerstoneTools.setToolActiveForElement(element, tool, { mouseButtonMask: parseInt(button) }); @@ -999,10 +1122,9 @@ function changeMouseBinding(e, db) { //db.mouse_bindings.put({button: button, mode: mode, tool: tool}).then(loadPrimaryDicomInterface()); } -export function selectThumb(new_index) { +export function selectThumb(new_index, dicom_element) { //console.log("select thumb new index", new_index); // There must be a better way to do this... - let dicom_element = document.getElementsByClassName("single-dicom-viewer")[0]; if (dicom_element == null) { return; }