306 lines
10 KiB
JavaScript
306 lines
10 KiB
JavaScript
import { Template } from 'meteor/templating';
|
|
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
|
import { Session } from 'meteor/session';
|
|
import { Tracker } from 'meteor/tracker';
|
|
import { Random } from 'meteor/random';
|
|
import { _ } from 'meteor/underscore';
|
|
import { $ } from 'meteor/jquery';
|
|
import { OHIF } from 'meteor/ohif:core';
|
|
import { viewportUtils } from '../../../lib/viewportUtils';
|
|
import { switchToImageRelative } from '../../../lib/switchToImageRelative';
|
|
import { switchToImageByIndex } from '../../../lib/switchToImageByIndex';
|
|
|
|
Template.cineDialog.onCreated(() => {
|
|
const instance = Template.instance();
|
|
|
|
// Create the data schema for CINE controls
|
|
instance.schema = new SimpleSchema({
|
|
intervalId: {
|
|
type: Number,
|
|
optional: true
|
|
},
|
|
loop: {
|
|
type: Boolean,
|
|
label: 'Loop',
|
|
defaultValue: true
|
|
},
|
|
framesPerSecond: {
|
|
type: Number,
|
|
label: '',
|
|
defaultValue: 24,
|
|
min: 1,
|
|
max: 90,
|
|
optional: true
|
|
}
|
|
});
|
|
|
|
// Update the current viewport frame rate
|
|
instance.updateFramerate = rate => {
|
|
OHIF.viewer.cine.framesPerSecond = rate;
|
|
|
|
// Update playClip toolData for this imageId
|
|
const element = viewportUtils.getActiveViewportElement();
|
|
if (!element) {
|
|
return;
|
|
}
|
|
|
|
let playClipData = cornerstoneTools.getToolState(element, 'playClip');
|
|
if (!playClipData || !playClipData.data || !playClipData.data.length) {
|
|
return;
|
|
}
|
|
|
|
// A valid playClip data object is available.
|
|
playClipData = playClipData.data[0];
|
|
|
|
// If the movie is playing, stop/start to update the framerate
|
|
if (playClipData.intervalId !== void 0) {
|
|
cornerstoneTools.stopClip(element);
|
|
cornerstoneTools.playClip(element, OHIF.viewer.cine.framesPerSecond);
|
|
} else {
|
|
playClipData.framesPerSecond = OHIF.viewer.cine.framesPerSecond;
|
|
}
|
|
|
|
Session.set('UpdateCINE', Math.random());
|
|
};
|
|
|
|
// Define the actions API
|
|
instance.api = {
|
|
displaySetPrevious: () => OHIF.viewerbase.layoutManager.moveDisplaySets(false),
|
|
displaySetNext: () => OHIF.viewerbase.layoutManager.moveDisplaySets(true),
|
|
cineToggle: () => viewportUtils.toggleCinePlay(),
|
|
cineFirst: () => switchToImageByIndex(0),
|
|
cineLast: () => switchToImageByIndex(-1),
|
|
cinePrevious: () => switchToImageRelative(-1),
|
|
cineNext: () => switchToImageRelative(1),
|
|
cineSlowDown: () => {
|
|
const newValue = OHIF.viewer.cine.framesPerSecond - 1;
|
|
if (newValue > 0) {
|
|
instance.updateFramerate(newValue);
|
|
}
|
|
},
|
|
cineSpeedUp: () => {
|
|
const newValue = OHIF.viewer.cine.framesPerSecond + 1;
|
|
if (newValue <= 90) {
|
|
instance.updateFramerate(newValue);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Run this computation every time the active viewport is changed
|
|
instance.autorun(() => {
|
|
Session.get('activeViewport');
|
|
|
|
Tracker.afterFlush(() => {
|
|
// Get the active viewportElement
|
|
const element = viewportUtils.getActiveViewportElement();
|
|
if (!element) {
|
|
return;
|
|
}
|
|
|
|
// check if playClip tool has been initialized...
|
|
const playClipData = cornerstoneTools.getToolState(element, 'playClip');
|
|
if (!playClipData) {
|
|
return;
|
|
}
|
|
|
|
// Get the cornerstone playClip tool data
|
|
const toolData = playClipData.data[0];
|
|
|
|
// Get the cine object
|
|
const cine = OHIF.viewer.cine;
|
|
|
|
// replace the cine values with the tool data
|
|
_.extend(cine, toolData);
|
|
|
|
// Set the defaults
|
|
cine.framesPerSecond = cine.framesPerSecond || 24;
|
|
cine.loop = _.isUndefined(cine.loop) ? true : cine.loop;
|
|
|
|
// Set the updated data on the form inputs
|
|
const elementComponent = instance.$('form:first').data('component');
|
|
if (elementComponent) {
|
|
elementComponent.value(cine);
|
|
}
|
|
|
|
// Update the session to refresh the framerate text
|
|
Session.set('UpdateCINE', Math.random());
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Set/Reset Window resize handler. This function is a replacement for
|
|
* ... jQuery's on('resize', func) version which, for some unkown reason
|
|
* ... is currently not working for this portion of code.
|
|
* ... Further investigation is necessary.
|
|
*
|
|
* This happens because when an event is attached using jQuery's
|
|
* you can't get it using vanilla JavaScript, it returns null.
|
|
* You need to use jQuery for that. So, either you use vanilla JS or jQuery
|
|
* to get an element's event handler. See viewerMain for more details.
|
|
*/
|
|
|
|
instance.setResizeHandler = handler => {
|
|
if (typeof handler === 'function') {
|
|
const origHandler = window.onresize;
|
|
instance.origWindowResizeHandler = typeof origHandler === 'function' ? origHandler : null;
|
|
window.onresize = event => {
|
|
if (typeof origHandler === 'function') {
|
|
origHandler.call(window, event);
|
|
}
|
|
|
|
handler.call(window, event);
|
|
};
|
|
} else {
|
|
window.onresize = instance.origWindowResizeHandler || null;
|
|
window.origWindowResizeHandler = null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Set optimal position for Cine dialog.
|
|
*/
|
|
|
|
instance.setOptimalPosition = (event, options) => {
|
|
const $viewer = $('#viewer');
|
|
const $toolbarElement = $('.toolbarSection .toolbarSectionTools:first');
|
|
const $cineDialog = $('#cineDialog');
|
|
|
|
if ($toolbarElement.length < 1 || $cineDialog.length < 1) {
|
|
return;
|
|
}
|
|
|
|
if ($cineDialog.data('wasDragged') || $cineDialog.data('wasBounded')) {
|
|
// restore original handler...
|
|
instance.setResizeHandler(null);
|
|
return;
|
|
}
|
|
|
|
const cineDialogSize = {
|
|
width: $cineDialog.outerWidth() || 0,
|
|
height: $cineDialog.outerHeight() || 0
|
|
};
|
|
|
|
const topLeftCoords = {
|
|
top: 0,
|
|
left: 0
|
|
};
|
|
|
|
const toolbarRect = {
|
|
offset: $toolbarElement.offset() || topLeftCoords,
|
|
width: $toolbarElement.outerWidth() || 0,
|
|
height: $toolbarElement.outerHeight() || 0
|
|
};
|
|
|
|
const cineDialogCoords = {
|
|
left: toolbarRect.offset.left + toolbarRect.width + 20,
|
|
top: toolbarRect.offset.top + toolbarRect.height - cineDialogSize.height
|
|
};
|
|
|
|
if (options) {
|
|
if (options.left) {
|
|
cineDialogCoords.left = options.left;
|
|
}
|
|
|
|
if (options.top) {
|
|
cineDialogCoords.top = options.top;
|
|
}
|
|
}
|
|
|
|
// Check if it is out of screen
|
|
if (cineDialogCoords.top < 0) {
|
|
cineDialogCoords.top = 0;
|
|
} else if (cineDialogCoords.top + cineDialogSize.height > $viewer.height()) {
|
|
cineDialogCoords.top -= (cineDialogCoords.top + cineDialogSize.height) - $viewer.height();
|
|
}
|
|
|
|
if (cineDialogCoords.left < 0) {
|
|
cineDialogCoords.left = 0;
|
|
} else if (cineDialogCoords.left + cineDialogSize.width > $viewer.width()) {
|
|
cineDialogCoords.left -= (cineDialogCoords.left + cineDialogSize.width) - $viewer.width();
|
|
}
|
|
|
|
$cineDialog.css(cineDialogCoords);
|
|
};
|
|
});
|
|
|
|
Template.cineDialog.onRendered(() => {
|
|
const instance = Template.instance();
|
|
const $dialog = instance.$('#cineDialog');
|
|
const singleRowLayout = OHIF.uiSettings.displayEchoUltrasoundWorkflow;
|
|
|
|
// set dialog in optimal position and make sure it continues in a optimal position...
|
|
// ... when the window has been resized
|
|
instance.setOptimalPosition(null, { top: singleRowLayout ? 47 : 26 });
|
|
|
|
// The jQuery method does not seem to be working...
|
|
// ... $(window).resize(instance.setOptimalPosition)
|
|
// This requires additional investigation.
|
|
instance.setResizeHandler(instance.setOptimalPosition);
|
|
|
|
// Make the CINE dialog bounded and draggable
|
|
$dialog.draggable({ defaultElementCursor: 'move' });
|
|
|
|
// Polyfill for older browsers
|
|
dialogPolyfill.registerDialog($dialog.get(0));
|
|
|
|
// Prevent dialog from being dragged when user clicks any button
|
|
const $controls = $dialog.find('.cine-navigation, .cine-controls, .cine-options');
|
|
$controls.on('mousedown touchstart', event => event.stopPropagation());
|
|
});
|
|
|
|
Template.cineDialog.onDestroyed(() => {
|
|
const instance = Template.instance();
|
|
// remove resize handler...
|
|
instance.setResizeHandler(null);
|
|
});
|
|
|
|
Template.cineDialog.events({
|
|
'change [data-key=loop] input'(event, instance) {
|
|
const element = viewportUtils.getActiveViewportElement();
|
|
OHIF.viewer.cine.loop = $(event.currentTarget).is(':checked');
|
|
// Update playClip tool data if available.
|
|
let playClipData = cornerstoneTools.getToolState(element, 'playClip');
|
|
if (playClipData && playClipData.data && playClipData.data.length > 0) {
|
|
playClipData.data[0].loop = OHIF.viewer.cine.loop;
|
|
}
|
|
},
|
|
|
|
'input [data-key=framesPerSecond] input, change [data-key=framesPerSecond] input'(event, instance) {
|
|
// Update the FPS text onscreen
|
|
const rate = parseFloat($(event.currentTarget).val());
|
|
instance.updateFramerate(rate);
|
|
}
|
|
});
|
|
|
|
Template.cineDialog.helpers({
|
|
isPlaying() {
|
|
return viewportUtils.isPlaying();
|
|
},
|
|
|
|
framerate() {
|
|
Session.get('UpdateCINE');
|
|
return OHIF.viewer.cine.framesPerSecond.toFixed(1);
|
|
},
|
|
|
|
displaySetDisabled(isNext) {
|
|
Session.get('LayoutManagerUpdated');
|
|
|
|
// @TODO: Investigate why this is running while OHIF.viewerbase.layoutManager is undefined
|
|
if (!OHIF.viewerbase.layoutManager) {
|
|
return;
|
|
}
|
|
|
|
return !OHIF.viewerbase.layoutManager.canMoveDisplaySets(isNext) ? 'disabled' : '';
|
|
},
|
|
|
|
buttonDisabled() {
|
|
return viewportUtils.hasMultipleFrames();
|
|
},
|
|
|
|
getClassNames(baseClass) {
|
|
const style = OHIF.uiSettings.displayEchoUltrasoundWorkflow ? 'single' : 'double';
|
|
return `${baseClass} ${style}-row-style`;
|
|
}
|
|
|
|
});
|