Allowing W/L Presets customization
This commit is contained in:
parent
4d9300f6c4
commit
e6b5a21ae2
@ -31,6 +31,7 @@ import './templates/form.html';
|
||||
import './templates/input.html';
|
||||
import './templates/link.html';
|
||||
import './templates/select.html';
|
||||
import './templates/tr.html';
|
||||
|
||||
// wrappers
|
||||
import './wrappers/label.html';
|
||||
|
||||
@ -141,19 +141,23 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
|
||||
component.parseData = value => {
|
||||
// Get the current schema data using component's key
|
||||
const { currentSchema } = getCurrentSchemaDefs(component.parent, instance.data.pathKey);
|
||||
const { dataType } = instance.data;
|
||||
|
||||
// Stop here if there's no schema data for current key
|
||||
if (!currentSchema) {
|
||||
// Stop here if there's no schema data for current key or no dataType defined
|
||||
if (!currentSchema && !dataType) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Check if the schema is a Number
|
||||
if (currentSchema.type === Number) {
|
||||
// Get the schema type
|
||||
const schemaType = currentSchema && currentSchema.type;
|
||||
|
||||
// Check if the type is Number
|
||||
if (schemaType === Number || dataType === 'Number') {
|
||||
return parseFloat(value);
|
||||
}
|
||||
|
||||
// Check if the schema is a Boolean
|
||||
if (currentSchema.type === Boolean) {
|
||||
// Check if the type is Boolean
|
||||
if (schemaType === Boolean || dataType === 'Boolean') {
|
||||
return !!value;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
<template name="baseTr">
|
||||
<tr
|
||||
id="{{this.id}}"
|
||||
class="{{this.class}}"
|
||||
{{this.tagAttributes}}
|
||||
>
|
||||
{{>UI.contentBlock}}
|
||||
</tr>
|
||||
</template>
|
||||
@ -1,7 +1,7 @@
|
||||
<template name="group">
|
||||
{{#baseComponent (extend this
|
||||
class=(concat 'component-group ' this.class)
|
||||
base='baseDiv'
|
||||
base=(choose this.base 'baseDiv')
|
||||
mixins=(concat 'group ' this.mixins)
|
||||
)}}
|
||||
{{>UI.contentBlock}}
|
||||
|
||||
@ -15,3 +15,7 @@ Template.registerHelper('sum', (...values) => {
|
||||
Template.registerHelper('isValidNumber', value => {
|
||||
return typeof value === 'number' && !isNaN(value);
|
||||
});
|
||||
|
||||
Template.registerHelper('filterNaN', value => {
|
||||
return isNaN(value) ? '' : value;
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@ Template.registerHelper('concat', (...args) => {
|
||||
const values = _.initial(args, 1);
|
||||
let result = '';
|
||||
_.each(values, value => {
|
||||
result += value || '';
|
||||
result += typeof value !== 'undefined' ? value : '';
|
||||
});
|
||||
return result;
|
||||
});
|
||||
|
||||
@ -42,7 +42,7 @@ HP.setEngine = protocolEngine => {
|
||||
|
||||
Meteor.startup(() => {
|
||||
HP.addCustomViewportSetting('wlPreset', 'Window/Level Preset', Object.create(null), (element, optionValue) => {
|
||||
if (optionValue in OHIF.viewer.wlPresets) {
|
||||
if (_.findWhere(OHIF.viewer.wlPresets, { id: optionValue })) {
|
||||
OHIF.viewerbase.wlPresets.applyWLPreset(optionValue, element);
|
||||
}
|
||||
});
|
||||
@ -113,7 +113,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
* with the given study. The best protocol are orded by score and returned in an array
|
||||
* @param {Object} study StudyMetadata instance object
|
||||
* @return {Array} Array of match objects or an empty array if no match was found
|
||||
* Each match object has the score of the matching and the matched
|
||||
* Each match object has the score of the matching and the matched
|
||||
* protocol
|
||||
*/
|
||||
findMatchByStudy(study) {
|
||||
@ -122,7 +122,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
const matched = [];
|
||||
const studyInstance = study.getFirstInstance();
|
||||
|
||||
// Set custom attribute for study metadata
|
||||
// Set custom attribute for study metadata
|
||||
const numberOfAvailablePriors = this.getNumberOfAvailablePriors(study.getObjectID());
|
||||
|
||||
HP.ProtocolStore.getProtocol().forEach(protocol => {
|
||||
@ -318,7 +318,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
// Set the custom attribute abstractPriorValue for the study metadata
|
||||
studyMetadata.setCustomAttribute(ABSTRACT_PRIOR_VALUE, abstractPriorValue);
|
||||
|
||||
// Also add custom attribute
|
||||
// Also add custom attribute
|
||||
const firstInstance = studyMetadata.getFirstInstance();
|
||||
if (firstInstance instanceof InstanceMetadata) {
|
||||
firstInstance.setCustomAttribute(ABSTRACT_PRIOR_VALUE, abstractPriorValue);
|
||||
@ -329,7 +329,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
|
||||
// Update the viewport to refresh layout manager with new study
|
||||
this.updateViewports(viewportIndex);
|
||||
}, error => {
|
||||
}, error => {
|
||||
OHIF.log.warn(error);
|
||||
throw new OHIFError(`ProtocolEngine::matchImages could not get study metadata for the Study with the following ObjectID: ${priorStudyObjectID}`);
|
||||
});
|
||||
@ -650,7 +650,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current stage to a new stage index in the display set sequence.
|
||||
* Changes the current stage to a new stage index in the display set sequence.
|
||||
* It checks if the next stage exists.
|
||||
*
|
||||
* @param {Integer} stageAction An integer value specifying wheater next (1) or previous (-1) stage
|
||||
@ -673,7 +673,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
// Set stage Session variable for reactivity
|
||||
Session.set('HangingProtocolStage', this.stage);
|
||||
|
||||
// Since stage has changed, we need to update the viewports
|
||||
// Since stage has changed, we need to update the viewports
|
||||
// and redo matchings
|
||||
this.updateViewports();
|
||||
|
||||
@ -682,7 +682,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of Stages in the current Protocol or
|
||||
* Retrieves the number of Stages in the current Protocol or
|
||||
* undefined if no protocol or stages are set
|
||||
*/
|
||||
getNumProtocolStages() {
|
||||
@ -710,7 +710,7 @@ HP.ProtocolEngine = class ProtocolEngine {
|
||||
*/
|
||||
previousProtocolStage() {
|
||||
OHIF.log.info('ProtocolEngine::previousProtocolStage');
|
||||
|
||||
|
||||
if (!this.setCurrentProtocolStage(-1)) {
|
||||
// Just for logging purpose
|
||||
OHIF.log.info('ProtocolEngine::previousProtocolStage failed');
|
||||
|
||||
@ -6,13 +6,13 @@ import { OHIF } from 'meteor/ohif:core';
|
||||
import { HotkeysContext } from 'meteor/ohif:hotkeys/client/classes/HotkeysContext';
|
||||
|
||||
export class HotkeysManager {
|
||||
constructor(retrieveFunction, storeFunction) {
|
||||
constructor() {
|
||||
this.contexts = {};
|
||||
this.defaults = {};
|
||||
this.currentContextName = null;
|
||||
this.enabled = new ReactiveVar(true);
|
||||
this.retrieveFunction = retrieveFunction;
|
||||
this.storeFunction = storeFunction;
|
||||
this.retrieveFunction = null;
|
||||
this.storeFunction = null;
|
||||
this.changeObserver = new Tracker.Dependency();
|
||||
|
||||
Tracker.autorun(() => {
|
||||
@ -21,6 +21,14 @@ export class HotkeysManager {
|
||||
});
|
||||
}
|
||||
|
||||
setRetrieveFunction(retrieveFunction) {
|
||||
this.retrieveFunction = retrieveFunction;
|
||||
}
|
||||
|
||||
setStoreFunction(storeFunction) {
|
||||
this.storeFunction = storeFunction;
|
||||
}
|
||||
|
||||
store(contextName, definitions) {
|
||||
const storageKey = `hotkeysDefinitions.${contextName}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -73,7 +81,11 @@ export class HotkeysManager {
|
||||
const context = this.getContext(contextName);
|
||||
if (!context) return;
|
||||
this.retrieve(contextName).then(definitions => {
|
||||
if (!definitions) return reject();
|
||||
if (!definitions) {
|
||||
this.changeObserver.changed();
|
||||
return reject();
|
||||
}
|
||||
|
||||
context.extend(definitions);
|
||||
this.changeObserver.changed();
|
||||
resolve(definitions);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template name="hotkeysDialog">
|
||||
{{#dialogSimple (extend this dialogClass='dialog-hotkeys' title='Keyboard Shortcuts')}}
|
||||
{{>hotkeysForm this}}
|
||||
{{! >hotkeysForm this}}
|
||||
<hr>
|
||||
{{>windowLevelPresetsForm this}}
|
||||
{{/dialogSimple}}
|
||||
|
||||
@ -19,9 +19,14 @@ OHIF.user.getData = key => {
|
||||
// Get the user persistent data
|
||||
const data = profile && profile.persistent;
|
||||
|
||||
if (data) {
|
||||
return data[key];
|
||||
}
|
||||
let result = data;
|
||||
const keys = key.split('.');
|
||||
keys.forEach(key => {
|
||||
if (typeof result !== 'object') return;
|
||||
result = result[key];
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Store the persistent data by giving a key and a value to store
|
||||
|
||||
@ -1,6 +1,25 @@
|
||||
<template name="windowLevelPresetsForm">
|
||||
{{#form (extend this class='form-themed' api=instance.api)}}
|
||||
{{>inputText label='W/L Preset 1' key='WLPreset1'}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Preset</th>
|
||||
<th>Name</th>
|
||||
<th>Window Level (WL)</th>
|
||||
<th>Window Width (WW)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each presetInputInformation in getPresetsInputInformationList}}
|
||||
{{#group base='baseTr' key=(concat @index)}}
|
||||
<td>{{sum @index 1}}</td>
|
||||
<td>{{>inputText key='id' value=presetInputInformation.id}}</td>
|
||||
<td>{{>inputText key='wc' value=(filterNaN presetInputInformation.wc) dataType='Number'}}</td>
|
||||
<td>{{>inputText key='ww' value=(filterNaN presetInputInformation.ww) dataType='Number'}}</td>
|
||||
{{/group}}
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="clearfix">
|
||||
{{#button class='btn btn-primary pull-right' action='save'}}Save{{/button}}
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Template.windowLevelPresetsForm.onCreated(() => {
|
||||
const instance = Template.instance();
|
||||
const { wlPresets } = OHIF.viewerbase;
|
||||
|
||||
instance.api = {
|
||||
save() {
|
||||
const form = instance.$('form').first().data('component');
|
||||
const definitions = form.value();
|
||||
// TODO: return save method with promise
|
||||
wlPresets.store(definitions);
|
||||
},
|
||||
|
||||
resetDefaults() {
|
||||
@ -17,9 +19,14 @@ Template.windowLevelPresetsForm.onCreated(() => {
|
||||
message: 'Are you sure you want to reset all the window level presets to their defaults?'
|
||||
};
|
||||
|
||||
return OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(() => {
|
||||
// TODO: return reset method with promise
|
||||
});
|
||||
return OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(() => wlPresets.resetDefaults());
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
Template.windowLevelPresetsForm.helpers({
|
||||
getPresetsInputInformationList() {
|
||||
OHIF.viewerbase.wlPresets.changeObserver.depend();
|
||||
return _.toArray(OHIF.viewer.wlPresets);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,141 +1,213 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Session } from 'meteor/session';
|
||||
|
||||
import { Tracker } from 'meteor/tracker';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { viewportUtils } from './viewportUtils';
|
||||
|
||||
const WL_PRESET_CUSTOM = 'Custom';
|
||||
const WL_PRESET_DEFAULT = 'Default';
|
||||
const WL_STORAGE_KEY = `WindowLevelPresetsDefinitions`;
|
||||
|
||||
OHIF.viewer.defaultWLPresets = {
|
||||
0: {
|
||||
id: 'SoftTissue',
|
||||
wc: 40,
|
||||
ww: 400
|
||||
},
|
||||
1: {
|
||||
id: 'Lung',
|
||||
wc: -600,
|
||||
ww: 1500
|
||||
},
|
||||
2: {
|
||||
id: 'Liver',
|
||||
wc: 90,
|
||||
ww: 150
|
||||
},
|
||||
3: {
|
||||
id: 'Bone',
|
||||
wc: 480,
|
||||
ww: 2500
|
||||
},
|
||||
4: {
|
||||
id: 'Brain',
|
||||
wc: 40,
|
||||
ww: 80
|
||||
},
|
||||
5: {},
|
||||
6: {},
|
||||
7: {},
|
||||
8: {},
|
||||
9: {}
|
||||
};
|
||||
|
||||
class WindowLevelPresetsManager {
|
||||
constructor() {
|
||||
this.defaults = {};
|
||||
this.retrieveFunction = null;
|
||||
this.storeFunction = null;
|
||||
this.changeObserver = new Tracker.Dependency();
|
||||
}
|
||||
|
||||
updateElementWLPresetData(element) {
|
||||
const wlPresetData = cornerstone.getElementData(element, 'wlPreset');
|
||||
const enabledElement = cornerstone.getEnabledElement(element);
|
||||
const { viewport, image } = enabledElement;
|
||||
const { windowCenter, windowWidth } = viewport.voi;
|
||||
let preset, presetName;
|
||||
|
||||
if (windowWidth === image.windowWidth && windowCenter === image.windowCenter) {
|
||||
presetName = WL_PRESET_DEFAULT;
|
||||
} else {
|
||||
const WLPresets = OHIF.viewer.wlPresets;
|
||||
for (let index in WLPresets) {
|
||||
const currentPreset = WLPresets[index];
|
||||
if (windowCenter === currentPreset.wc && windowWidth === currentPreset.ww) {
|
||||
preset = currentPreset;
|
||||
presetName = preset.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wlPresetData.name = presetName || WL_PRESET_CUSTOM;
|
||||
wlPresetData.ww = windowWidth;
|
||||
wlPresetData.wc = windowCenter;
|
||||
|
||||
if (wlPresetData.name === WL_PRESET_CUSTOM) {
|
||||
const custom = wlPresetData.custom || (wlPresetData.custom = Object.create(null));
|
||||
custom.ww = windowWidth;
|
||||
custom.wc = windowCenter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set specified W/L preset on given element on fallback to default W/L preset if the specified preset is not valid.
|
||||
* @param {String} presetName The desired W/L preset to be applied
|
||||
* @param {DOMElement} element An enabled viewport DOM Element.
|
||||
*/
|
||||
applyWLPreset(presetName, element) {
|
||||
const wlPresets = OHIF.viewer.wlPresets;
|
||||
const wlPresetData = cornerstone.getElementData(element, 'wlPreset');
|
||||
const viewport = cornerstone.getViewport(element);
|
||||
|
||||
const preset = wlPresets[presetName] || _.findWhere(wlPresets, { id: presetName });
|
||||
if (presetName === WL_PRESET_CUSTOM && wlPresetData.custom) {
|
||||
viewport.voi.windowWidth = wlPresetData.custom.ww;
|
||||
viewport.voi.windowCenter = wlPresetData.custom.wc;
|
||||
} else if (preset && !_.isEmpty(preset) && preset.id) {
|
||||
presetName = preset.id;
|
||||
viewport.voi.windowWidth = preset.ww;
|
||||
viewport.voi.windowCenter = preset.wc;
|
||||
} else {
|
||||
const enabledElement = cornerstone.getEnabledElement(element);
|
||||
viewport.voi.windowWidth = enabledElement.image.windowWidth;
|
||||
viewport.voi.windowCenter = enabledElement.image.windowCenter;
|
||||
presetName = WL_PRESET_DEFAULT;
|
||||
}
|
||||
|
||||
wlPresetData.name = presetName;
|
||||
wlPresetData.ww = viewport.voi.windowWidth;
|
||||
wlPresetData.wc = viewport.voi.windowCenter;
|
||||
|
||||
// Update the viewport
|
||||
cornerstone.setViewport(element, viewport);
|
||||
|
||||
OHIF.log.info('WLPresets::Applying WL Preset: ' + presetName);
|
||||
|
||||
// Notify other components about W/L Preset changes
|
||||
Session.set('OHIFWlPresetApplied', presetName);
|
||||
}
|
||||
|
||||
store(wlPresets) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.storeFunction) {
|
||||
this.storeFunction(wlPresets).then(resolve).catch(reject);
|
||||
} else if (Meteor.userId()) {
|
||||
OHIF.user.setData(WL_STORAGE_KEY, wlPresets).then(resolve).catch(reject);
|
||||
} else {
|
||||
Session.setPersistent(WL_STORAGE_KEY, wlPresets);
|
||||
resolve();
|
||||
}
|
||||
}).then(() => this.setOHIFWLPresets(wlPresets));
|
||||
}
|
||||
|
||||
retrieve() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.retrieveFunction) {
|
||||
this.retrieveFunction().then(resolve).catch(reject);
|
||||
} else if (Meteor.userId()) {
|
||||
try {
|
||||
resolve(OHIF.user.getData(WL_STORAGE_KEY));
|
||||
} catch(error) {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
resolve(Session.get(WL_STORAGE_KEY));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
load() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.retrieve().then(wlPresets => {
|
||||
if (wlPresets) {
|
||||
this.setOHIFWLPresets(wlPresets);
|
||||
} else {
|
||||
this.loadDefauls();
|
||||
}
|
||||
}).catch(this.loadDefauls);
|
||||
});
|
||||
}
|
||||
|
||||
applyWLPresetToActiveElement(presetName) {
|
||||
const element = viewportUtils.getActiveViewportElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.applyWLPreset(presetName, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides OHIF's wlPresets
|
||||
* @param {Object} wlPresets Object with wlPresets mapping
|
||||
*/
|
||||
setOHIFWLPresets(wlPresets) {
|
||||
const hasOwn = Object.prototype.hasOwnProperty;
|
||||
const presetMap = Object.create(null); // Objects without prototype have much faster lookup times
|
||||
for (let index in wlPresets) {
|
||||
if (hasOwn.call(wlPresets, index)) {
|
||||
presetMap[index] = wlPresets[index];
|
||||
}
|
||||
}
|
||||
|
||||
OHIF.viewer.wlPresets = presetMap;
|
||||
this.changeObserver.changed();
|
||||
}
|
||||
|
||||
loadDefauls() {
|
||||
this.setOHIFWLPresets(OHIF.viewer.defaultWLPresets);
|
||||
}
|
||||
|
||||
resetDefaults() {
|
||||
return this.store(OHIF.viewer.defaultWLPresets);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add this to a namespace definition
|
||||
Meteor.startup(function() {
|
||||
OHIF.viewer.defaultWLPresets = {
|
||||
SoftTissue: {
|
||||
wc: 40,
|
||||
ww: 400
|
||||
},
|
||||
Lung: {
|
||||
wc: -600,
|
||||
ww: 1500
|
||||
},
|
||||
Liver: {
|
||||
wc: 90,
|
||||
ww: 150
|
||||
},
|
||||
Bone: {
|
||||
wc: 480,
|
||||
ww: 2500
|
||||
},
|
||||
Brain: {
|
||||
wc: 40,
|
||||
ww: 80
|
||||
}
|
||||
};
|
||||
|
||||
setOHIFWLPresets(OHIF.viewer.defaultWLPresets);
|
||||
});
|
||||
|
||||
function updateElementWLPresetData(element) {
|
||||
const wlPresetData = cornerstone.getElementData(element, 'wlPreset');
|
||||
const enabledElement = cornerstone.getEnabledElement(element);
|
||||
const { viewport, image } = enabledElement;
|
||||
const { windowCenter, windowWidth } = viewport.voi;
|
||||
let presetName;
|
||||
|
||||
if (windowWidth === image.windowWidth && windowCenter === image.windowCenter) {
|
||||
presetName = WL_PRESET_DEFAULT;
|
||||
} else {
|
||||
const WLPresets = OHIF.viewer.wlPresets;
|
||||
for (let name in WLPresets) {
|
||||
const preset = WLPresets[name];
|
||||
if (windowCenter === preset.wc && windowWidth === preset.ww) {
|
||||
presetName = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wlPresetData.name = presetName || WL_PRESET_CUSTOM;
|
||||
wlPresetData.ww = windowWidth;
|
||||
wlPresetData.wc = windowCenter;
|
||||
|
||||
if (wlPresetData.name === WL_PRESET_CUSTOM) {
|
||||
const custom = wlPresetData.custom || (wlPresetData.custom = Object.create(null));
|
||||
custom.ww = windowWidth;
|
||||
custom.wc = windowCenter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set specified W/L preset on given element on fallback to default W/L preset if the specified preset is not valid.
|
||||
* @param {String} presetName The desired W/L preset to be applied
|
||||
* @param {DOMElement} element An enabled viewport DOM Element.
|
||||
*/
|
||||
function applyWLPreset(presetName, element) {
|
||||
const wlPresets = OHIF.viewer.wlPresets;
|
||||
const wlPresetData = cornerstone.getElementData(element, 'wlPreset');
|
||||
const viewport = cornerstone.getViewport(element);
|
||||
|
||||
if (presetName === WL_PRESET_CUSTOM && wlPresetData.custom) {
|
||||
viewport.voi.windowWidth = wlPresetData.custom.ww;
|
||||
viewport.voi.windowCenter = wlPresetData.custom.wc;
|
||||
} else if (presetName in wlPresets) {
|
||||
const preset = wlPresets[presetName];
|
||||
viewport.voi.windowWidth = preset.ww;
|
||||
viewport.voi.windowCenter = preset.wc;
|
||||
} else {
|
||||
const enabledElement = cornerstone.getEnabledElement(element);
|
||||
viewport.voi.windowWidth = enabledElement.image.windowWidth;
|
||||
viewport.voi.windowCenter = enabledElement.image.windowCenter;
|
||||
presetName = WL_PRESET_DEFAULT;
|
||||
}
|
||||
|
||||
wlPresetData.name = presetName;
|
||||
wlPresetData.ww = viewport.voi.windowWidth;
|
||||
wlPresetData.wc = viewport.voi.windowCenter;
|
||||
|
||||
// Update the viewport
|
||||
cornerstone.setViewport(element, viewport);
|
||||
|
||||
OHIF.log.info('WLPresets::Applying WL Preset: ' + presetName);
|
||||
|
||||
// Notify other components about W/L Preset changes
|
||||
Session.set('OHIFWlPresetApplied', presetName);
|
||||
}
|
||||
|
||||
function applyWLPresetToActiveElement(presetName) {
|
||||
const element = viewportUtils.getActiveViewportElement();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyWLPreset(presetName, element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides OHIF's wlPresets
|
||||
* @param {Object} wlPresets Object with wlPresets mapping
|
||||
*/
|
||||
function setOHIFWLPresets(wlPresets) {
|
||||
const hasOwn = Object.prototype.hasOwnProperty;
|
||||
const presetMap = Object.create(null); // Objects without prototype have much faster lookup times
|
||||
for (let name in wlPresets) {
|
||||
if (hasOwn.call(wlPresets, name)) {
|
||||
presetMap[name] = wlPresets[name];
|
||||
}
|
||||
}
|
||||
OHIF.viewer.wlPresets = presetMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export functions inside WLPresets namespace.
|
||||
*/
|
||||
const WLPresets = new WindowLevelPresetsManager();
|
||||
|
||||
const WLPresets = {
|
||||
applyWLPreset,
|
||||
applyWLPresetToActiveElement,
|
||||
setOHIFWLPresets,
|
||||
updateElementWLPresetData
|
||||
};
|
||||
Meteor.startup(() => {
|
||||
WLPresets.load();
|
||||
});
|
||||
|
||||
export { WLPresets };
|
||||
|
||||
@ -65,11 +65,16 @@ Meteor.startup(function() {
|
||||
toggleCineDialog: '',
|
||||
|
||||
// Preset hotkeys
|
||||
WLPresetSoftTissue: '1',
|
||||
WLPresetLung: '2',
|
||||
WLPresetLiver: '3',
|
||||
WLPresetBone: '4',
|
||||
WLPresetBrain: '5'
|
||||
WLPreset0: '1',
|
||||
WLPreset1: '2',
|
||||
WLPreset2: '3',
|
||||
WLPreset3: '4',
|
||||
WLPreset4: '5',
|
||||
WLPreset5: '6',
|
||||
WLPreset6: '7',
|
||||
WLPreset7: '8',
|
||||
WLPreset8: '9',
|
||||
WLPreset9: '0'
|
||||
};
|
||||
|
||||
// For now
|
||||
@ -140,23 +145,15 @@ Meteor.startup(function() {
|
||||
clearTools: 'Clear Tools'
|
||||
});
|
||||
|
||||
// Functions to register the preset switching commands
|
||||
const registerWLPresetCommands = map => _.each(map, (commandName, presetName) => {
|
||||
OHIF.commands.register(contextName, presetName, {
|
||||
name: commandName,
|
||||
action: WLPresets.applyWLPresetToActiveElement,
|
||||
params: presetName.replace('WLPreset', '')
|
||||
});
|
||||
});
|
||||
|
||||
// Register the preset switching commands
|
||||
registerWLPresetCommands({
|
||||
WLPresetSoftTissue: 'W/L Preset: Soft Tissue',
|
||||
WLPresetLung: 'W/L Preset: Lung',
|
||||
WLPresetLiver: 'W/L Preset: Liver',
|
||||
WLPresetBone: 'W/L Preset: Bone',
|
||||
WLPresetBrain: 'W/L Preset: Brain'
|
||||
});
|
||||
const applyPreset = presetName => WLPresets.applyWLPresetToActiveElement(presetName);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
OHIF.commands.register(contextName, `WLPreset${i}`, {
|
||||
name: `W/L Preset ${i + 1}`,
|
||||
action: applyPreset,
|
||||
params: i
|
||||
});
|
||||
}
|
||||
|
||||
// Register viewport navigation commands
|
||||
OHIF.commands.set(contextName, {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user