AWV-1: Refactoring layout manager
This commit is contained in:
parent
0469747b5a
commit
e98e686664
@ -97,7 +97,7 @@ Template.toolbarSection.helpers({
|
|||||||
title: 'Previous',
|
title: 'Previous',
|
||||||
classes: 'imageViewerCommand',
|
classes: 'imageViewerCommand',
|
||||||
buttonTemplateName: 'displaySetNavigation',
|
buttonTemplateName: 'displaySetNavigation',
|
||||||
isPrevious: true
|
isNext: false
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonData.push({
|
buttonData.push({
|
||||||
@ -105,7 +105,7 @@ Template.toolbarSection.helpers({
|
|||||||
title: 'Next',
|
title: 'Next',
|
||||||
classes: 'imageViewerCommand',
|
classes: 'imageViewerCommand',
|
||||||
buttonTemplateName: 'displaySetNavigation',
|
buttonTemplateName: 'displaySetNavigation',
|
||||||
isPrevious: false
|
isNext: true
|
||||||
});
|
});
|
||||||
|
|
||||||
buttonData.push({
|
buttonData.push({
|
||||||
|
|||||||
@ -2,6 +2,107 @@ import { OHIF } from 'meteor/ohif:core';
|
|||||||
|
|
||||||
OHIF.viewer = {};
|
OHIF.viewer = {};
|
||||||
|
|
||||||
|
OHIF.viewer.getDisplaySetSequenceMap = () => {
|
||||||
|
// Get the viewport data list
|
||||||
|
const viewportDataList = window.layoutManager.viewportData;
|
||||||
|
|
||||||
|
// Create a map to control the display set sequence
|
||||||
|
const sequenceMap = new Map();
|
||||||
|
|
||||||
|
// Iterate over each viewport and register its details on the sequence map
|
||||||
|
viewportDataList.forEach((viewportData, viewportIndex) => {
|
||||||
|
// Get the current study
|
||||||
|
const currentStudy = _.findWhere(window.layoutManager.studies, {
|
||||||
|
studyInstanceUid: viewportData.studyInstanceUid
|
||||||
|
}) || window.layoutManager.studies[0];
|
||||||
|
|
||||||
|
// Get the display sets
|
||||||
|
const displaySets = currentStudy.displaySets;
|
||||||
|
|
||||||
|
// Get the current display set
|
||||||
|
const displaySet = _.findWhere(displaySets, {
|
||||||
|
displaySetInstanceUid: viewportData.displaySetInstanceUid
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the current instance index
|
||||||
|
let displaySetIndex = _.indexOf(displaySets, displaySet);
|
||||||
|
displaySetIndex = displaySetIndex < 0 ? 9999 : displaySetIndex;
|
||||||
|
|
||||||
|
// Try to get a map entry for current study or create it if not present
|
||||||
|
let studyViewports = sequenceMap.get(currentStudy);
|
||||||
|
if (!studyViewports) {
|
||||||
|
studyViewports = [];
|
||||||
|
sequenceMap.set(currentStudy, studyViewports);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the viewport index and the display set index on the map
|
||||||
|
studyViewports.push({
|
||||||
|
viewportIndex,
|
||||||
|
displaySetIndex
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the generated sequence map
|
||||||
|
return sequenceMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
OHIF.viewer.isDisplaySetsSequenced = definedSequenceMap => {
|
||||||
|
let isSequenced = true;
|
||||||
|
|
||||||
|
// Get the studies and display sets sequence map
|
||||||
|
const sequenceMap = definedSequenceMap || OHIF.viewer.getDisplaySetSequenceMap();
|
||||||
|
|
||||||
|
sequenceMap.forEach((studyViewports, study) => {
|
||||||
|
let lastDisplaySetIndex = null;
|
||||||
|
let lastViewportIndex = null;
|
||||||
|
studyViewports.forEach(({ viewportIndex, displaySetIndex }, index) => {
|
||||||
|
// Check if the sequence is wrong
|
||||||
|
if (
|
||||||
|
displaySetIndex !== 9999 &&
|
||||||
|
lastViewportIndex !== null &&
|
||||||
|
lastDisplaySetIndex !== null &&
|
||||||
|
displaySetIndex !== null &&
|
||||||
|
(viewportIndex - 1) !== lastViewportIndex &&
|
||||||
|
(displaySetIndex - 1) !== lastDisplaySetIndex
|
||||||
|
) {
|
||||||
|
// Set the sequenced flag as false;
|
||||||
|
isSequenced = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the last viewport index
|
||||||
|
lastViewportIndex = viewportIndex;
|
||||||
|
|
||||||
|
// Update the last display set index
|
||||||
|
lastDisplaySetIndex = displaySetIndex;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return isSequenced;
|
||||||
|
};
|
||||||
|
|
||||||
|
OHIF.viewer.canMoveDisplaySets = isNext => {
|
||||||
|
// Get the setting that defines if the display set navigation is multiple
|
||||||
|
const isMultiple = OHIF.uiSettings.displaySetNavigationMultipleViewports;
|
||||||
|
|
||||||
|
// Get the setting that allow display set navigation looping over series
|
||||||
|
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
||||||
|
|
||||||
|
// Return false if no layout manager is not defined yet
|
||||||
|
if (!window.layoutManager) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the studies and display sets sequence map
|
||||||
|
const sequenceMap = OHIF.viewer.getDisplaySetSequenceMap();
|
||||||
|
|
||||||
|
// Return false for moving backward if display sets are not sequenced
|
||||||
|
if (isMultiple && !isNext && !OHIF.viewer.isDisplaySetsSequenced(sequenceMap)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
// Move display sets forward or backward in the given viewport index
|
// Move display sets forward or backward in the given viewport index
|
||||||
OHIF.viewer.moveSingleViewportDisplaySets = (viewportIndex, isNext) => {
|
OHIF.viewer.moveSingleViewportDisplaySets = (viewportIndex, isNext) => {
|
||||||
// Get the setting that allow display set navigation looping over series
|
// Get the setting that allow display set navigation looping over series
|
||||||
@ -59,47 +160,14 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
|||||||
// Get the setting that allow display set navigation looping over series
|
// Get the setting that allow display set navigation looping over series
|
||||||
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
||||||
|
|
||||||
// Get the viewport data list
|
// Create a map to control the display set sequence
|
||||||
const viewportDataList = window.layoutManager.viewportData;
|
const sequenceMap = new OHIF.viewer.getDisplaySetSequenceMap();
|
||||||
|
|
||||||
// Create a map to control the display set movement
|
// Check if the display sets are sequenced
|
||||||
const moveMap = new Map();
|
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
|
||||||
|
|
||||||
// Iterate over each viewport and register its details on the movement map
|
|
||||||
viewportDataList.forEach((viewportData, viewportIndex) => {
|
|
||||||
// Get the current study
|
|
||||||
const currentStudy = _.findWhere(window.layoutManager.studies, {
|
|
||||||
studyInstanceUid: viewportData.studyInstanceUid
|
|
||||||
}) || window.layoutManager.studies[0];
|
|
||||||
|
|
||||||
// Get the display sets
|
|
||||||
const displaySets = currentStudy.displaySets;
|
|
||||||
|
|
||||||
// Get the current display set
|
|
||||||
const displaySet = _.findWhere(displaySets, {
|
|
||||||
displaySetInstanceUid: viewportData.displaySetInstanceUid
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the current instance index
|
|
||||||
let displaySetIndex = _.indexOf(displaySets, displaySet);
|
|
||||||
displaySetIndex = displaySetIndex < 0 ? 9999 : displaySetIndex;
|
|
||||||
|
|
||||||
// Try to get a map entry for current study or create it if not present
|
|
||||||
let studyViewports = moveMap.get(currentStudy);
|
|
||||||
if (!studyViewports) {
|
|
||||||
studyViewports = [];
|
|
||||||
moveMap.set(currentStudy, studyViewports);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the viewport index and the display set index on the map
|
|
||||||
studyViewports.push({
|
|
||||||
viewportIndex,
|
|
||||||
displaySetIndex
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Iterate over the studies map and move its display sets
|
// Iterate over the studies map and move its display sets
|
||||||
moveMap.forEach((studyViewports, study) => {
|
sequenceMap.forEach((studyViewports, study) => {
|
||||||
// Sort the viewports on the study by the display set index
|
// Sort the viewports on the study by the display set index
|
||||||
studyViewports.sort((a, b) => a.displaySetIndex > b.displaySetIndex);
|
studyViewports.sort((a, b) => a.displaySetIndex > b.displaySetIndex);
|
||||||
|
|
||||||
@ -114,13 +182,17 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
|||||||
const direction = isNext ? 1 : -1;
|
const direction = isNext ? 1 : -1;
|
||||||
baseIndex += amount * direction;
|
baseIndex += amount * direction;
|
||||||
|
|
||||||
// Check if the base index will be outside the array bounds
|
// Check if the indexes are sequenced or will overflow the array bounds
|
||||||
if (baseIndex >= displaySets.length) {
|
if (!isSequenced) {
|
||||||
|
// Reset the sequence if indexes are not sequenced
|
||||||
|
baseIndex = 0;
|
||||||
|
} else if (baseIndex >= displaySets.length) {
|
||||||
// Stop here if looping is not allowed
|
// Stop here if looping is not allowed
|
||||||
if (!allowLooping) {
|
if (!allowLooping) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start over the series if looping is allowed
|
||||||
baseIndex = 0;
|
baseIndex = 0;
|
||||||
} else if (baseIndex < 0) {
|
} else if (baseIndex < 0) {
|
||||||
// Stop here if looping is not allowed
|
// Stop here if looping is not allowed
|
||||||
@ -128,6 +200,7 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Go to the series' end if looping is allowed
|
||||||
baseIndex = (displaySets.length - 1) - ((displaySets.length - 1) % amount);
|
baseIndex = (displaySets.length - 1) - ((displaySets.length - 1) % amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
<template name="displaySetNavigation">
|
<template name="displaySetNavigation">
|
||||||
<div id="{{this.id}}"
|
<div id="{{this.id}}"
|
||||||
class="toolbarSectionButton rp-x-1 {{this.classes}} {{#if isPrevious}}js-prev{{else}}js-next{{/if}}"
|
class="toolbarSectionButton rp-x-1 {{this.classes}} {{#if isNext}}js-next{{else}}js-prev{{/if}} {{#if (disableButton isNext)}}disabled{{/if}}"
|
||||||
title="{{this.title}}">
|
title="{{this.title}}">
|
||||||
<div class="svgContainer">
|
<div class="svgContainer">
|
||||||
{{#if isPrevious}}
|
{{#if isNext}}
|
||||||
<i class="fa fa-toggle-up fa-fw"></i>
|
|
||||||
{{else}}
|
|
||||||
<i class="fa fa-toggle-down fa-fw"></i>
|
<i class="fa fa-toggle-down fa-fw"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa fa-toggle-up fa-fw"></i>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="buttonLabel" disabled="{{#if (disableButton isPrevious)}}disabled{{/if}}">
|
<div class="buttonLabel">
|
||||||
{{#if isPrevious}}Previous{{else}}Next{{/if}}
|
{{#if isNext}}Next{{else}}Previous{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -3,16 +3,25 @@ import { Template } from 'meteor/templating';
|
|||||||
|
|
||||||
Template.displaySetNavigation.events({
|
Template.displaySetNavigation.events({
|
||||||
'click .js-next'(event, instance) {
|
'click .js-next'(event, instance) {
|
||||||
|
if ($(event.currentTarget).hasClass('disabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OHIF.viewer.moveDisplaySets(true);
|
OHIF.viewer.moveDisplaySets(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
'click .js-prev'(event, instance) {
|
'click .js-prev'(event, instance) {
|
||||||
|
if ($(event.currentTarget).hasClass('disabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OHIF.viewer.moveDisplaySets(false);
|
OHIF.viewer.moveDisplaySets(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.displaySetNavigation.helpers({
|
Template.displaySetNavigation.helpers({
|
||||||
disableButton(isPrevious) {
|
disableButton(isNext) {
|
||||||
|
Session.get('LayoutManagerUpdated');
|
||||||
|
return !OHIF.viewer.canMoveDisplaySets(isNext);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -25,68 +25,74 @@ LayoutManager = class LayoutManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setDefaultViewportData() {
|
setDefaultViewportData() {
|
||||||
var numViewports = this.getNumberOfViewports();
|
const self = this;
|
||||||
|
|
||||||
var viewportIndex = 0;
|
// Get the number of vieports to be rendered
|
||||||
var self = this;
|
const viewportsAmount = this.getNumberOfViewports();
|
||||||
var oldViewportData = self.viewportData;
|
|
||||||
var running = true;
|
|
||||||
self.viewportData = [];
|
|
||||||
this.studies.forEach(function(study) {
|
|
||||||
study.displaySets.forEach(function(displaySet) {
|
|
||||||
if (!displaySet.images.length || !running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentViewportData;
|
// Store the old viewport data and reset the current
|
||||||
var existingViewportData = oldViewportData[viewportIndex];
|
const oldViewportData = self.viewportData;
|
||||||
if (oldViewportData[viewportIndex]) {
|
|
||||||
currentViewportData = {
|
|
||||||
viewportIndex: existingViewportData.viewportIndex,
|
|
||||||
studyInstanceUid: existingViewportData.studyInstanceUid,
|
|
||||||
seriesInstanceUid: existingViewportData.seriesInstanceUid,
|
|
||||||
displaySetInstanceUid: existingViewportData.displaySetInstanceUid,
|
|
||||||
sopInstanceUid: existingViewportData.sopInstanceUid,
|
|
||||||
viewport: existingViewportData.viewport,
|
|
||||||
imageId: existingViewportData.imageId,
|
|
||||||
currentImageIdIndex: existingViewportData.currentImageIdIndex // TODO Remove this once currentImageIdIndex is removed from imageViewerViewports
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// This tests to make sure there is actually image data in this instance
|
|
||||||
// TODO: Change this when we add PDF and MPEG support
|
|
||||||
// See https://ohiforg.atlassian.net/browse/LT-227
|
|
||||||
var firstInstance = displaySet.images[0];
|
|
||||||
|
|
||||||
// All imaging modalities must have a valid value for sopClassUid or rows
|
// Get the studies and display sets sequence map
|
||||||
if (!firstInstance || (!isImage(firstInstance.sopClassUid) && !firstInstance.rows)) {
|
const sequenceMap = OHIF.viewer.getDisplaySetSequenceMap();
|
||||||
currentViewportData = {};
|
|
||||||
} else {
|
|
||||||
currentViewportData = {
|
|
||||||
viewportIndex: viewportIndex,
|
|
||||||
studyInstanceUid: study.studyInstanceUid,
|
|
||||||
seriesInstanceUid: displaySet.seriesInstanceUid,
|
|
||||||
displaySetInstanceUid: displaySet.displaySetInstanceUid,
|
|
||||||
sopInstanceUid: firstInstance.sopInstanceUid,
|
|
||||||
currentImageIdIndex: 0 // TODO Remove this once currentImageIdIndex is removed from imageViewerViewports
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.viewportData.push(currentViewportData);
|
// Check if the display sets are sequenced
|
||||||
|
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
|
||||||
|
|
||||||
viewportIndex++;
|
// Define the current viewport index and the viewport data array
|
||||||
|
let currentViewportIndex = 0;
|
||||||
|
if (viewportsAmount > oldViewportData.length && isSequenced) {
|
||||||
|
// Keep the displayed display sets
|
||||||
|
self.viewportData = oldViewportData;
|
||||||
|
currentViewportIndex = oldViewportData.length - 1;
|
||||||
|
} else if (viewportsAmount <= oldViewportData.length) {
|
||||||
|
// Reduce the original displayed display sets
|
||||||
|
self.viewportData = oldViewportData.slice(0, viewportsAmount);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Reset all display sets
|
||||||
|
self.viewportData = [];
|
||||||
|
}
|
||||||
|
|
||||||
if (viewportIndex === numViewports) {
|
// Get all the display sets for the viewer studies
|
||||||
running = false;
|
let displaySets = [];
|
||||||
return false;
|
this.studies.forEach(study => {
|
||||||
}
|
study.displaySets.forEach(displaySet => {
|
||||||
|
displaySet.images.length && displaySets.push(displaySet);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (viewportIndex === numViewports) {
|
|
||||||
running = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get the display sets that will be appended to the current ones
|
||||||
|
let appendix;
|
||||||
|
const currentLength = self.viewportData.length;
|
||||||
|
if (currentLength) {
|
||||||
|
// TODO: isolate displaySets array by study (maybe a map?)
|
||||||
|
const endIndex = currentViewportIndex + (viewportsAmount - currentLength) + 1;
|
||||||
|
appendix = displaySets.slice(currentViewportIndex + 1, endIndex);
|
||||||
|
} else {
|
||||||
|
// Get available display sets from the first to the grid size
|
||||||
|
appendix = displaySets.slice(0, viewportsAmount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the additional data based on the appendix
|
||||||
|
const additionalData = [];
|
||||||
|
appendix.forEach((displaySet, index) => {
|
||||||
|
additionalData.push({
|
||||||
|
viewportIndex: currentViewportIndex + index,
|
||||||
|
studyInstanceUid: displaySet.studyInstanceUid,
|
||||||
|
seriesInstanceUid: displaySet.seriesInstanceUid,
|
||||||
|
displaySetInstanceUid: displaySet.displaySetInstanceUid,
|
||||||
|
sopInstanceUid: displaySet.images[0].sopInstanceUid
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Append the additional data with the viewport data
|
||||||
|
self.viewportData = self.viewportData.concat(additionalData);
|
||||||
|
|
||||||
|
// Push empty objects if the amount is lesser than the grid size
|
||||||
|
while (self.viewportData.length < viewportsAmount) {
|
||||||
|
self.viewportData.push({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateViewports() {
|
updateViewports() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user