diff --git a/anatomy/static/css/anatomy.css b/anatomy/static/css/anatomy.css index 8c849a87..a5bef0dd 100644 --- a/anatomy/static/css/anatomy.css +++ b/anatomy/static/css/anatomy.css @@ -158,7 +158,7 @@ button a { height: 600px; } -#dicom-image.marking-dicom { +.marking-dicom { position: fixed; right: 0px; bottom: 0px; @@ -167,6 +167,10 @@ button a { z-index: 1; } +.cornerstone-canvas { + height: 100%; +} + .marking { } diff --git a/anatomy/static/js/anatomy.js b/anatomy/static/js/anatomy.js index abc09bd5..043271c6 100644 --- a/anatomy/static/js/anatomy.js +++ b/anatomy/static/js/anatomy.js @@ -1,10 +1,13 @@ +import * as dicomViewer from "./dicomViewer.js" -var marked_answers = { +window.marked_answers = { "correct": [], "half-correct": [], "incorrect": [], } +window.control_pressed = false; + $(document).ready(function () { $(".answer-list li").each(function (index, element) { @@ -39,7 +42,7 @@ $(document).ready(function () { }); } - dicom_images = document.getElementsByClassName("dicom-image"); + let dicom_images = document.getElementsByClassName("dicom-image"); if (dicom_images.length) { for (let element of dicom_images) { @@ -48,6 +51,13 @@ $(document).ready(function () { } + let single_dicom = document.getElementById("single-dicom-viewer"); + if (single_dicom) { + let images = single_dicom.dataset.images.split(","); + let annotations = single_dicom.dataset.annotations.split(","); + dicomViewer.loadCornerstone($(single_dicom), null, images, annotations); + } + if ($("#question-mark-list").length) { $(".show-all-button").click(() => { $("#question-mark-list li").show(); @@ -62,6 +72,9 @@ $(document).ready(function () { } + $(document).keydown(keyDownHandler); + $(document).keyup(keyUpHandler); + }); function prepAnswerData() { @@ -85,15 +98,15 @@ function prepAnswerData() { window.marked_answers["half-correct"] = []; window.marked_answers["incorrect"] = []; $("li span.correct").map(function () { - ans = $(this).text(); + let ans = $(this).text(); window.marked_answers["correct"].push(ans); }) $("li span.half-correct").map(function () { - ans = $(this).text(); + let ans = $(this).text(); window.marked_answers["half-correct"].push(ans); }) $("li span.incorrect").map(function () { - ans = $(this).text(); + let ans = $(this).text(); window.marked_answers["incorrect"].push(ans); }) $("#id_marked_answers").val(JSON.stringify(window.marked_answers)); @@ -168,12 +181,12 @@ function setUpDicom(element) { const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool; - const imageId = element.dataset.url; + const imageIds = element.dataset.url.split(","); - console.log("Dicom - load imageId: ", imageId); + console.log("Dicom - load imageId: ", imageIds); cornerstone.enable(element); - cornerstone.loadAndCacheImage(imageId).then(function (image) { + cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { cornerstone.displayImage(element, image); cornerstoneTools.addTool(PanTool); @@ -220,4 +233,115 @@ function setUpDicom(element) { }); +} + +function keyUpHandler(e) { + if(e.key == "Control") { + dicomViewer.registerPrimaryDicomInterface(e); + window.control_pressed = false; + } +} + +function keyDownHandler(e) { + // 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; + } + } + + if(e.key == "Control") { + if(window.control_pressed == false) { + window.control_pressed = true; + dicomViewer.registerAltDicomInterface(e); + } + } + + var charCode = typeof e.which == "number" ? e.which : e.keyCode; + console.log(e, charCode); + + function numberKeyPressed(e, x) { + if(e.altKey ? true : false) { + dicomViewer.selectThumb(x); + 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; + } } \ No newline at end of file diff --git a/anatomy/templates/anatomy/base.html b/anatomy/templates/anatomy/base.html index 43b491bf..a5b9bd8c 100644 --- a/anatomy/templates/anatomy/base.html +++ b/anatomy/templates/anatomy/base.html @@ -8,6 +8,7 @@ + @@ -17,7 +18,7 @@ - + {% block js %} {% endblock %} diff --git a/physics/templates/physics/base.html b/physics/templates/physics/base.html index 05aa729c..d8c31457 100644 --- a/physics/templates/physics/base.html +++ b/physics/templates/physics/base.html @@ -8,6 +8,7 @@ + diff --git a/rapids/models.py b/rapids/models.py index 505e6f4e..7e5b3b5d 100644 --- a/rapids/models.py +++ b/rapids/models.py @@ -242,8 +242,12 @@ class Rapid(models.Model): ) def GetUnmarkedAnswers(self): + # If normal no answers to mark + if self.normal: + return [] + user_answers = set( - [i.answer_compare for i in self.cid_user_answers.all()] + [i.answer_compare for i in self.cid_user_answers.all() if i.normal == False] ) unmarked_answers = user_answers - self.GetMarkedAnswers() @@ -283,6 +287,8 @@ class Rapid(models.Model): return images + def GetImageUrls(self): + return ",".join(["http://penracourses.org.uk{}".format(i.url) for i in self.GetImages()]) #def GetNonFeedbackQuestionImages(self): #return self.GetImages() diff --git a/rapids/templates/rapids/base.html b/rapids/templates/rapids/base.html index df200546..7725b483 100755 --- a/rapids/templates/rapids/base.html +++ b/rapids/templates/rapids/base.html @@ -8,6 +8,7 @@ + {% comment %} @@ -15,6 +16,7 @@ {% endcomment %} + @@ -23,7 +25,7 @@ - + {% block js %} {% endblock %} diff --git a/rapids/templates/rapids/mark.html b/rapids/templates/rapids/mark.html index ca4a31cf..d0c7a519 100644 --- a/rapids/templates/rapids/mark.html +++ b/rapids/templates/rapids/mark.html @@ -2,48 +2,66 @@ {% block content %}