AWV-1: Refactoring layout manager
This commit is contained in:
parent
0469747b5a
commit
e98e686664
@ -97,7 +97,7 @@ Template.toolbarSection.helpers({
|
||||
title: 'Previous',
|
||||
classes: 'imageViewerCommand',
|
||||
buttonTemplateName: 'displaySetNavigation',
|
||||
isPrevious: true
|
||||
isNext: false
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
@ -105,7 +105,7 @@ Template.toolbarSection.helpers({
|
||||
title: 'Next',
|
||||
classes: 'imageViewerCommand',
|
||||
buttonTemplateName: 'displaySetNavigation',
|
||||
isPrevious: false
|
||||
isNext: true
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
|
||||
@ -2,6 +2,107 @@ import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
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
|
||||
OHIF.viewer.moveSingleViewportDisplaySets = (viewportIndex, isNext) => {
|
||||
// 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
|
||||
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
||||
|
||||
// Get the viewport data list
|
||||
const viewportDataList = window.layoutManager.viewportData;
|
||||
// Create a map to control the display set sequence
|
||||
const sequenceMap = new OHIF.viewer.getDisplaySetSequenceMap();
|
||||
|
||||
// Create a map to control the display set movement
|
||||
const moveMap = new Map();
|
||||
|
||||
// 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
|
||||
});
|
||||
});
|
||||
// Check if the display sets are sequenced
|
||||
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
|
||||
|
||||
// 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
|
||||
studyViewports.sort((a, b) => a.displaySetIndex > b.displaySetIndex);
|
||||
|
||||
@ -114,13 +182,17 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
||||
const direction = isNext ? 1 : -1;
|
||||
baseIndex += amount * direction;
|
||||
|
||||
// Check if the base index will be outside the array bounds
|
||||
if (baseIndex >= displaySets.length) {
|
||||
// Check if the indexes are sequenced or will overflow the array bounds
|
||||
if (!isSequenced) {
|
||||
// Reset the sequence if indexes are not sequenced
|
||||
baseIndex = 0;
|
||||
} else if (baseIndex >= displaySets.length) {
|
||||
// Stop here if looping is not allowed
|
||||
if (!allowLooping) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start over the series if looping is allowed
|
||||
baseIndex = 0;
|
||||
} else if (baseIndex < 0) {
|
||||
// Stop here if looping is not allowed
|
||||
@ -128,6 +200,7 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Go to the series' end if looping is allowed
|
||||
baseIndex = (displaySets.length - 1) - ((displaySets.length - 1) % amount);
|
||||
}
|
||||
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
<template name="displaySetNavigation">
|
||||
<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}}">
|
||||
<div class="svgContainer">
|
||||
{{#if isPrevious}}
|
||||
<i class="fa fa-toggle-up fa-fw"></i>
|
||||
{{else}}
|
||||
{{#if isNext}}
|
||||
<i class="fa fa-toggle-down fa-fw"></i>
|
||||
{{else}}
|
||||
<i class="fa fa-toggle-up fa-fw"></i>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="buttonLabel" disabled="{{#if (disableButton isPrevious)}}disabled{{/if}}">
|
||||
{{#if isPrevious}}Previous{{else}}Next{{/if}}
|
||||
<div class="buttonLabel">
|
||||
{{#if isNext}}Next{{else}}Previous{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -3,16 +3,25 @@ import { Template } from 'meteor/templating';
|
||||
|
||||
Template.displaySetNavigation.events({
|
||||
'click .js-next'(event, instance) {
|
||||
if ($(event.currentTarget).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
OHIF.viewer.moveDisplaySets(true);
|
||||
},
|
||||
|
||||
'click .js-prev'(event, instance) {
|
||||
if ($(event.currentTarget).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
OHIF.viewer.moveDisplaySets(false);
|
||||
}
|
||||
});
|
||||
|
||||
Template.displaySetNavigation.helpers({
|
||||
disableButton(isPrevious) {
|
||||
|
||||
disableButton(isNext) {
|
||||
Session.get('LayoutManagerUpdated');
|
||||
return !OHIF.viewer.canMoveDisplaySets(isNext);
|
||||
}
|
||||
});
|
||||
|
||||
@ -25,68 +25,74 @@ LayoutManager = class LayoutManager {
|
||||
}
|
||||
|
||||
setDefaultViewportData() {
|
||||
var numViewports = this.getNumberOfViewports();
|
||||
const self = this;
|
||||
|
||||
var viewportIndex = 0;
|
||||
var self = this;
|
||||
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;
|
||||
}
|
||||
// Get the number of vieports to be rendered
|
||||
const viewportsAmount = this.getNumberOfViewports();
|
||||
|
||||
var currentViewportData;
|
||||
var existingViewportData = oldViewportData[viewportIndex];
|
||||
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];
|
||||
// Store the old viewport data and reset the current
|
||||
const oldViewportData = self.viewportData;
|
||||
|
||||
// All imaging modalities must have a valid value for sopClassUid or rows
|
||||
if (!firstInstance || (!isImage(firstInstance.sopClassUid) && !firstInstance.rows)) {
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
// Get the studies and display sets sequence map
|
||||
const sequenceMap = OHIF.viewer.getDisplaySetSequenceMap();
|
||||
|
||||
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) {
|
||||
running = false;
|
||||
return false;
|
||||
}
|
||||
// Get all the display sets for the viewer studies
|
||||
let displaySets = [];
|
||||
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() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user