LT-275: Storing the selected label and description on measurements collection
This commit is contained in:
parent
20a2a8e453
commit
cd5a1277aa
@ -1,3 +1,5 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Session } from 'meteor/session';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Session.set('TimepointsReady', false);
|
||||
@ -102,5 +104,36 @@ Template.viewer.events({
|
||||
},
|
||||
'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance, eventData) {
|
||||
OHIF.measurements.MeasurementHandlers.onRemoved(event, instance, eventData);
|
||||
},
|
||||
CornerstoneToolsMouseClick(event, instance, data) {
|
||||
const element = instance.$('.imageViewerViewport')[0];
|
||||
|
||||
const toolState = cornerstoneTools.getToolState(element, 'bidirectional');
|
||||
|
||||
// Stop here if no tool state was found
|
||||
if (!toolState) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectLabelCallback = (options, value, description) => {
|
||||
console.warn('>>>>options, value, description', options, value, description);
|
||||
};
|
||||
|
||||
setTimeout(() => {
|
||||
for (let i = 0; i < toolState.data.length; i++) {
|
||||
const toolData = toolState.data[i];
|
||||
if (toolData.active) {
|
||||
OHIF.measurements.toggleLabelButton({
|
||||
instance,
|
||||
toolData,
|
||||
element,
|
||||
measurementApi: instance.data.measurementApi,
|
||||
position: data.currentPoints.page,
|
||||
callback: selectLabelCallback
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template name="wrapperLabel">
|
||||
{{#unless this.labelAsDiv}}
|
||||
<label class="wrapperLabel {{this.labelClass}}">
|
||||
<label class="wrapperLabel {{this.labelClass}}" {{clone this.labelTagAttributes}}>
|
||||
{{#wrapperLabelContent}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/wrapperLabelContent}}
|
||||
</label>
|
||||
{{else}}
|
||||
<div class="wrapperLabel {{this.labelClass}}">
|
||||
<div class="wrapperLabel {{this.labelClass}}" {{clone this.labelTagAttributes}}>
|
||||
{{#wrapperLabelContent}}
|
||||
{{>UI.contentBlock}}
|
||||
{{/wrapperLabelContent}}
|
||||
|
||||
@ -4,26 +4,26 @@ import { MeasurementSchemaTypes } from 'meteor/ohif:measurements/both/schema/mea
|
||||
const CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema;
|
||||
|
||||
const BidirectionalHandlesSchema = new SimpleSchema({
|
||||
start: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Start'
|
||||
},
|
||||
end: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'End'
|
||||
},
|
||||
perpendicularStart: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Perpendicular Start'
|
||||
},
|
||||
perpendicularEnd: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Perpendicular End'
|
||||
},
|
||||
textBox: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Text Box'
|
||||
},
|
||||
start: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Start'
|
||||
},
|
||||
end: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'End'
|
||||
},
|
||||
perpendicularStart: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Perpendicular Start'
|
||||
},
|
||||
perpendicularEnd: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Perpendicular End'
|
||||
},
|
||||
textBox: {
|
||||
type: CornerstoneHandleSchema,
|
||||
label: 'Text Box'
|
||||
},
|
||||
});
|
||||
|
||||
const BidirectionalSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, {
|
||||
@ -31,36 +31,46 @@ const BidirectionalSchema = new SimpleSchema([MeasurementSchemaTypes.Cornerstone
|
||||
type: BidirectionalHandlesSchema,
|
||||
label: 'Handles'
|
||||
},
|
||||
location: {
|
||||
type: String,
|
||||
label: 'Location',
|
||||
optional: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
label: 'Description',
|
||||
optional: true
|
||||
},
|
||||
longestDiameter: {
|
||||
type: Number,
|
||||
label: 'Longest Diameter',
|
||||
type: Number,
|
||||
label: 'Longest Diameter',
|
||||
decimal: true
|
||||
},
|
||||
shortestDiameter: {
|
||||
type: Number,
|
||||
label: 'Shortest Diameter',
|
||||
type: Number,
|
||||
label: 'Shortest Diameter',
|
||||
decimal: true
|
||||
},
|
||||
locationUid: {
|
||||
type: String,
|
||||
label: 'Location UID',
|
||||
type: String,
|
||||
label: 'Location UID',
|
||||
optional: true // Optional because it is added after initial drawing, via a callback
|
||||
}
|
||||
}]);
|
||||
|
||||
function displayFunction(data) {
|
||||
// Check whether this is a Nodal or Extranodal Measurement
|
||||
const targetType = 'target';
|
||||
const nodalType = data.isNodal ? 'nodal' : 'extraNodal';
|
||||
// const targetType = 'target';
|
||||
// const nodalType = data.isNodal ? 'nodal' : 'extraNodal';
|
||||
|
||||
// Get criteria types
|
||||
const criteriaTypes = TrialCriteriaTypes.find({
|
||||
selected: true
|
||||
}).map(criteria => {
|
||||
return criteria.id;
|
||||
});
|
||||
// const criteriaTypes = TrialCriteriaTypes.find({
|
||||
// selected: true
|
||||
// }).map(criteria => {
|
||||
// return criteria.id;
|
||||
// });
|
||||
|
||||
const currentConstraints = OHIF.lesiontracker.getTrialCriteriaConstraints(criteriaTypes, data.imageId);
|
||||
// const currentConstraints = OHIF.lesiontracker.getTrialCriteriaConstraints(criteriaTypes, data.imageId);
|
||||
|
||||
if (data.shortestDiameter) {
|
||||
// TODO: Make this check criteria again to see if we should display
|
||||
@ -83,4 +93,4 @@ export const bidirectional = {
|
||||
},
|
||||
includeInCaseProgress: true,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template name="measureFlow">
|
||||
<div class="measure-flow {{#if this.threeColumns}}tree-columns{{/if}} {{instance.state.get}}" style="top:{{choose position.y 0}}px;left:{{choose position.x 0}}px">
|
||||
<div class="measure-flow {{#if this.threeColumns}}tree-columns{{/if}} {{instance.state.get}}" style="top:{{choose position.y 0}}px;left:{{choose position.x 0}}px" tabindex="-1">
|
||||
<button class="btn-add">Add label</button>
|
||||
{{#if eq instance.state.get 'selected'}}
|
||||
<div class="tree-leaf">
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import { Blaze } from 'meteor/blaze';
|
||||
import { ReactiveVar } from 'meteor/reactive-var';
|
||||
@ -8,8 +9,10 @@ import { $ } from 'meteor/jquery';
|
||||
Template.measureFlow.onCreated(() => {
|
||||
const instance = Template.instance();
|
||||
|
||||
instance.value = instance.data.currentValue || '';
|
||||
|
||||
instance.state = new ReactiveVar('closed');
|
||||
instance.description = new ReactiveVar('');
|
||||
instance.description = new ReactiveVar(instance.data.currentDescription || '');
|
||||
instance.descriptionEdit = new ReactiveVar(false);
|
||||
|
||||
const items = [
|
||||
@ -76,6 +79,8 @@ Template.measureFlow.onRendered(() => {
|
||||
|
||||
// Make the measure flow bounded by the window borders
|
||||
instance.$('.measure-flow').bounded();
|
||||
|
||||
instance.$('.btn-add').focus();
|
||||
});
|
||||
|
||||
Template.measureFlow.events({
|
||||
@ -84,6 +89,8 @@ Template.measureFlow.events({
|
||||
},
|
||||
|
||||
'click .measure-flow .btn-add, click .measure-flow .btn-rename'(event, instance) {
|
||||
const $measureFlow = instance.$('.measure-flow');
|
||||
|
||||
// Set the open state for the component
|
||||
instance.state.set('open');
|
||||
|
||||
@ -109,10 +116,13 @@ Template.measureFlow.events({
|
||||
};
|
||||
|
||||
// Define in which element the selectTree will be rendered in
|
||||
const parentElement = instance.$('.measure-flow')[0];
|
||||
const parentElement = $measureFlow[0];
|
||||
|
||||
// Render the selectTree element
|
||||
instance.selectTreeView = Blaze.renderWithData(Template.selectTree, data, parentElement);
|
||||
|
||||
// Focus the measure flow to handle closing
|
||||
$measureFlow.focus();
|
||||
});
|
||||
},
|
||||
|
||||
@ -149,6 +159,7 @@ Template.measureFlow.events({
|
||||
if (event.which === 13 || event.which === 27) {
|
||||
instance.$('.measure-flow .actions').removeClass('fadeOut');
|
||||
instance.descriptionEdit.set(false);
|
||||
instance.$('.measure-flow').focus();
|
||||
}
|
||||
|
||||
// Keep the current description if ENTER was pressed
|
||||
@ -219,5 +230,31 @@ Template.measureFlow.events({
|
||||
|
||||
// Wait the fade-out transition and remove the selectTree component
|
||||
$container.one('transitionend', event => Blaze.remove(instance.selectTreeView));
|
||||
},
|
||||
|
||||
'blur .measure-flow'(event, instance) {
|
||||
const $measureFlow = $(event.currentTarget);
|
||||
const element = $measureFlow[0];
|
||||
Meteor.defer(() => {
|
||||
const focused = $(':focus')[0];
|
||||
if (element !== focused && !$.contains(element, focused)) {
|
||||
$measureFlow.trigger('close');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
'mouseout .measure-flow'(event, instance) {
|
||||
const $measureFlow = $(event.currentTarget);
|
||||
const canClose = instance.state.get() === 'selected' && !instance.descriptionEdit.get();
|
||||
if (canClose && !$.contains($measureFlow[0], event.toElement)) {
|
||||
$measureFlow.trigger('close');
|
||||
}
|
||||
},
|
||||
|
||||
'close .measure-flow'(event, instance) {
|
||||
const $measureFlow = $(event.currentTarget);
|
||||
$measureFlow.one('animationend', () => {
|
||||
instance.data.doneCallback(instance.value.value, instance.description.get());
|
||||
}).addClass('fadeOut');
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
@import "{design}/app"
|
||||
|
||||
.measure-flow
|
||||
outline: none
|
||||
position: fixed
|
||||
z-index: 1
|
||||
|
||||
&.fadeOut
|
||||
animateFadeOut()
|
||||
|
||||
&.open,
|
||||
&.selected
|
||||
|
||||
@ -61,7 +65,7 @@
|
||||
display: none
|
||||
|
||||
.actions
|
||||
margin-top: 16px
|
||||
padding-top: 16px
|
||||
opacity: 0
|
||||
|
||||
&:not(.fadeOut)
|
||||
@ -84,7 +88,7 @@
|
||||
|
||||
.description
|
||||
margin-top: -10px
|
||||
margin-bottom: 26px
|
||||
margin-bottom: 10px
|
||||
|
||||
textarea
|
||||
background-color: white
|
||||
@ -102,7 +106,7 @@
|
||||
background-color: white
|
||||
box-shadow: 0 10px white
|
||||
line-height: 20px
|
||||
margin-bottom: 26px
|
||||
margin-bottom: 10px
|
||||
margin-top: -10px
|
||||
padding: 0 12px
|
||||
|
||||
|
||||
@ -1 +0,0 @@
|
||||
import './viewer/imageViewerViewport.js';
|
||||
@ -1,27 +0,0 @@
|
||||
import { Template } from 'meteor/templating';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
Template.imageViewerViewport.events({
|
||||
CornerstoneToolsMouseClick(event, instance, data) {
|
||||
const toolState = cornerstoneTools.getToolState(instance.element, 'bidirectional');
|
||||
|
||||
// Stop here if no tool state was found
|
||||
if (!toolState) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
for (let i = 0; i < toolState.data.length; i++) {
|
||||
const toolData = toolState.data[i];
|
||||
if (toolData.active) {
|
||||
OHIF.measurements.toggleLabelButton({
|
||||
instance,
|
||||
toolData,
|
||||
position: data.currentPoints.page
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,4 +1,3 @@
|
||||
import './lib';
|
||||
import './helpers';
|
||||
import './components';
|
||||
import './hooks';
|
||||
|
||||
@ -2,25 +2,43 @@ import { Template } from 'meteor/templating';
|
||||
import { Blaze } from 'meteor/blaze';
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
|
||||
const toolMap = {
|
||||
bidirectional: 'targets'
|
||||
};
|
||||
|
||||
OHIF.measurements.toggleLabelButton = options => {
|
||||
const removeButtonView = () => {
|
||||
if (!options.instance.buttonView) {
|
||||
return;
|
||||
}
|
||||
|
||||
Blaze.remove(options.instance.buttonView);
|
||||
options.instance.buttonView = null;
|
||||
};
|
||||
|
||||
if (options.instance.buttonView) {
|
||||
removeButtonView();
|
||||
} else {
|
||||
const data = {
|
||||
position: options.position,
|
||||
threeColumns: true,
|
||||
hideCommon: true,
|
||||
doneCallback(data) {
|
||||
console.warn('>>>>DONE CALLBACK', data);
|
||||
removeButtonView();
|
||||
}
|
||||
};
|
||||
const view = Blaze.renderWithData(Template.measureFlow, data, options.instance.element);
|
||||
options.instance.buttonView = view;
|
||||
}
|
||||
|
||||
const data = {
|
||||
position: options.position,
|
||||
threeColumns: true,
|
||||
hideCommon: true,
|
||||
doneCallback(location, description) {
|
||||
options.callback(options, location, description);
|
||||
|
||||
const tool = toolMap[options.toolData.toolType];
|
||||
|
||||
options.measurementApi[tool].update(options.toolData.id, {
|
||||
$set: {
|
||||
location,
|
||||
description
|
||||
}
|
||||
});
|
||||
|
||||
removeButtonView();
|
||||
}
|
||||
};
|
||||
const view = Blaze.renderWithData(Template.measureFlow, data, options.element);
|
||||
options.instance.buttonView = view;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user