Mostly style files and Hanging Protocol changes
This commit is contained in:
parent
680beb163f
commit
21400c5836
@ -1,324 +1,3 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
OHIF.viewer = {};
|
OHIF.viewer = {};
|
||||||
|
|
||||||
// Return the display sets map sequence of display sets and viewports
|
|
||||||
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 (using 9999 to sort greater than -1)
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if all the display sets and viewports are sequenced
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if is possible to move display sets on a specific direction
|
|
||||||
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();
|
|
||||||
|
|
||||||
// Check if the display sets are sequenced
|
|
||||||
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
|
|
||||||
|
|
||||||
// Get Active Viewport Index if isMultiple is false
|
|
||||||
const activeViewportIndex = !isMultiple ? Session.get('activeViewport') : null;
|
|
||||||
|
|
||||||
// Check if is next and looping is blocked
|
|
||||||
if (isNext && !allowLooping) {
|
|
||||||
// Check if the end was reached
|
|
||||||
let endReached = true;
|
|
||||||
|
|
||||||
sequenceMap.forEach((studyViewports, study) => {
|
|
||||||
// Get active viewport index if isMultiple is false ortherwise get last
|
|
||||||
const studyViewport = studyViewports[activeViewportIndex !== null ? activeViewportIndex : studyViewports.length - 1];
|
|
||||||
if (!studyViewport) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const viewportIndex = studyViewport.displaySetIndex;
|
|
||||||
const layoutViewports = studyViewports.length;
|
|
||||||
const amount = study.displaySets.length;
|
|
||||||
const move = !isMultiple ? 1 : ((amount % layoutViewports) || layoutViewports);
|
|
||||||
const lastStepIndex = amount - move;
|
|
||||||
|
|
||||||
// 9999 for index means empty viewport, see getDisplaySetSequenceMap function
|
|
||||||
if (viewportIndex !== 9999 && viewportIndex !== lastStepIndex) {
|
|
||||||
endReached = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return false if end is not reached yet
|
|
||||||
if ((!isMultiple || isSequenced) && endReached) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if is previous and looping is blocked
|
|
||||||
if (!isNext && !allowLooping) {
|
|
||||||
// Check if the begin was reached
|
|
||||||
let beginReached = true;
|
|
||||||
|
|
||||||
if(activeViewportIndex >= 0) {
|
|
||||||
sequenceMap.forEach((studyViewports, study) => {
|
|
||||||
// Get active viewport index if isMultiple is false ortherwise get first
|
|
||||||
const studyViewport = studyViewports[activeViewportIndex !== null ? activeViewportIndex : 0];
|
|
||||||
if (!studyViewport) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const viewportIndex = studyViewport.displaySetIndex;
|
|
||||||
const layoutViewports = studyViewports.length;
|
|
||||||
|
|
||||||
// 9999 for index means empty viewport, see getDisplaySetSequenceMap function
|
|
||||||
if (viewportIndex !== 9999 && viewportIndex - layoutViewports !== -layoutViewports) {
|
|
||||||
beginReached = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return false if begin is not reached yet
|
|
||||||
if ((!isMultiple || isSequenced) && beginReached) {
|
|
||||||
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
|
|
||||||
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
|
||||||
|
|
||||||
// Get the selected viewport data
|
|
||||||
const viewportData = window.layoutManager.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 currentDisplaySet = _.findWhere(displaySets, {
|
|
||||||
displaySetInstanceUid: viewportData.displaySetInstanceUid
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the new index and ensure that it will exists in display sets
|
|
||||||
let newIndex = _.indexOf(displaySets, currentDisplaySet);
|
|
||||||
if (isNext) {
|
|
||||||
newIndex++;
|
|
||||||
if (newIndex >= displaySets.length) {
|
|
||||||
// Stop here if looping is not allowed
|
|
||||||
if (!allowLooping) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newIndex = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newIndex--;
|
|
||||||
if (newIndex < 0) {
|
|
||||||
// Stop here if looping is not allowed
|
|
||||||
if (!allowLooping) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newIndex = displaySets.length - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the display set data for the new index
|
|
||||||
const newDisplaySetData = displaySets[newIndex];
|
|
||||||
|
|
||||||
// Rerender the viewport using the new display set data
|
|
||||||
window.layoutManager.rerenderViewportWithNewDisplaySet(viewportIndex, newDisplaySetData);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Move multiple display sets forward or backward in all viewports
|
|
||||||
OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
|
|
||||||
// Get the setting that allow display set navigation looping over series
|
|
||||||
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
|
|
||||||
|
|
||||||
// Create a map to control the display set sequence
|
|
||||||
const sequenceMap = new OHIF.viewer.getDisplaySetSequenceMap();
|
|
||||||
|
|
||||||
// Check if the display sets are sequenced
|
|
||||||
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
|
|
||||||
|
|
||||||
const displaySetsToRender = [];
|
|
||||||
|
|
||||||
// Iterate over the studies map and move its display sets
|
|
||||||
sequenceMap.forEach((studyViewports, study) => {
|
|
||||||
// Sort the viewports on the study by the display set index
|
|
||||||
studyViewports.sort((a, b) => a.displaySetIndex > b.displaySetIndex);
|
|
||||||
|
|
||||||
// Get the study display sets
|
|
||||||
const displaySets = study.displaySets;
|
|
||||||
|
|
||||||
// Calculate the base index
|
|
||||||
const firstIndex = studyViewports[0].displaySetIndex;
|
|
||||||
const steps = studyViewports.length;
|
|
||||||
const rest = firstIndex % steps;
|
|
||||||
let baseIndex = rest ? firstIndex - rest : firstIndex;
|
|
||||||
const direction = isNext ? 1 : -1;
|
|
||||||
baseIndex += steps * direction;
|
|
||||||
|
|
||||||
const amount = displaySets.length;
|
|
||||||
|
|
||||||
// Check if the indexes are sequenced or will overflow the array bounds
|
|
||||||
if (baseIndex >= amount) {
|
|
||||||
const move = (amount % steps) || steps;
|
|
||||||
const lastStepIndex = amount - move;
|
|
||||||
if (firstIndex + steps !== lastStepIndex + steps) {
|
|
||||||
// Reset the index if the display sets are sequenced but shifted
|
|
||||||
baseIndex = lastStepIndex;
|
|
||||||
} else if (!allowLooping) {
|
|
||||||
// Stop here if looping is not allowed
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Start over the series if looping is allowed
|
|
||||||
baseIndex = 0;
|
|
||||||
}
|
|
||||||
} else if (baseIndex < 0) {
|
|
||||||
if (firstIndex > 0) {
|
|
||||||
// Reset the index if the display sets are sequenced but shifted
|
|
||||||
baseIndex = 0;
|
|
||||||
} else if (!allowLooping) {
|
|
||||||
// Stop here if looping is not allowed
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Go to the series' end if looping is allowed
|
|
||||||
baseIndex = (amount - 1) - ((amount - 1) % steps);
|
|
||||||
}
|
|
||||||
} else if (!isSequenced) {
|
|
||||||
// Reset the sequence if indexes are not sequenced
|
|
||||||
baseIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over the current study viewports
|
|
||||||
studyViewports.forEach(({ viewportIndex }, index) => {
|
|
||||||
// Get the new displaySet index to be rendered in viewport
|
|
||||||
const newIndex = baseIndex + index;
|
|
||||||
|
|
||||||
// Get the display set data for the new index
|
|
||||||
const displaySetData = displaySets[newIndex] || {};
|
|
||||||
|
|
||||||
// Add the current display set that on the render list
|
|
||||||
displaySetsToRender.push(displaySetData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sort the display sets
|
|
||||||
const sortingFunction = OHIF.utils.sortBy({
|
|
||||||
name: 'studyInstanceUid'
|
|
||||||
}, {
|
|
||||||
name: 'instanceNumber'
|
|
||||||
}, {
|
|
||||||
name: 'seriesNumber'
|
|
||||||
});
|
|
||||||
displaySetsToRender.sort((a, b) => sortingFunction(a, b));
|
|
||||||
|
|
||||||
// Iterate over each display set data and render on its respective viewport
|
|
||||||
displaySetsToRender.forEach((data, index) => {
|
|
||||||
window.layoutManager.rerenderViewportWithNewDisplaySet(index, data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Move display sets forward or backward
|
|
||||||
OHIF.viewer.moveDisplaySets = isNext => {
|
|
||||||
//Check if navigation is on a single or multiple viewports
|
|
||||||
if (OHIF.uiSettings.displaySetNavigationMultipleViewports) {
|
|
||||||
// Move display sets on multiple viewports
|
|
||||||
OHIF.viewer.moveMultipleViewportDisplaySets(isNext);
|
|
||||||
} else {
|
|
||||||
// Get the selected viewport index
|
|
||||||
const viewportIndex = Session.get('activeViewport');
|
|
||||||
|
|
||||||
// Move display sets on a single viewport
|
|
||||||
OHIF.viewer.moveSingleViewportDisplaySets(viewportIndex, isNext);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Router } from 'meteor/clinical:router';
|
import { Router } from 'meteor/iron:router';
|
||||||
|
|
||||||
Router.route('/playground', function() {
|
Router.route('/playground', function() {
|
||||||
this.render('componentPlayground');
|
this.render('componentPlayground');
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
|
|
||||||
// Allow attaching to jQuery selectors
|
// Allow attaching to jQuery selectors
|
||||||
$.fn.draggable = function() {
|
$.fn.draggable = function(options) {
|
||||||
OHIF.ui.makeDraggable(this);
|
makeDraggable(this, options);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,7 +11,7 @@ $.fn.draggable = function() {
|
|||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
OHIF.ui.makeDraggable = function(element) {
|
function makeDraggable(element, options) {
|
||||||
var container = $(window);
|
var container = $(window);
|
||||||
var diffX,
|
var diffX,
|
||||||
diffY,
|
diffY,
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.resizable
|
.resizable
|
||||||
transform(scale(1))
|
transform(scale(1))
|
||||||
|
|||||||
@ -16,7 +16,8 @@ Package.onUse(function(api) {
|
|||||||
api.use('reactive-var');
|
api.use('reactive-var');
|
||||||
|
|
||||||
// Router dependencies
|
// Router dependencies
|
||||||
api.use('clinical:router@2.0.18', 'client');
|
// api.use('clinical:router@2.0.18', 'client');
|
||||||
|
api.use('iron:router@1.0.13', 'client');
|
||||||
|
|
||||||
// Component's library dependencies
|
// Component's library dependencies
|
||||||
api.use('natestrauser:select2@4.0.1', 'client');
|
api.use('natestrauser:select2@4.0.1', 'client');
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import "{design}/styles/imports/animations"
|
@import "{ohif:design}/styles/imports/animations"
|
||||||
@import "{design}/styles/imports/mixins"
|
@import "{ohif:design}/styles/imports/mixins"
|
||||||
@import "{design}/styles/imports/spacings"
|
@import "{ohif:design}/styles/imports/spacings"
|
||||||
@import "{design}/styles/imports/variables"
|
@import "{ohif:design}/styles/imports/variables"
|
||||||
@import "{design}/styles/imports/theme-icons"
|
@import "{ohif:design}/styles/imports/theme-icons"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$height = 25px
|
$height = 25px
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
Package.describe({
|
Package.describe({
|
||||||
name: 'design',
|
name: 'ohif:design',
|
||||||
summary: 'OHIF Design styles and components',
|
summary: 'OHIF Design styles and components',
|
||||||
version: '0.0.1'
|
version: '0.0.1'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
html body
|
html body
|
||||||
font-family: 'Roboto', 'OpenSans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif
|
font-family: 'Roboto', 'OpenSans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
@keyframes zoomIn
|
@keyframes zoomIn
|
||||||
0%
|
0%
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
generateSpacings('', $spacer-x, $spacer-y)
|
generateSpacings('', $spacer-x, $spacer-y)
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.viewerDialogs>.dialog-animated
|
.viewerDialogs>.dialog-animated
|
||||||
&:not(.dialog-closed):not(.dialog-open)
|
&:not(.dialog-closed):not(.dialog-open)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.group-radio
|
.group-radio
|
||||||
label
|
label
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
// TODO: [design] can't we use colors that are already in common pallete?
|
// TODO: [design] can't we use colors that are already in common pallete?
|
||||||
$gray1 = #C3C3C3
|
$gray1 = #C3C3C3
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.state-error
|
.state-error
|
||||||
&+.tooltip
|
&+.tooltip
|
||||||
|
|||||||
@ -17,9 +17,6 @@ HP.studyAttributes = [{
|
|||||||
}, {
|
}, {
|
||||||
id: 'studyInstanceUid',
|
id: 'studyInstanceUid',
|
||||||
text: '(x0020000d) Study Instance UID'
|
text: '(x0020000d) Study Instance UID'
|
||||||
}, {
|
|
||||||
id: 'studyInstanceUid',
|
|
||||||
text: '(x0020000d) Study Instance UID'
|
|
||||||
}, {
|
}, {
|
||||||
id: 'studyDate',
|
id: 'studyDate',
|
||||||
text: '(x00080020) Study Date'
|
text: '(x00080020) Study Date'
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { Random } from 'meteor/random';
|
||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import 'meteor/ohif:viewerbase';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the Hanging Protocol Select2 Input
|
* Updates the Hanging Protocol Select2 Input
|
||||||
*/
|
*/
|
||||||
@ -98,7 +107,7 @@ Template.protocolEditor.helpers({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the Stage Model for the current Protocol's active Stage
|
// Retrieve the Stage Model for the current Protocol's active Stage
|
||||||
var stage = ProtocolEngine.getCurrentStageModel();
|
const stage = ProtocolEngine.getCurrentStageModel();
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -114,14 +123,14 @@ Template.protocolEditor.helpers({
|
|||||||
// by removing or adding Viewports to the stage
|
// by removing or adding Viewports to the stage
|
||||||
//
|
//
|
||||||
// First, calculate the difference, if any exists
|
// First, calculate the difference, if any exists
|
||||||
var difference = stage.viewportStructure.getNumViewports() - stage.viewports.length;
|
const difference = stage.viewportStructure.getNumViewports() - stage.viewports.length;
|
||||||
|
|
||||||
if (difference < 0) {
|
if (difference < 0) {
|
||||||
// Make the viewport difference into a positive value
|
// Make the viewport difference into a positive value
|
||||||
var absDifference = Math.abs(difference);
|
const absDifference = Math.abs(difference);
|
||||||
|
|
||||||
// If there are more Viewports defined than necessary, remove the extraneous Viewports
|
// If there are more Viewports defined than necessary, remove the extraneous Viewports
|
||||||
var position = stage.viewports.length - absDifference;
|
const position = stage.viewports.length - absDifference;
|
||||||
|
|
||||||
// Splice extra viewports from the Stage's viewports array
|
// Splice extra viewports from the Stage's viewports array
|
||||||
stage.viewports.splice(position, absDifference);
|
stage.viewports.splice(position, absDifference);
|
||||||
@ -130,9 +139,9 @@ Template.protocolEditor.helpers({
|
|||||||
// required amount
|
// required amount
|
||||||
|
|
||||||
// Count up until the difference in number of Viewports
|
// Count up until the difference in number of Viewports
|
||||||
for (var i = 0; i < difference; i++) {
|
for (let i = 0; i < difference; i++) {
|
||||||
// Instantiate a new Viewport Model
|
// Instantiate a new Viewport Model
|
||||||
var viewport = new HP.Viewport();
|
const viewport = new HP.Viewport();
|
||||||
|
|
||||||
// Add new Viewports to the Stage's viewports array
|
// Add new Viewports to the Stage's viewports array
|
||||||
stage.viewports.push(viewport);
|
stage.viewports.push(viewport);
|
||||||
@ -154,7 +163,7 @@ Template.protocolEditor.events({
|
|||||||
*/
|
*/
|
||||||
'click #newProtocol'() {
|
'click #newProtocol'() {
|
||||||
// Clone the default Protocol
|
// Clone the default Protocol
|
||||||
var protocol = HP.defaultProtocol.createClone();
|
const protocol = HP.defaultProtocol.createClone();
|
||||||
|
|
||||||
// Change the Protocol name to state that it is New, and give it a timestamp
|
// Change the Protocol name to state that it is New, and give it a timestamp
|
||||||
protocol.name = 'New (created ' + moment().format('h:mm:ss a') + ')';
|
protocol.name = 'New (created ' + moment().format('h:mm:ss a') + ')';
|
||||||
@ -175,19 +184,19 @@ Template.protocolEditor.events({
|
|||||||
* Rename the current Protocol
|
* Rename the current Protocol
|
||||||
*/
|
*/
|
||||||
'click #renameProtocol'() {
|
'click #renameProtocol'() {
|
||||||
var selectedProtocol = this;
|
const selectedProtocol = this;
|
||||||
if (selectedProtocol.locked) {
|
if (selectedProtocol.locked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define some details for the text entry dialog
|
// Define some details for the text entry dialog
|
||||||
var title = 'Rename Protocol';
|
const title = 'Rename Protocol';
|
||||||
var instructions = 'Enter a new name';
|
const instructions = 'Enter a new name';
|
||||||
var currentValue = selectedProtocol.name;
|
const currentValue = selectedProtocol.name;
|
||||||
|
|
||||||
// Open the text entry dialog with the details above
|
// Open the text entry dialog with the details above
|
||||||
// and fire the callback function when finished.
|
// and fire the callback function when finished.
|
||||||
openTextEntryDialog(title, instructions, currentValue, function(value) {
|
openTextEntryDialog(title, instructions, currentValue, value => {
|
||||||
// Update the name with the entered text
|
// Update the name with the entered text
|
||||||
selectedProtocol.name = value;
|
selectedProtocol.name = value;
|
||||||
|
|
||||||
@ -211,17 +220,17 @@ Template.protocolEditor.events({
|
|||||||
*
|
*
|
||||||
* @param event The Change event for the input
|
* @param event The Change event for the input
|
||||||
*/
|
*/
|
||||||
'change .btn-file :file': function(event) {
|
'change .btn-file :file'(event) {
|
||||||
// http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/
|
// http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/
|
||||||
|
|
||||||
// Find the Input in the DOM
|
// Find the Input in the DOM
|
||||||
var input = $(event.currentTarget);
|
const input = $(event.currentTarget);
|
||||||
|
|
||||||
// Get the number of selected files
|
// Get the number of selected files
|
||||||
var numFiles = input.get(0).files ? input.get(0).files.length : 1;
|
const numFiles = input.get(0).files ? input.get(0).files.length : 1;
|
||||||
|
|
||||||
// Get the label of the file
|
// Get the label of the file
|
||||||
var label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
|
const label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
|
||||||
|
|
||||||
// Trigger our custom event with the number of files and label
|
// Trigger our custom event with the number of files and label
|
||||||
input.trigger('fileselect', [numFiles, label]);
|
input.trigger('fileselect', [numFiles, label]);
|
||||||
@ -231,15 +240,15 @@ Template.protocolEditor.events({
|
|||||||
*
|
*
|
||||||
* @param event The custom fileselect event
|
* @param event The custom fileselect event
|
||||||
*/
|
*/
|
||||||
'fileselect .btn-file :file': function(event) {
|
'fileselect .btn-file :file'(event) {
|
||||||
// Retreieve the FileList
|
// Retreieve the FileList
|
||||||
var files = event.target.files;
|
const files = event.target.files;
|
||||||
|
|
||||||
// Create an HTML5 File Reader
|
// Create an HTML5 File Reader
|
||||||
var reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
var protocolToImport = JSON.parse(reader.result);
|
const protocolToImport = JSON.parse(reader.result);
|
||||||
|
|
||||||
// Insert the protocol
|
// Insert the protocol
|
||||||
HP.ProtocolStore.addProtocol(protocolToImport);
|
HP.ProtocolStore.addProtocol(protocolToImport);
|
||||||
@ -257,12 +266,14 @@ Template.protocolEditor.events({
|
|||||||
*
|
*
|
||||||
* @param event The select2:select event
|
* @param event The select2:select event
|
||||||
*/
|
*/
|
||||||
'select2:select #protocolSelect': function(event) {
|
'select2:select #protocolSelect'(event) {
|
||||||
// Retrieve the protocolId
|
// Retrieve the protocolId
|
||||||
var protocolId = event.params.data.id;
|
const protocolId = event.params.data.id;
|
||||||
|
|
||||||
// Retrieve the protocol from the protocol store
|
// Retrieve the Protocol from the HangingProtocols Collection
|
||||||
var selectedProtocol = HP.ProtocolStore.getProtocol(protocolId);
|
const selectedProtocol = HangingProtocols.findOne({
|
||||||
|
id: protocolId
|
||||||
|
});
|
||||||
|
|
||||||
// If it doesn't exist, stop here
|
// If it doesn't exist, stop here
|
||||||
if (!selectedProtocol) {
|
if (!selectedProtocol) {
|
||||||
@ -280,92 +291,85 @@ Template.protocolEditor.events({
|
|||||||
$(this).addClass('active').siblings().removeClass('active');
|
$(this).addClass('active').siblings().removeClass('active');
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Update the protocol with the latest changes to the current Protocol
|
* Update the HangingProtocols Collection with the latest changes to the current Protocol
|
||||||
*/
|
*/
|
||||||
'click #saveProtocol'() {
|
'click #saveProtocol'() {
|
||||||
var selectedProtocol = this;
|
const selectedProtocol = this;
|
||||||
if (selectedProtocol.locked) {
|
if (selectedProtocol.locked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the ID for the update call
|
||||||
|
const id = selectedProtocol._id;
|
||||||
|
|
||||||
|
// Remove the MongoDB _id property so that we can
|
||||||
|
// simplify the $set value
|
||||||
|
delete selectedProtocol._id;
|
||||||
|
|
||||||
// Update the Protocol's modifiedDate and modifiedBy User details
|
// Update the Protocol's modifiedDate and modifiedBy User details
|
||||||
selectedProtocol.protocolWasModified();
|
selectedProtocol.protocolWasModified();
|
||||||
|
|
||||||
// Update the current Protocol in the database with the latest changes
|
// Update the current Protocol in the database with the latest changes
|
||||||
HP.ProtocolStore.updateProtocol(selectedProtocol.id, selectedProtocol);
|
HangingProtocols.update(id, {
|
||||||
|
$set: selectedProtocol
|
||||||
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Save the current Protocol as a new document
|
* Save the current Protocol as a new document in the HangingProtocols Collection
|
||||||
*/
|
*/
|
||||||
'click #saveAsProtocol'() {
|
'click #saveAsProtocol'() {
|
||||||
var selectedProtocol = this;
|
const selectedProtocol = this;
|
||||||
|
|
||||||
// Clone the selected Protocol
|
|
||||||
var protocol = selectedProtocol.createClone();
|
|
||||||
|
|
||||||
// Define some details for the text entry dialog
|
// Define some details for the text entry dialog
|
||||||
var title = 'Save Protocol As';
|
const title = 'Save Protocol As';
|
||||||
var instructions = 'Enter a new name';
|
const instructions = 'Enter a new name';
|
||||||
var currentValue = protocol.name;
|
const currentValue = selectedProtocol.name;
|
||||||
|
|
||||||
// Open the text entry dialog with the details above
|
// Open the text entry dialog with the details above
|
||||||
// and fire the callback function when finished.
|
// and fire the callback function when finished.
|
||||||
openTextEntryDialog(title, instructions, currentValue, function(value) {
|
openTextEntryDialog(title, instructions, currentValue, value => {
|
||||||
|
// Erase the MongoDB _id
|
||||||
|
delete selectedProtocol._id;
|
||||||
|
|
||||||
// Create a new ID for the protocol
|
// Create a new ID for the protocol
|
||||||
protocol.id = Random.id();
|
selectedProtocol.id = Random.id();
|
||||||
|
|
||||||
// Update the name with the entered text
|
// Update the name with the entered text
|
||||||
protocol.name = value;
|
selectedProtocol.name = value;
|
||||||
|
|
||||||
// Unlock the protocol
|
|
||||||
protocol.locked = false;
|
|
||||||
|
|
||||||
// Update the Protocol's modifiedDate and modifiedBy User details
|
// Update the Protocol's modifiedDate and modifiedBy User details
|
||||||
protocol.protocolWasModified();
|
selectedProtocol.protocolWasModified();
|
||||||
|
|
||||||
// Insert the new Protocol
|
// Insert the new Protocol
|
||||||
HP.ProtocolStore.addProtocol(protocol);
|
HangingProtocols.insert(selectedProtocol);
|
||||||
|
|
||||||
// Activate the new Protocol using the ProtocolEngine
|
|
||||||
ProtocolEngine.setHangingProtocol(protocol);
|
|
||||||
|
|
||||||
// Update the protocol selector to display the new Protocols
|
|
||||||
updateProtocolSelect();
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Export the currently selected Protocol as a JSON file
|
* Export the currently selected Protocol as a JSON file
|
||||||
*/
|
*/
|
||||||
'click #exportJSON'() {
|
'click #exportJSON'() {
|
||||||
var selectedProtocol = this;
|
// Tell the User's Browser to download the JSON file by routing a hidden iframe to our
|
||||||
|
// protocol-export Route. This prevents the tab from changing its current content.
|
||||||
var protocolJSON = JSON.stringify(selectedProtocol, null, 2),
|
const selectedProtocol = this;
|
||||||
currentDate = new Date(),
|
document.getElementById('download_iframe').src = '/protocol-export/' + selectedProtocol.id;
|
||||||
filename = selectedProtocol.name + '-' + (currentDate.getTime().toString()) + '.json',
|
|
||||||
protocolBlob = new Blob([protocolJSON], { type: 'application/json' });
|
|
||||||
|
|
||||||
var downloadElement = document.getElementById('downloadElement');
|
|
||||||
downloadElement.href = URL.createObjectURL(protocolBlob);
|
|
||||||
downloadElement.download = filename;
|
|
||||||
downloadElement.click();
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Delete the currently selected Protocol
|
* Delete the currently selected Protocol
|
||||||
*/
|
*/
|
||||||
'click #deleteProtocol'() {
|
'click #deleteProtocol'() {
|
||||||
var selectedProtocol = this;
|
const selectedProtocol = this;
|
||||||
if (selectedProtocol.locked) {
|
if (selectedProtocol.locked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {
|
const options = {
|
||||||
title: 'Delete Protocol',
|
title: 'Delete Protocol',
|
||||||
text: 'Are you sure you would like to remove this Protocol? This cannot be reversed.'
|
text: 'Are you sure you would like to remove this Protocol? This cannot be reversed.'
|
||||||
};
|
};
|
||||||
|
|
||||||
showConfirmDialog(() => {
|
OHIF.viewerbase.showConfirmDialog(() => {
|
||||||
// Remove the Protocol
|
// Send a call to remove the Protocol from the HangingProtocols Collection on the server
|
||||||
HP.ProtocolStore.removeProtocol(selectedProtocol.id);
|
Meteor.call('removeHangingProtocol', selectedProtocol._id);
|
||||||
|
|
||||||
// Reset the ProtocolEngine to the next best match
|
// Reset the ProtocolEngine to the next best match
|
||||||
ProtocolEngine.reset();
|
ProtocolEngine.reset();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$height = 20px
|
$height = 20px
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { $ } from 'meteor/jquery';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Blaze } from 'meteor/blaze';
|
||||||
|
|
||||||
var keys = {
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
||||||
|
|
||||||
|
const keys = {
|
||||||
ESC: 27
|
ESC: 27
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,7 +17,7 @@ var keys = {
|
|||||||
*
|
*
|
||||||
* @param dialog The DOM element of the dialog to close
|
* @param dialog The DOM element of the dialog to close
|
||||||
*/
|
*/
|
||||||
function closeHandler(dialog) {
|
const closeHandler = dialog => {
|
||||||
// Hide the lesion dialog
|
// Hide the lesion dialog
|
||||||
$(dialog).css('display', 'none');
|
$(dialog).css('display', 'none');
|
||||||
|
|
||||||
@ -18,8 +25,8 @@ function closeHandler(dialog) {
|
|||||||
$('.removableBackdrop').remove();
|
$('.removableBackdrop').remove();
|
||||||
|
|
||||||
// Restore the focus to the active viewport
|
// Restore the focus to the active viewport
|
||||||
setFocusToActiveViewport();
|
Viewerbase.setFocusToActiveViewport();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays and updates the UI of the Rule Entry Dialog given a new set of
|
* Displays and updates the UI of the Rule Entry Dialog given a new set of
|
||||||
@ -32,10 +39,10 @@ function closeHandler(dialog) {
|
|||||||
*/
|
*/
|
||||||
openRuleEntryDialog = function(attributes, level, rule) {
|
openRuleEntryDialog = function(attributes, level, rule) {
|
||||||
// Get the lesion location dialog
|
// Get the lesion location dialog
|
||||||
var dialog = $('.ruleEntryDialog');
|
const dialog = $('.ruleEntryDialog');
|
||||||
|
|
||||||
// Clear any input that is still on the page
|
// Clear any input that is still on the page
|
||||||
var currentValueInput = dialog.find('input.currentValue');
|
const currentValueInput = dialog.find('input.currentValue');
|
||||||
currentValueInput.val('');
|
currentValueInput.val('');
|
||||||
|
|
||||||
// Store the Dialog DOM data, rule level and rule in the template data
|
// Store the Dialog DOM data, rule level and rule in the template data
|
||||||
@ -44,7 +51,7 @@ openRuleEntryDialog = function(attributes, level, rule) {
|
|||||||
Template.ruleEntryDialog.rule = rule;
|
Template.ruleEntryDialog.rule = rule;
|
||||||
|
|
||||||
// Initialize the Select2 search box for the attribute list
|
// Initialize the Select2 search box for the attribute list
|
||||||
var attributeSelect = dialog.find('.attributes');
|
const attributeSelect = dialog.find('.attributes');
|
||||||
attributeSelect.html('').select2({
|
attributeSelect.html('').select2({
|
||||||
data: attributes,
|
data: attributes,
|
||||||
placeholder: 'Select an attribute',
|
placeholder: 'Select an attribute',
|
||||||
@ -63,15 +70,15 @@ openRuleEntryDialog = function(attributes, level, rule) {
|
|||||||
|
|
||||||
// If a rule has been provided, use its constraint to find the relevant Comparator
|
// If a rule has been provided, use its constraint to find the relevant Comparator
|
||||||
if (rule && rule.constraint) {
|
if (rule && rule.constraint) {
|
||||||
var validator = Object.keys(rule.constraint)[0];
|
const validator = Object.keys(rule.constraint)[0];
|
||||||
var validatorOption = Object.keys(rule.constraint[validator])[0];
|
const validatorOption = Object.keys(rule.constraint[validator])[0];
|
||||||
var comparator = Comparators.findOne({
|
const comparator = Comparators.findOne({
|
||||||
validator: validator,
|
validator: validator,
|
||||||
validatorOption: validatorOption
|
validatorOption: validatorOption
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the current value input based on the rule constraint
|
// Set the current value input based on the rule constraint
|
||||||
var currentValue = rule.constraint[validator][validatorOption];
|
const currentValue = rule.constraint[validator][validatorOption];
|
||||||
currentValueInput.val(currentValue);
|
currentValueInput.val(currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +93,10 @@ openRuleEntryDialog = function(attributes, level, rule) {
|
|||||||
dialog.css('display', 'block');
|
dialog.css('display', 'block');
|
||||||
|
|
||||||
// Show the backdrop
|
// Show the backdrop
|
||||||
UI.render(Template.removableBackdrop, document.body);
|
Blaze.render(Template.removableBackdrop, document.body);
|
||||||
|
|
||||||
// Make sure the context menu is closed when the user clicks away
|
// Make sure the context menu is closed when the user clicks away
|
||||||
$('.removableBackdrop').one('mousedown touchstart', function() {
|
$('.removableBackdrop').one('mousedown touchstart', () => {
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -99,23 +106,23 @@ openRuleEntryDialog = function(attributes, level, rule) {
|
|||||||
*/
|
*/
|
||||||
function getActiveViewportImageId() {
|
function getActiveViewportImageId() {
|
||||||
// Retrieve the active viewport index from the Session
|
// Retrieve the active viewport index from the Session
|
||||||
var activeViewport = Session.get('activeViewport');
|
const activeViewport = Session.get('activeViewport');
|
||||||
if (activeViewport === undefined) {
|
if (activeViewport === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the list of all Viewports on the page
|
// Obtain the list of all Viewports on the page
|
||||||
var viewports = $('.imageViewerViewport');
|
const viewports = $('.imageViewerViewport');
|
||||||
|
|
||||||
// Retrieve the active viewport element
|
// Retrieve the active viewport element
|
||||||
var element = viewports.get(activeViewport);
|
const element = viewports.get(activeViewport);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the enabled element from Cornerstone
|
// Obtain the enabled element from Cornerstone
|
||||||
try {
|
try {
|
||||||
var enabledElement = cornerstone.getEnabledElement(element);
|
const enabledElement = cornerstone.getEnabledElement(element);
|
||||||
if (!enabledElement) {
|
if (!enabledElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -128,7 +135,7 @@ function getActiveViewportImageId() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getAbstractPriorValue(imageId) {
|
function getAbstractPriorValue(imageId) {
|
||||||
var currentStudy = ViewerStudies.findOne({}, {
|
const currentStudy = ViewerStudies.findOne({}, {
|
||||||
sort: {
|
sort: {
|
||||||
studyDate: -1
|
studyDate: -1
|
||||||
},
|
},
|
||||||
@ -139,12 +146,12 @@ function getAbstractPriorValue(imageId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var priorStudy = cornerstoneTools.metaData.get('study', imageId);
|
const priorStudy = cornerstoneTools.metaData.get('study', imageId);
|
||||||
if (!priorStudy) {
|
if (!priorStudy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var studies = StudyListStudies.find({
|
const studies = StudyListStudies.find({
|
||||||
patientId: currentStudy.patientId,
|
patientId: currentStudy.patientId,
|
||||||
studyDate: {
|
studyDate: {
|
||||||
$lt: currentStudy.studyDate
|
$lt: currentStudy.studyDate
|
||||||
@ -155,7 +162,7 @@ function getAbstractPriorValue(imageId) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var priorIndex = 0;
|
let priorIndex = 0;
|
||||||
|
|
||||||
// TODO: Check what the abstract prior value should equal for an unrelated study?
|
// TODO: Check what the abstract prior value should equal for an unrelated study?
|
||||||
studies.forEach(function(study, index) {
|
studies.forEach(function(study, index) {
|
||||||
@ -176,7 +183,7 @@ function getAbstractPriorValue(imageId) {
|
|||||||
*/
|
*/
|
||||||
function getCurrentAttributeValue(attribute, level) {
|
function getCurrentAttributeValue(attribute, level) {
|
||||||
// Retrieve the active viewport's imageId. If none exists, stop here
|
// Retrieve the active viewport's imageId. If none exists, stop here
|
||||||
var imageId = getActiveViewportImageId();
|
const imageId = getActiveViewportImageId();
|
||||||
if (!imageId) {
|
if (!imageId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -193,7 +200,7 @@ function getCurrentAttributeValue(attribute, level) {
|
|||||||
|
|
||||||
// Retrieve the metadata values for the specified level from
|
// Retrieve the metadata values for the specified level from
|
||||||
// the Cornerstone Tools metaData provider
|
// the Cornerstone Tools metaData provider
|
||||||
var metadata = cornerstoneTools.metaData.get(level, imageId);
|
const metadata = cornerstoneTools.metaData.get(level, imageId);
|
||||||
|
|
||||||
if (metadata[attribute] === undefined) {
|
if (metadata[attribute] === undefined) {
|
||||||
return HP.attributeDefaults[attribute];
|
return HP.attributeDefaults[attribute];
|
||||||
@ -204,7 +211,7 @@ function getCurrentAttributeValue(attribute, level) {
|
|||||||
|
|
||||||
Template.ruleEntryDialog.onCreated(function() {
|
Template.ruleEntryDialog.onCreated(function() {
|
||||||
// Define the ReactiveVars that will be used to link aspects of the UI
|
// Define the ReactiveVars that will be used to link aspects of the UI
|
||||||
var template = this;
|
const template = this;
|
||||||
// Note: currentValue's initial value must be a string so the template renders properly
|
// Note: currentValue's initial value must be a string so the template renders properly
|
||||||
template.currentValue = new ReactiveVar('');
|
template.currentValue = new ReactiveVar('');
|
||||||
template.attribute = new ReactiveVar();
|
template.attribute = new ReactiveVar();
|
||||||
@ -213,12 +220,12 @@ Template.ruleEntryDialog.onCreated(function() {
|
|||||||
|
|
||||||
Template.ruleEntryDialog.onRendered(function() {
|
Template.ruleEntryDialog.onRendered(function() {
|
||||||
// Initialize the Comparators Select2 box
|
// Initialize the Comparators Select2 box
|
||||||
var template = Template.instance();
|
const template = Template.instance();
|
||||||
template.$('.comparators').select2();
|
template.$('.comparators').select2();
|
||||||
|
|
||||||
// Get the default Comparator from the Select2 box and use it to
|
// Get the default Comparator from the Select2 box and use it to
|
||||||
// initialize the comparatorId ReactiveVar
|
// initialize the comparatorId ReactiveVar
|
||||||
var comparatorId = template.$('.comparators').val();
|
const comparatorId = template.$('.comparators').val();
|
||||||
template.comparatorId.set(comparatorId);
|
template.comparatorId.set(comparatorId);
|
||||||
|
|
||||||
const dialog = template.$('.ruleEntryDialog');
|
const dialog = template.$('.ruleEntryDialog');
|
||||||
@ -229,7 +236,7 @@ Template.ruleEntryDialog.helpers({
|
|||||||
/**
|
/**
|
||||||
* Returns the Comparators Collection to the Template with reactive rerendering
|
* Returns the Comparators Collection to the Template with reactive rerendering
|
||||||
*/
|
*/
|
||||||
comparators: function() {
|
comparators() {
|
||||||
return Comparators.find();
|
return Comparators.find();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -237,7 +244,7 @@ Template.ruleEntryDialog.helpers({
|
|||||||
*
|
*
|
||||||
* @returns {*} Attribute value for the active image
|
* @returns {*} Attribute value for the active image
|
||||||
*/
|
*/
|
||||||
currentValue: function() {
|
currentValue() {
|
||||||
return Template.instance().currentValue.get();
|
return Template.instance().currentValue.get();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -249,15 +256,15 @@ Template.ruleEntryDialog.events({
|
|||||||
* @param event the Click event
|
* @param event the Click event
|
||||||
* @param template The template context
|
* @param template The template context
|
||||||
*/
|
*/
|
||||||
'click #save': function(event, template) {
|
'click #save'(event, template) {
|
||||||
// Retrieve the input properties to the template
|
// Retrieve the input properties to the template
|
||||||
var dialog = Template.ruleEntryDialog.dialog;
|
const dialog = Template.ruleEntryDialog.dialog;
|
||||||
var level = Template.ruleEntryDialog.level;
|
const level = Template.ruleEntryDialog.level;
|
||||||
|
|
||||||
// Retrieve the current values for the attribute value and comparatorId
|
// Retrieve the current values for the attribute value and comparatorId
|
||||||
var attribute = template.attribute.get();
|
const attribute = template.attribute.get();
|
||||||
var comparatorId = template.comparatorId.get();
|
const comparatorId = template.comparatorId.get();
|
||||||
var currentValue = template.currentValue.get();
|
const currentValue = template.currentValue.get();
|
||||||
|
|
||||||
// If currentValue input is undefined, prevent saving this rule
|
// If currentValue input is undefined, prevent saving this rule
|
||||||
if (currentValue === undefined) {
|
if (currentValue === undefined) {
|
||||||
@ -265,14 +272,14 @@ Template.ruleEntryDialog.events({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if we are editing a rule or creating a new one
|
// Check if we are editing a rule or creating a new one
|
||||||
var rule;
|
let rule;
|
||||||
if (Template.ruleEntryDialog.rule) {
|
if (Template.ruleEntryDialog.rule) {
|
||||||
// If we are editing a rule, change the rule data
|
// If we are editing a rule, change the rule data
|
||||||
rule = Template.ruleEntryDialog.rule;
|
rule = Template.ruleEntryDialog.rule;
|
||||||
} else {
|
} else {
|
||||||
// If we are creating a rule, obtain the active Viewport model
|
// If we are creating a rule, obtain the active Viewport model
|
||||||
// from the Protocol and Stage
|
// from the Protocol and Stage
|
||||||
var viewport = getActiveViewportModel();
|
const viewport = getActiveViewportModel();
|
||||||
|
|
||||||
// Create a rule depending on the level property of this dialog
|
// Create a rule depending on the level property of this dialog
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -296,12 +303,12 @@ Template.ruleEntryDialog.events({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the Comparator from the Comparators Collection given its ID
|
// Find the Comparator from the Comparators Collection given its ID
|
||||||
var comparator = Comparators.findOne({
|
const comparator = Comparators.findOne({
|
||||||
id: comparatorId
|
id: comparatorId
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a new constraint to add to the rule
|
// Create a new constraint to add to the rule
|
||||||
var constraint = {};
|
const constraint = {};
|
||||||
constraint[comparator.validator] = {};
|
constraint[comparator.validator] = {};
|
||||||
constraint[comparator.validator][comparator.validatorOption] = currentValue;
|
constraint[comparator.validator][comparator.validatorOption] = currentValue;
|
||||||
|
|
||||||
@ -310,7 +317,7 @@ Template.ruleEntryDialog.events({
|
|||||||
rule.constraint = constraint;
|
rule.constraint = constraint;
|
||||||
|
|
||||||
// Instruct the Protocol Engine to update the Layout Manager with new data
|
// Instruct the Protocol Engine to update the Layout Manager with new data
|
||||||
var viewportIndex = Session.get('activeViewport');
|
const viewportIndex = Session.get('activeViewport');
|
||||||
ProtocolEngine.updateViewports(viewportIndex);
|
ProtocolEngine.updateViewports(viewportIndex);
|
||||||
|
|
||||||
// Close the dialog
|
// Close the dialog
|
||||||
@ -319,8 +326,8 @@ Template.ruleEntryDialog.events({
|
|||||||
/**
|
/**
|
||||||
* Allow the user to click the Cancel button to close the dialog
|
* Allow the user to click the Cancel button to close the dialog
|
||||||
*/
|
*/
|
||||||
'click #cancel': function() {
|
'click #cancel'() {
|
||||||
var dialog = Template.ruleEntryDialog.dialog;
|
const dialog = Template.ruleEntryDialog.dialog;
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -329,8 +336,8 @@ Template.ruleEntryDialog.events({
|
|||||||
* @param event The Keydown event details
|
* @param event The Keydown event details
|
||||||
* @returns {boolean} Return false to prevent bubbling of the event
|
* @returns {boolean} Return false to prevent bubbling of the event
|
||||||
*/
|
*/
|
||||||
'keydown .ruleEntryDialog': function(event) {
|
'keydown .ruleEntryDialog'(event) {
|
||||||
var dialog = Template.ruleEntryDialog.dialog;
|
const dialog = Template.ruleEntryDialog.dialog;
|
||||||
|
|
||||||
// If Esc key is pressed, close the dialog
|
// If Esc key is pressed, close the dialog
|
||||||
if (event.which === keys.ESC) {
|
if (event.which === keys.ESC) {
|
||||||
@ -344,9 +351,9 @@ Template.ruleEntryDialog.events({
|
|||||||
* @param event The Change event for the select box
|
* @param event The Change event for the select box
|
||||||
* @param template The current template context
|
* @param template The current template context
|
||||||
*/
|
*/
|
||||||
'change select.attributes': function(event, template) {
|
'change select.attributes'(event, template) {
|
||||||
// Obtain the user-specified attribute to test against
|
// Obtain the user-specified attribute to test against
|
||||||
var attribute = $(event.currentTarget).val();
|
const attribute = $(event.currentTarget).val();
|
||||||
|
|
||||||
// Store it in the ReactiveVar
|
// Store it in the ReactiveVar
|
||||||
template.attribute.set(attribute);
|
template.attribute.set(attribute);
|
||||||
@ -355,10 +362,10 @@ Template.ruleEntryDialog.events({
|
|||||||
Template.ruleEntryDialog.selectedAttribute = attribute;
|
Template.ruleEntryDialog.selectedAttribute = attribute;
|
||||||
|
|
||||||
// Get the level of this dialog
|
// Get the level of this dialog
|
||||||
var level = Template.ruleEntryDialog.level;
|
const level = Template.ruleEntryDialog.level;
|
||||||
|
|
||||||
// Retrieve the current value of the attribute for the active viewport model
|
// Retrieve the current value of the attribute for the active viewport model
|
||||||
var value = getCurrentAttributeValue(attribute, level);
|
const value = getCurrentAttributeValue(attribute, level);
|
||||||
|
|
||||||
// Update the ReactiveVar with the user-specified value
|
// Update the ReactiveVar with the user-specified value
|
||||||
template.currentValue.set(value);
|
template.currentValue.set(value);
|
||||||
@ -369,12 +376,12 @@ Template.ruleEntryDialog.events({
|
|||||||
* @param event The Change event for the input
|
* @param event The Change event for the input
|
||||||
* @param template The current template context
|
* @param template The current template context
|
||||||
*/
|
*/
|
||||||
'change input.currentValue': function(event, template) {
|
'change input.currentValue'(event, template) {
|
||||||
// Get the DOM element representing the input box
|
// Get the DOM element representing the input box
|
||||||
var input = $(event.currentTarget);
|
const input = $(event.currentTarget);
|
||||||
|
|
||||||
// Get the current value of the input
|
// Get the current value of the input
|
||||||
var value = input.val();
|
let value = input.val();
|
||||||
|
|
||||||
// If the input is of type 'number', parse it as a Float
|
// If the input is of type 'number', parse it as a Float
|
||||||
if (input.attr('type') === 'number') {
|
if (input.attr('type') === 'number') {
|
||||||
@ -390,9 +397,9 @@ Template.ruleEntryDialog.events({
|
|||||||
* @param event The Change event for the select box
|
* @param event The Change event for the select box
|
||||||
* @param template The current template context
|
* @param template The current template context
|
||||||
*/
|
*/
|
||||||
'change select.comparators': function(event, template) {
|
'change select.comparators'(event, template) {
|
||||||
// Get the current value of the select box
|
// Get the current value of the select box
|
||||||
var comparatorId = $(event.currentTarget).val();
|
const comparatorId = $(event.currentTarget).val();
|
||||||
|
|
||||||
// Update the ReactiveVar with the value of the Comparators select box
|
// Update the ReactiveVar with the value of the Comparators select box
|
||||||
template.comparatorId.set(comparatorId);
|
template.comparatorId.set(comparatorId);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.ruleEntryDialog
|
.ruleEntryDialog
|
||||||
theme('background', '$uiGrayDarkest', 0.95)
|
theme('background', '$uiGrayDarkest', 0.95)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
table.ruleTable
|
table.ruleTable
|
||||||
thead
|
thead
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
var keys = {
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
import { Blaze } from 'meteor/blaze';
|
||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
|
||||||
|
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
||||||
|
|
||||||
|
const keys = {
|
||||||
ESC: 27
|
ESC: 27
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -8,7 +16,7 @@ var keys = {
|
|||||||
*
|
*
|
||||||
* @param dialog The DOM element of the dialog to close
|
* @param dialog The DOM element of the dialog to close
|
||||||
*/
|
*/
|
||||||
function closeHandler(dialog) {
|
const closeHandler = dialog => {
|
||||||
// Hide the lesion dialog
|
// Hide the lesion dialog
|
||||||
$(dialog).css('display', 'none');
|
$(dialog).css('display', 'none');
|
||||||
|
|
||||||
@ -16,8 +24,8 @@ function closeHandler(dialog) {
|
|||||||
$('.removableBackdrop').remove();
|
$('.removableBackdrop').remove();
|
||||||
|
|
||||||
// Restore the focus to the active viewport
|
// Restore the focus to the active viewport
|
||||||
setFocusToActiveViewport();
|
Viewerbase.setFocusToActiveViewport();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays and updates the UI of the Setting Entry Dialog given an
|
* Displays and updates the UI of the Setting Entry Dialog given an
|
||||||
@ -27,40 +35,40 @@ function closeHandler(dialog) {
|
|||||||
*/
|
*/
|
||||||
openSettingEntryDialog = function(settingObject) {
|
openSettingEntryDialog = function(settingObject) {
|
||||||
// Get the lesion location dialog
|
// Get the lesion location dialog
|
||||||
var dialog = $('.settingEntryDialog');
|
const dialog = $('.settingEntryDialog');
|
||||||
|
|
||||||
// Store the Dialog DOM data, setting level and setting in the template data
|
// Store the Dialog DOM data, setting level and setting in the template data
|
||||||
Template.settingEntryDialog.dialog = dialog;
|
Template.settingEntryDialog.dialog = dialog;
|
||||||
Template.settingEntryDialog.settingObject = settingObject;
|
Template.settingEntryDialog.settingObject = settingObject;
|
||||||
|
|
||||||
// Initialize the Select2 search box for the attribute list
|
// Initialize the Select2 search box for the attribute list
|
||||||
var settings = Object.keys(HP.displaySettings);
|
const settings = Object.keys(HP.displaySettings);
|
||||||
settings.concat(Object.keys(HP.CustomViewportSettings));
|
settings.concat(Object.keys(HP.CustomViewportSettings));
|
||||||
|
|
||||||
var displaySettingsOptions = Object.keys(HP.displaySettings).map(key => {
|
const displaySettingsOptions = Object.keys(HP.displaySettings).map(key => {
|
||||||
return {
|
return {
|
||||||
id: key,
|
id: key,
|
||||||
text: HP.displaySettings[key].text
|
text: HP.displaySettings[key].text
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var customSettingsOptions = Object.keys(HP.CustomViewportSettings).map(key => {
|
const customSettingsOptions = Object.keys(HP.CustomViewportSettings).map(key => {
|
||||||
return {
|
return {
|
||||||
id: key,
|
id: key,
|
||||||
text: HP.CustomViewportSettings[key].text
|
text: HP.CustomViewportSettings[key].text
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
var settingsOptions = displaySettingsOptions.concat(customSettingsOptions);
|
const settingsOptions = displaySettingsOptions.concat(customSettingsOptions);
|
||||||
|
|
||||||
var settingSelect = dialog.find('.settings');
|
const settingSelect = dialog.find('.settings');
|
||||||
settingSelect.html('').select2({
|
settingSelect.html('').select2({
|
||||||
data: settingsOptions,
|
data: settingsOptions,
|
||||||
placeholder: 'Select a setting',
|
placeholder: 'Select a setting',
|
||||||
allowClear: true
|
allowClear: true
|
||||||
});
|
});
|
||||||
|
|
||||||
var settingDetails = {
|
let settingDetails = {
|
||||||
options: []
|
options: []
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +78,7 @@ openSettingEntryDialog = function(settingObject) {
|
|||||||
settingDetails = HP.CustomViewportSettings[settingObject.id];
|
settingDetails = HP.CustomViewportSettings[settingObject.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
var valueSelect = dialog.find('.currentValue');
|
const valueSelect = dialog.find('.currentValue');
|
||||||
valueSelect.html('').select2({
|
valueSelect.html('').select2({
|
||||||
data: settingDetails.options,
|
data: settingDetails.options,
|
||||||
placeholder: 'Select a value',
|
placeholder: 'Select a value',
|
||||||
@ -99,14 +107,14 @@ openSettingEntryDialog = function(settingObject) {
|
|||||||
Blaze.render(Template.removableBackdrop, document.body);
|
Blaze.render(Template.removableBackdrop, document.body);
|
||||||
|
|
||||||
// Make sure the context menu is closed when the user clicks away
|
// Make sure the context menu is closed when the user clicks away
|
||||||
$('.removableBackdrop').one('mousedown touchstart', function() {
|
$('.removableBackdrop').one('mousedown touchstart', () => {
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Template.settingEntryDialog.onCreated(function() {
|
Template.settingEntryDialog.onCreated(function() {
|
||||||
// Define the ReactiveVars that will be used to link aspects of the UI
|
// Define the ReactiveVars that will be used to link aspects of the UI
|
||||||
var template = this;
|
const template = this;
|
||||||
|
|
||||||
// Note: currentValue's initial value must be a string so the template renders properly
|
// Note: currentValue's initial value must be a string so the template renders properly
|
||||||
template.currentValue = new ReactiveVar('');
|
template.currentValue = new ReactiveVar('');
|
||||||
@ -126,29 +134,29 @@ Template.settingEntryDialog.events({
|
|||||||
* @param event the Click event
|
* @param event the Click event
|
||||||
* @param template The template context
|
* @param template The template context
|
||||||
*/
|
*/
|
||||||
'click #save': function(event, template) {
|
'click #save'(event, template) {
|
||||||
// Retrieve the input properties to the template
|
// Retrieve the input properties to the template
|
||||||
var dialog = Template.settingEntryDialog.dialog;
|
const dialog = Template.settingEntryDialog.dialog;
|
||||||
|
|
||||||
// Retrieve the current values for the id and current value
|
// Retrieve the current values for the id and current value
|
||||||
var setting = template.setting.get();
|
const setting = template.setting.get();
|
||||||
var currentValue = template.currentValue.get();
|
const currentValue = template.currentValue.get();
|
||||||
|
|
||||||
// If currentValue input is undefined, prevent saving this setting
|
// If currentValue input is undefined, prevent saving this setting
|
||||||
if (currentValue === undefined) {
|
if (currentValue === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportSetting = {
|
const viewportSetting = {
|
||||||
id: setting,
|
id: setting,
|
||||||
value: currentValue
|
value: currentValue
|
||||||
};
|
};
|
||||||
|
|
||||||
// Obtain the active Viewport model from the Protocol and Stage
|
// Obtain the active Viewport model from the Protocol and Stage
|
||||||
var viewport = getActiveViewportModel();
|
const viewport = getActiveViewportModel();
|
||||||
|
|
||||||
// Remove any old rules if the ID has been changes
|
// Remove any old rules if the ID has been changes
|
||||||
var originalSettingObject = Template.settingEntryDialog.settingObject;
|
const originalSettingObject = Template.settingEntryDialog.settingObject;
|
||||||
if (originalSettingObject && originalSettingObject.id) {
|
if (originalSettingObject && originalSettingObject.id) {
|
||||||
delete viewport.viewportSettings[originalSettingObject.id];
|
delete viewport.viewportSettings[originalSettingObject.id];
|
||||||
}
|
}
|
||||||
@ -157,7 +165,7 @@ Template.settingEntryDialog.events({
|
|||||||
viewport.viewportSettings[viewportSetting.id] = viewportSetting.value;
|
viewport.viewportSettings[viewportSetting.id] = viewportSetting.value;
|
||||||
|
|
||||||
// Instruct the Protocol Engine to update the Layout Manager with new data
|
// Instruct the Protocol Engine to update the Layout Manager with new data
|
||||||
var viewportIndex = Session.get('activeViewport');
|
const viewportIndex = Session.get('activeViewport');
|
||||||
ProtocolEngine.updateViewports(viewportIndex);
|
ProtocolEngine.updateViewports(viewportIndex);
|
||||||
|
|
||||||
// Close the dialog
|
// Close the dialog
|
||||||
@ -166,8 +174,8 @@ Template.settingEntryDialog.events({
|
|||||||
/**
|
/**
|
||||||
* Allow the user to click the Cancel button to close the dialog
|
* Allow the user to click the Cancel button to close the dialog
|
||||||
*/
|
*/
|
||||||
'click #cancel': function() {
|
'click #cancel'() {
|
||||||
var dialog = Template.settingEntryDialog.dialog;
|
const dialog = Template.settingEntryDialog.dialog;
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -176,8 +184,8 @@ Template.settingEntryDialog.events({
|
|||||||
* @param event The Keydown event details
|
* @param event The Keydown event details
|
||||||
* @returns {boolean} Return false to prevent bubbling of the event
|
* @returns {boolean} Return false to prevent bubbling of the event
|
||||||
*/
|
*/
|
||||||
'keydown .settingEntryDialog': function(event) {
|
'keydown .settingEntryDialog'(event) {
|
||||||
var dialog = Template.settingEntryDialog.dialog;
|
const dialog = Template.settingEntryDialog.dialog;
|
||||||
|
|
||||||
// If Esc key is pressed, close the dialog
|
// If Esc key is pressed, close the dialog
|
||||||
if (event.which === keys.ESC) {
|
if (event.which === keys.ESC) {
|
||||||
@ -191,15 +199,15 @@ Template.settingEntryDialog.events({
|
|||||||
* @param event The Change event for the select box
|
* @param event The Change event for the select box
|
||||||
* @param template The current template context
|
* @param template The current template context
|
||||||
*/
|
*/
|
||||||
'change select.settings': function(event, template) {
|
'change select.settings'(event, template) {
|
||||||
// Obtain the user-specified attribute to test against
|
// Obtain the user-specified attribute to test against
|
||||||
var settingId = $(event.currentTarget).val();
|
const settingId = $(event.currentTarget).val();
|
||||||
|
|
||||||
// Store it in the ReactiveVar
|
// Store it in the ReactiveVar
|
||||||
template.setting.set(settingId);
|
template.setting.set(settingId);
|
||||||
|
|
||||||
// Retrieve the current value from the attribute
|
// Retrieve the current value from the attribute
|
||||||
var settingDetails = {
|
let settingDetails = {
|
||||||
options: []
|
options: []
|
||||||
};
|
};
|
||||||
if (settingId && HP.displaySettings[settingId]) {
|
if (settingId && HP.displaySettings[settingId]) {
|
||||||
@ -208,8 +216,8 @@ Template.settingEntryDialog.events({
|
|||||||
settingDetails = HP.CustomViewportSettings[settingId];
|
settingDetails = HP.CustomViewportSettings[settingId];
|
||||||
}
|
}
|
||||||
|
|
||||||
var dialog = Template.settingEntryDialog.dialog;
|
const dialog = Template.settingEntryDialog.dialog;
|
||||||
var valueSelect = dialog.find('.currentValue');
|
const valueSelect = dialog.find('.currentValue');
|
||||||
valueSelect.html('').select2({
|
valueSelect.html('').select2({
|
||||||
data: settingDetails.options,
|
data: settingDetails.options,
|
||||||
placeholder: 'Select a value',
|
placeholder: 'Select a value',
|
||||||
@ -228,9 +236,9 @@ Template.settingEntryDialog.events({
|
|||||||
* @param event The Change event for the input
|
* @param event The Change event for the input
|
||||||
* @param template The current template context
|
* @param template The current template context
|
||||||
*/
|
*/
|
||||||
'change select.currentValue': function(event, template) {
|
'change select.currentValue'(event, template) {
|
||||||
// Get the current value of the select box
|
// Get the current value of the select box
|
||||||
var value = $(event.currentTarget).val();
|
const value = $(event.currentTarget).val();
|
||||||
|
|
||||||
// Update the ReactiveVar with the user-specified value
|
// Update the ReactiveVar with the user-specified value
|
||||||
template.currentValue.set(value);
|
template.currentValue.set(value);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.settingEntryDialog
|
.settingEntryDialog
|
||||||
theme('border', '1px solid $uiBorderColor', 0.95)
|
theme('border', '1px solid $uiBorderColor', 0.95)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
table.settingsTable
|
table.settingsTable
|
||||||
thead
|
thead
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
#stageDetails
|
#stageDetails
|
||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
#stageSortingContainer
|
#stageSortingContainer
|
||||||
padding: 0 20px
|
padding: 0 20px
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.textEntryDialog
|
.textEntryDialog
|
||||||
theme('border', '1px solid $uiBorderColor', 0.95)
|
theme('border', '1px solid $uiBorderColor', 0.95)
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
// OHIF Modules
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import 'meteor/ohif:viewerbase';
|
||||||
|
|
||||||
// Define a global variable that will be used to refer to the Protocol Engine
|
// Define a global variable that will be used to refer to the Protocol Engine
|
||||||
// It must be populated by HP.setEngine when the Viewer is initialized and a ProtocolEngine
|
// It must be populated by HP.setEngine when the Viewer is initialized and a ProtocolEngine
|
||||||
@ -74,7 +79,7 @@ HP.addCustomViewportSetting = function(settingId, settingName, options, callback
|
|||||||
Meteor.startup(function() {
|
Meteor.startup(function() {
|
||||||
HP.addCustomViewportSetting('wlPreset', 'Window/Level Preset', Object.keys(OHIF.viewer.wlPresets), function(element, optionValue) {
|
HP.addCustomViewportSetting('wlPreset', 'Window/Level Preset', Object.keys(OHIF.viewer.wlPresets), function(element, optionValue) {
|
||||||
if (OHIF.viewer.wlPresets.hasOwnProperty(optionValue)) {
|
if (OHIF.viewer.wlPresets.hasOwnProperty(optionValue)) {
|
||||||
applyWLPreset(optionValue, element);
|
OHIF.viewerbase.wlPresets.applyWLPreset(optionValue, element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -191,7 +196,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
|||||||
findMatchByStudy(study) {
|
findMatchByStudy(study) {
|
||||||
var matched = [];
|
var matched = [];
|
||||||
|
|
||||||
HP.ProtocolStore.getProtocol().forEach(protocol => {
|
HangingProtocols.find().forEach(protocol => {
|
||||||
// Clone the protocol's protocolMatchingRules array
|
// Clone the protocol's protocolMatchingRules array
|
||||||
// We clone it so that we don't accidentally add the
|
// We clone it so that we don't accidentally add the
|
||||||
// numberOfPriorsReferenced rule to the Protocol itself.
|
// numberOfPriorsReferenced rule to the Protocol itself.
|
||||||
@ -220,7 +225,9 @@ HP.ProtocolEngine = class ProtocolEngine {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!matched.length) {
|
if (!matched.length) {
|
||||||
var defaultProtocol = HP.ProtocolStore.getProtocol('defaultProtocol');
|
var defaultProtocol = HangingProtocols.findOne({
|
||||||
|
id: 'defaultProtocol'
|
||||||
|
});
|
||||||
|
|
||||||
return [{
|
return [{
|
||||||
score: 1,
|
score: 1,
|
||||||
@ -403,7 +410,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
|||||||
if (!alreadyLoaded) {
|
if (!alreadyLoaded) {
|
||||||
getStudyMetadata(priorStudy.studyInstanceUid, study => {
|
getStudyMetadata(priorStudy.studyInstanceUid, study => {
|
||||||
study.abstractPriorValue = abstractPriorValue;
|
study.abstractPriorValue = abstractPriorValue;
|
||||||
study.displaySets = createStacks(study);
|
study.displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
|
||||||
ViewerStudies.insert(study);
|
ViewerStudies.insert(study);
|
||||||
this.studies.push(study);
|
this.studies.push(study);
|
||||||
this.matchImages(viewport);
|
this.matchImages(viewport);
|
||||||
@ -437,7 +444,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
|||||||
// This tests to make sure there is actually image data in this instance
|
// This tests to make sure there is actually image data in this instance
|
||||||
// TODO: Change this when we add PDF and MPEG support
|
// TODO: Change this when we add PDF and MPEG support
|
||||||
// See https://ohiforg.atlassian.net/browse/LT-227
|
// See https://ohiforg.atlassian.net/browse/LT-227
|
||||||
if (!isImage(instance.sopClassUid) && !instance.rows) {
|
if (!OHIF.viewerbase.isImage(instance.sopClassUid) && !instance.rows) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +489,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
|||||||
// If the instance was found, set the displaySet ID
|
// If the instance was found, set the displaySet ID
|
||||||
if (displaySet) {
|
if (displaySet) {
|
||||||
imageDetails.displaySetInstanceUid = displaySet.displaySetInstanceUid;
|
imageDetails.displaySetInstanceUid = displaySet.displaySetInstanceUid;
|
||||||
imageDetails.imageId = getImageId(instance);
|
imageDetails.imageId = OHIF.viewerbase.getImageId(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((totalMatchScore > highestImageMatchingScore) || !bestMatch) {
|
if ((totalMatchScore > highestImageMatchingScore) || !bestMatch) {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Package.onUse(function(api) {
|
|||||||
api.use('random');
|
api.use('random');
|
||||||
api.use('templating');
|
api.use('templating');
|
||||||
api.use('natestrauser:select2@4.0.1', 'client');
|
api.use('natestrauser:select2@4.0.1', 'client');
|
||||||
api.use('clinical:router');
|
api.use('iron:router@1.0.13');
|
||||||
api.use('momentjs:moment');
|
api.use('momentjs:moment');
|
||||||
api.use('validatejs');
|
api.use('validatejs');
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
#aboutModal
|
#aboutModal
|
||||||
.logo
|
.logo
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.thumbnailEntry.active .imageThumbnail
|
.thumbnailEntry.active .imageThumbnail
|
||||||
theme('border-color', '$activeColor')
|
theme('border-color', '$activeColor')
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$seriesCountBackgroundColor = #678696
|
$seriesCountBackgroundColor = #678696
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.annotationDialog
|
.annotationDialog
|
||||||
theme('border', '1px solid $uiBorderColor', 0.95)
|
theme('border', '1px solid $uiBorderColor', 0.95)
|
||||||
|
|||||||
@ -1,45 +1,47 @@
|
|||||||
<template name="cineDialog">
|
<template name="cineDialog">
|
||||||
{{#form id='cineDialog' class=(getClassNames 'dialog-animated noselect') schema=instance.schema api=instance.api}}
|
<dialog id="cineDialog">
|
||||||
{{>inputHidden key='intervalId'}}
|
{{#form id='cineDialogForm' class=(getClassNames 'dialog-animated noselect') schema=instance.schema api=instance.api}}
|
||||||
<div class="cine-navigation">
|
{{>inputHidden key='intervalId'}}
|
||||||
<div class="btn-group">
|
<div class="cine-navigation">
|
||||||
{{#button class='btn' disabled=(displaySetDisabled false) action='displaySetPrevious' title='Previous display set'}}
|
<div class="btn-group">
|
||||||
<i class="fa fa-toggle-up"></i>
|
{{#button class='btn' disabled=(displaySetDisabled false) action='displaySetPrevious' title='Previous display set'}}
|
||||||
{{/button}}
|
<i class="fa fa-toggle-up"></i>
|
||||||
{{#button class='btn' disabled=(displaySetDisabled true) action='displaySetNext' title='Next display set'}}
|
{{/button}}
|
||||||
<i class="fa fa-toggle-down"></i>
|
{{#button class='btn' disabled=(displaySetDisabled true) action='displaySetNext' title='Next display set'}}
|
||||||
{{/button}}
|
<i class="fa fa-toggle-down"></i>
|
||||||
|
{{/button}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="cine-controls">
|
||||||
<div class="cine-controls">
|
<div class="btn-group">
|
||||||
<div class="btn-group">
|
{{#button class='btn' action='cineFirst' title='Skip to first image' disabled=(buttonDisabled)}}
|
||||||
{{#button class='btn' action='cineFirst' title='Skip to first image' disabled=(buttonDisabled)}}
|
<i class="fa fa-fast-backward"></i>
|
||||||
<i class="fa fa-fast-backward"></i>
|
{{/button}}
|
||||||
{{/button}}
|
{{#button class='btn' action='cinePrevious' title='Previous image' disabled=(buttonDisabled)}}
|
||||||
{{#button class='btn' action='cinePrevious' title='Previous image' disabled=(buttonDisabled)}}
|
<i class="fa fa-step-backward"></i>
|
||||||
<i class="fa fa-step-backward"></i>
|
{{/button}}
|
||||||
{{/button}}
|
{{#button class='btn' action='cineToggle' title='Play / Stop' class=(concat 'btn ' (valueIf isPlaying 'active' '')) disabled=(buttonDisabled)}}
|
||||||
{{#button class='btn' action='cineToggle' title='Play / Stop' class=(concat 'btn ' (valueIf isPlaying 'active' '')) disabled=(buttonDisabled)}}
|
{{#if isPlaying}}
|
||||||
{{#if isPlaying}}
|
<i class="fa fa-fw fa-stop"></i>
|
||||||
<i class="fa fa-fw fa-stop"></i>
|
{{else}}
|
||||||
{{else}}
|
<i class="fa fa-fw fa-play"></i>
|
||||||
<i class="fa fa-fw fa-play"></i>
|
{{/if}}
|
||||||
{{/if}}
|
{{/button}}
|
||||||
{{/button}}
|
{{#button class='btn' action='cineNext' title='Next image' disabled=(buttonDisabled)}}
|
||||||
{{#button class='btn' action='cineNext' title='Next image' disabled=(buttonDisabled)}}
|
<i class="fa fa-step-forward"></i>
|
||||||
<i class="fa fa-step-forward"></i>
|
{{/button}}
|
||||||
{{/button}}
|
{{#button class='btn' action='cineLast' title='Skip to last image' disabled=(buttonDisabled)}}
|
||||||
{{#button class='btn' action='cineLast' title='Skip to last image' disabled=(buttonDisabled)}}
|
<i class="fa fa-fast-forward"></i>
|
||||||
<i class="fa fa-fast-forward"></i>
|
{{/button}}
|
||||||
{{/button}}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="cine-options">
|
||||||
<div class="cine-options">
|
<div class="fps-section">
|
||||||
<div class="fps-section">
|
{{#inputRange key='framesPerSecond' class='p-a-0' labelClass='form-group m-a-0' labelAsDiv=true}}
|
||||||
{{#inputRange key='framesPerSecond' class='p-a-0' labelClass='form-group m-a-0' labelAsDiv=true}}
|
{{/inputRange}}
|
||||||
{{/inputRange}}
|
</div>
|
||||||
|
<span id="fps">{{framerate}} fps</span>
|
||||||
</div>
|
</div>
|
||||||
<span id="fps">{{framerate}} fps</span>
|
{{/form}}
|
||||||
</div>
|
</dialog>
|
||||||
{{/form}}
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
#cineDialog
|
#cineDialog
|
||||||
theme('border', '2px solid $uiBorderColor', 0.95)
|
theme('border', '2px solid $uiBorderColor', 0.95)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
#imageViewerViewports
|
#imageViewerViewports
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$imageSliderBorderRadius = 57px
|
$imageSliderBorderRadius = 57px
|
||||||
$imageSliderTrackColor = rgba(0,0,0,0)
|
$imageSliderTrackColor = rgba(0,0,0,0)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.imageViewerViewport
|
.imageViewerViewport
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$borderColor = rgba(77, 99, 110, 0.81)
|
$borderColor = rgba(77, 99, 110, 0.81)
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.imageViewerLoadingIndicator
|
.imageViewerLoadingIndicator
|
||||||
theme('color', '$textSecondaryColor')
|
theme('color', '$textSecondaryColor')
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$switchSize = 55px
|
$switchSize = 55px
|
||||||
$seriesSpacing = 2px
|
$seriesSpacing = 2px
|
||||||
@ -121,7 +121,7 @@ $seriesSpacing = 2px
|
|||||||
width: $switchSize + $seriesSpacing
|
width: $switchSize + $seriesSpacing
|
||||||
|
|
||||||
.seriesItem
|
.seriesItem
|
||||||
theme('background-color', '$boxBackgroundColor')
|
theme('background-color', '$boxBackgroundColor')Dark
|
||||||
border-radius: 3px
|
border-radius: 3px
|
||||||
height: 15px
|
height: 15px
|
||||||
margin: $seriesSpacing
|
margin: $seriesSpacing
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.studyTimepointWrapper
|
.studyTimepointWrapper
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$timepointButtonHeight = 55px
|
$timepointButtonHeight = 55px
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$boxBorderColor = transparent
|
$boxBorderColor = transparent
|
||||||
$boxHoverBackgroundColor = #14191E
|
$boxHoverBackgroundColor = #14191E
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.toolbarSectionButton
|
.toolbarSectionButton
|
||||||
theme('color', '$defaultColor')
|
theme('color', '$defaultColor')
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$distance = 10px
|
$distance = 10px
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
.viewerMain
|
.viewerMain
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import "{design}/app"
|
@import "{ohif:design}/app"
|
||||||
|
|
||||||
$viewportTagPadding = 20px
|
$viewportTagPadding = 20px
|
||||||
|
|
||||||
@ -48,3 +48,4 @@ $viewportTagPadding = 20px
|
|||||||
margin: 2px
|
margin: 2px
|
||||||
width: 18px
|
width: 18px
|
||||||
height: 18px
|
height: 18px
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user