Mercurial > hg > orthanc-stone
changeset 2020:88673f50d7b9
added key bindings to change active study and series
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sat, 03 Dec 2022 11:59:20 +0100 |
parents | fe9999d6a636 |
children | 1458f3bcb991 |
files | Applications/StoneWebViewer/NEWS Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html |
diffstat | 3 files changed, 98 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/NEWS Sat Dec 03 09:22:19 2022 +0100 +++ b/Applications/StoneWebViewer/NEWS Sat Dec 03 11:59:20 2022 +0100 @@ -2,6 +2,11 @@ =============================== * Click-drag is available on the vertical slider +* Added key bindings: + - Left/right arrows to change the active frame + - Up/down arrows to change the active series + - Page up/down to change the active study + - Space bar to play/pause videos * New URL argument "menu" to change the layout of the list of studies/series * The first series to be loaded is now automatically opened * Annotations are grouped into one submenu for narrow screens
--- a/Applications/StoneWebViewer/WebApplication/app.js Sat Dec 03 09:22:19 2022 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Sat Dec 03 11:59:20 2022 +0100 @@ -125,6 +125,17 @@ } +function LookupIndexOfResource(array, tag, value) { + for (var i = 0; i < array.length; i++) { + if (array[i].tags[tag] == value) { + return i; + } + } + + return -1; +} + + /** * Enable support for tooltips in Bootstrap. This function must be * called after each modification to the DOM that introduces new @@ -351,9 +362,9 @@ } }); - window.addEventListener('CineSwitch', function(args) { + window.addEventListener('KeyCineSwitch', function(args) { if (that.active) { - that.CineSwitch(); + that.KeyCineSwitch(); } }); }, @@ -395,7 +406,7 @@ this.cineIncrement = 1; this.UpdateCine(); }, - CineSwitch: function() { + KeyCineSwitch: function() { if (this.cineIncrement != 0) { this.CinePause(); } else { @@ -589,8 +600,30 @@ }); } }, + + GetActiveViewportSeriesTags: function() { + if (this.activeViewport == 1 && + this.viewport1Content.virtualSeriesId === undefined) { + return this.viewport1Content.series.tags; + } + else if (this.activeViewport == 2 && + this.viewport2Content.virtualSeriesId === undefined) { + return this.viewport2Content.series.tags; + } + else if (this.activeViewport == 3 && + this.viewport3Content.virtualSeriesId === undefined) { + return this.viewport3Content.series.tags; + } + else if (this.activeViewport == 4 && + this.viewport4Content.virtualSeriesId === undefined) { + return this.viewport4Content.series.tags; + } + else { + return null; + } + }, - GetActiveSeries: function() { + GetActiveSeriesInstanceUid: function() { var s = []; if ('tags' in this.viewport1Content.series) @@ -1196,7 +1229,48 @@ .catch(function (error) { alert('Cannot find the study in Orthanc'); }); - + }, + + ChangeActiveSeries: function(offset) { + var seriesTags = this.GetActiveViewportSeriesTags(); + if (seriesTags !== null) { + var studyIndex = LookupIndexOfResource(this.studies, STUDY_INSTANCE_UID, seriesTags[STUDY_INSTANCE_UID]); + if (studyIndex != -1) { + var seriesInStudyIndices = this.studies[studyIndex].series; + for (var i = 0; i < seriesInStudyIndices.length; i++) { + if (this.series[seriesInStudyIndices[i]].tags[SERIES_INSTANCE_UID] == seriesTags[SERIES_INSTANCE_UID]) { + var next = i + offset; + if (next >= 0 && + next < seriesInStudyIndices.length) { + this.SetViewportSeriesInstanceUid(this.activeViewport, this.series[seriesInStudyIndices[next]].tags[SERIES_INSTANCE_UID]); + } + break; + } + } + } + } + }, + + ChangeActiveStudy: function(offset) { + var seriesTags = this.GetActiveViewportSeriesTags(); + if (seriesTags !== null) { + var studyIndex = LookupIndexOfResource(this.studies, STUDY_INSTANCE_UID, seriesTags[STUDY_INSTANCE_UID]); + if (studyIndex != -1) { + var next = studyIndex + offset; + if (next >= 0 && + next < this.studies.length) { + var nextStudy = this.studies[next]; + if (nextStudy.series.length > 0) { + var seriesIndex = nextStudy.series[0]; + if (this.series[seriesIndex].virtualSeries !== null) { + this.ClickVirtualSeries(seriesIndex, this.series[seriesIndex].virtualSeries); + } else { + this.ClickSeries(seriesIndex); + } + } + } + } + } } }, @@ -1276,15 +1350,25 @@ case 'Up': case 'ArrowUp': + that.ChangeActiveSeries(-1); + break + + case 'Down': + case 'ArrowDown': + that.ChangeActiveSeries(1); break; - case 'Down': - case 'ArrowDown': + case 'PageUp': + that.ChangeActiveStudy(-1); + break + + case 'PageDown': + that.ChangeActiveStudy(1); break; case ' ': case 'Space': - dispatchEvent(new CustomEvent('CineSwitch', { })); + dispatchEvent(new CustomEvent('KeyCineSwitch', { })); event.preventDefault(); break;
--- a/Applications/StoneWebViewer/WebApplication/index.html Sat Dec 03 09:22:19 2022 +0100 +++ b/Applications/StoneWebViewer/WebApplication/index.html Sat Dec 03 11:59:20 2022 +0100 @@ -217,7 +217,7 @@ <!-- Series without multiple multiframe instances --> <span v-for="seriesIndex in study.series"> <li class="wvSerieslist__seriesItem" - v-bind:class="{ highlighted : GetActiveSeries().includes(series[seriesIndex].tags[SERIES_INSTANCE_UID]), 'wvSerieslist__seriesItem--list' : leftMode != 'grid', 'wvSerieslist__seriesItem--grid' : leftMode == 'grid' }" + v-bind:class="{ highlighted : GetActiveSeriesInstanceUid().includes(series[seriesIndex].tags[SERIES_INSTANCE_UID]), 'wvSerieslist__seriesItem--list' : leftMode != 'grid', 'wvSerieslist__seriesItem--grid' : leftMode == 'grid' }" v-on:dragstart="SeriesDragStart($event, seriesIndex)" v-on:click="ClickSeries(seriesIndex)" v-if="series[seriesIndex].virtualSeries === null">