AWV-3: Creating mixin for form button components
This commit is contained in:
parent
e1da28ca88
commit
b1a786071e
@ -8,6 +8,7 @@ import './section/section.html';
|
|||||||
import './section/section.js';
|
import './section/section.js';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
|
import './mixins/button.js';
|
||||||
import './mixins/component.js';
|
import './mixins/component.js';
|
||||||
import './mixins/form.js';
|
import './mixins/form.js';
|
||||||
import './mixins/formItem.js';
|
import './mixins/formItem.js';
|
||||||
|
|||||||
@ -28,6 +28,11 @@ class Mixin {
|
|||||||
// Get the dependent mixin to be initizalized
|
// Get the dependent mixin to be initizalized
|
||||||
const mixin = Mixin.getMixin(dependency);
|
const mixin = Mixin.getMixin(dependency);
|
||||||
|
|
||||||
|
// Throw an error if a cyclic dependency was found on this mixin
|
||||||
|
if (mixin === this) {
|
||||||
|
throw new Error(`Mixin ${dependency} has a cyclic dependency.`);
|
||||||
|
}
|
||||||
|
|
||||||
// Initizalize the mixin dependencies recursively
|
// Initizalize the mixin dependencies recursively
|
||||||
mixin.init(template, data, applied, behaviors);
|
mixin.init(template, data, applied, behaviors);
|
||||||
});
|
});
|
||||||
|
|||||||
38
Packages/ohif-core/client/components/base/mixins/button.js
Normal file
38
Packages/ohif-core/client/components/base/mixins/button.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* input: controls a button
|
||||||
|
*/
|
||||||
|
OHIF.mixins.button = new OHIF.Mixin({
|
||||||
|
dependencies: 'formItem',
|
||||||
|
composition: {
|
||||||
|
onRendered() {
|
||||||
|
const instance = Template.instance();
|
||||||
|
const component = instance.component;
|
||||||
|
|
||||||
|
// Set the element to be controlled
|
||||||
|
component.$element = instance.$('button:first');
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click button'(event, instance) {
|
||||||
|
const component = instance.component;
|
||||||
|
|
||||||
|
// Extract the action and the params
|
||||||
|
const { action, params } = instance.data;
|
||||||
|
|
||||||
|
// Get the current component's API
|
||||||
|
const api = component.getApi();
|
||||||
|
|
||||||
|
// Stop here if no API or action was defined
|
||||||
|
if (!api || !action || typeof api[action] !== 'function') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the defined action function
|
||||||
|
api[action].call(this, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -140,6 +140,32 @@ OHIF.mixins.formItem = new OHIF.Mixin({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get the current component API
|
||||||
|
component.getApi = () => {
|
||||||
|
const api = instance.data.api;
|
||||||
|
|
||||||
|
// Check if the API was not given
|
||||||
|
if (!api) {
|
||||||
|
// Stop here if the component is form and API was not given
|
||||||
|
if (component.isForm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current component's form
|
||||||
|
const form = component.getForm();
|
||||||
|
|
||||||
|
// Stop here if the component has no form
|
||||||
|
if (!form) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return form.getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the given API
|
||||||
|
return api;
|
||||||
|
};
|
||||||
|
|
||||||
// Check if the component value is valid in its form's schema
|
// Check if the component value is valid in its form's schema
|
||||||
component.validate = () => {
|
component.validate = () => {
|
||||||
// Get the component's form
|
// Get the component's form
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
{{#baseComponent (extend this
|
{{#baseComponent (extend this
|
||||||
base='baseButton'
|
base='baseButton'
|
||||||
class=(concat 'btn ' this.class)
|
class=(concat 'btn ' this.class)
|
||||||
mixins=(concat 'formItem ' this.mixins)
|
mixins=(concat 'button ' this.mixins)
|
||||||
)}}
|
)}}
|
||||||
{{>UI.contentBlock}}
|
{{>UI.contentBlock}}
|
||||||
{{/baseComponent}}
|
{{/baseComponent}}
|
||||||
|
|||||||
@ -1,51 +1,52 @@
|
|||||||
<template name="cineDialog">
|
<template name="cineDialog">
|
||||||
{{#form id='cineDialog' class='noselect' schema=instance.schema}}
|
{{#form id='cineDialog' class='noselect' schema=instance.schema api=instance.api}}
|
||||||
|
{{>inputHidden key='intervalId'}}
|
||||||
<h5>CINE Controls</h5>
|
<h5>CINE Controls</h5>
|
||||||
<div class="cine-navigation">
|
<div class="cine-navigation">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
{{#button id='cineDisplaySetPrevious' title='Previous display set'}}
|
{{#button action='displaySetPrevious' title='Previous display set'}}
|
||||||
<i class="fa fa-toggle-up"></i>
|
<i class="fa fa-toggle-up"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cineDisplaySetNext' title='Next display set'}}
|
{{#button action='displaySetNext' title='Next display set'}}
|
||||||
<i class="fa fa-toggle-down"></i>
|
<i class="fa fa-toggle-down"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cine-controls">
|
<div class="cine-controls">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
{{#button id='cineFirstButton' title='Skip to first image'}}
|
{{#button action='cineFirst' title='Skip to first image'}}
|
||||||
<i class="fa fa-fast-backward"></i>
|
<i class="fa fa-fast-backward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cineBackButton' title='Previous image'}}
|
{{#button action='cinePrevious' title='Previous image'}}
|
||||||
<i class="fa fa-step-backward"></i>
|
<i class="fa fa-step-backward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cineSlowPlaybackButton' title='Slow playback'}}
|
{{#button action='cineSlowDown' title='Slow playback'}}
|
||||||
<i class="fa fa-backward"></i>
|
<i class="fa fa-backward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cinePlayButton' title='Play / Stop' class=(valueIf isPlaying 'active' '')}}
|
{{#button action='cineToggle' title='Play / Stop' class=(valueIf isPlaying 'active' '')}}
|
||||||
{{#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 id='cineFastForwardButton' title='Increase playback speed'}}
|
{{#button action='cineSpeedUp' title='Increase playback speed'}}
|
||||||
<i class="fa fa-forward"></i>
|
<i class="fa fa-forward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cineNextButton' title='Next image'}}
|
{{#button action='cineNext' title='Next image'}}
|
||||||
<i class="fa fa-step-forward"></i>
|
<i class="fa fa-step-forward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button id='cineLastButton' title='Skip to last image'}}
|
{{#button action='cineLast' title='Skip to last image'}}
|
||||||
<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">
|
||||||
|
{{>inputCheckbox key='loop' labelClass='pull-right m-a-0'}}
|
||||||
<div class="fps-section">
|
<div class="fps-section">
|
||||||
{{#inputRange id='cineSlider' key='speed' 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}}
|
||||||
{{#section 'labelAfterText'}}:
|
{{#section 'labelAfterText'}}:
|
||||||
<span id="fps">{{framerate}}</span>
|
<span id="fps">{{framerate}}</span>
|
||||||
{{>inputCheckbox id='cineLoopCheckbox' key='loop' labelClass='pull-right m-a-0'}}
|
|
||||||
{{/section}}
|
{{/section}}
|
||||||
{{/inputRange}}
|
{{/inputRange}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,24 +1,35 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { Template } from 'meteor/templating';
|
||||||
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
|
||||||
Template.cineDialog.onCreated(() => {
|
Template.cineDialog.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
// Create the data schema for CINE controls
|
||||||
instance.schema = new SimpleSchema({
|
instance.schema = new SimpleSchema({
|
||||||
|
intervalId: {
|
||||||
|
type: Number,
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
loop: {
|
loop: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
label: 'Loop',
|
label: 'Loop',
|
||||||
defaultValue: true
|
defaultValue: true
|
||||||
},
|
},
|
||||||
speed: {
|
framesPerSecond: {
|
||||||
type: Number,
|
type: Number,
|
||||||
label: 'Cine Speed',
|
label: 'Cine Speed',
|
||||||
defaultValue: 24,
|
defaultValue: 24,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 90
|
max: 90,
|
||||||
|
optional: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update the current viewport frame rate
|
||||||
instance.updateFramerate = rate => {
|
instance.updateFramerate = rate => {
|
||||||
OHIF.viewer.cine.framesPerSecond = rate;
|
OHIF.viewer.cine.framesPerSecond = rate;
|
||||||
|
|
||||||
@ -33,66 +44,78 @@ Template.cineDialog.onCreated(() => {
|
|||||||
cornerstoneTools.playClip(element);
|
cornerstoneTools.playClip(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
Session.set('UpdateCine', Random.id());
|
Session.set('UpdateCINE', Random.id());
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
Template.cineDialog.onRendered(() => {
|
// Define the actions API
|
||||||
// Make the CINE dialog bounded and draggable
|
instance.api = {
|
||||||
Template.instance().$('#cineDialog').bounded().draggable();
|
displaySetPrevious: () => OHIF.viewer.moveDisplaySets(false),
|
||||||
});
|
displaySetNext: () => OHIF.viewer.moveDisplaySets(true),
|
||||||
|
cineToggle: () => toggleCinePlay(),
|
||||||
Template.cineDialog.events({
|
cineFirst: () => switchToImageByIndex(0),
|
||||||
'click #cineDisplaySetPrevious'(event, instance) {
|
cineLast: () => switchToImageByIndex(-1),
|
||||||
OHIF.viewer.moveDisplaySets(false);
|
cinePrevious: () => switchToImageRelative(-1),
|
||||||
},
|
cineNext: () => switchToImageRelative(1),
|
||||||
|
cineSlowDown: () => {
|
||||||
'click #cineDisplaySetNext'(event, instance) {
|
|
||||||
OHIF.viewer.moveDisplaySets(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #cineFirstButton'(event, instance) {
|
|
||||||
switchToImageByIndex(0);
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #cineBackButton'(event, instance) {
|
|
||||||
switchToImageRelative(-1);
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #cineSlowPlaybackButton'(event, instance) {
|
|
||||||
const newValue = OHIF.viewer.cine.framesPerSecond - 1;
|
const newValue = OHIF.viewer.cine.framesPerSecond - 1;
|
||||||
if (newValue > 0) {
|
if (newValue > 0) {
|
||||||
instance.updateFramerate(newValue);
|
instance.updateFramerate(newValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
cineSpeedUp: () => {
|
||||||
'click #cinePlayButton'(event, instance) {
|
|
||||||
toggleCinePlay();
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #cineNextButton'(event, instance) {
|
|
||||||
switchToImageRelative(1);
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #cineFastForwardButton'(event, instance) {
|
|
||||||
const newValue = OHIF.viewer.cine.framesPerSecond + 1;
|
const newValue = OHIF.viewer.cine.framesPerSecond + 1;
|
||||||
if (newValue <= 90) {
|
if (newValue <= 90) {
|
||||||
instance.updateFramerate(newValue);
|
instance.updateFramerate(newValue);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
};
|
||||||
|
|
||||||
'click #cineLastButton'(event, instance) {
|
// Run this computation every time the active viewport is changed
|
||||||
switchToImageByIndex(-1);
|
instance.autorun(() => {
|
||||||
},
|
Session.get('activeViewport');
|
||||||
|
|
||||||
'change #cineLoopCheckbox'(event, instance) {
|
Tracker.afterFlush(() => {
|
||||||
|
// Get the active viewportElement
|
||||||
|
const element = getActiveViewportElement();
|
||||||
|
|
||||||
|
// Get the cornerstone playClip tool data
|
||||||
|
const toolData = cornerstoneTools.getToolState(element, 'playClip').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
|
||||||
|
instance.$('form:first').data('component').value(cine);
|
||||||
|
|
||||||
|
// Update the session to refresh the framerate text
|
||||||
|
Session.set('UpdateCINE', Random.id());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.cineDialog.onRendered(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
// Make the CINE dialog bounded and draggable
|
||||||
|
instance.$('#cineDialog').bounded().draggable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.cineDialog.events({
|
||||||
|
'change [data-key=loop] input'(event, instance) {
|
||||||
const element = getActiveViewportElement();
|
const element = getActiveViewportElement();
|
||||||
const playClipToolData = cornerstoneTools.getToolState(element, 'playClip');
|
const playClipToolData = cornerstoneTools.getToolState(element, 'playClip');
|
||||||
playClipToolData.data[0].loop = $(event.currentTarget).is(':checked');
|
playClipToolData.data[0].loop = $(event.currentTarget).is(':checked');
|
||||||
OHIF.viewer.cine.loop = playClipToolData.data[0].loop;
|
OHIF.viewer.cine.loop = playClipToolData.data[0].loop;
|
||||||
},
|
},
|
||||||
|
|
||||||
'input #cineSlider'(event, instance) {
|
'input [data-key=framesPerSecond] input'(event, instance) {
|
||||||
// Update the FPS text onscreen
|
// Update the FPS text onscreen
|
||||||
const rate = parseFloat($(event.currentTarget).val());
|
const rate = parseFloat($(event.currentTarget).val());
|
||||||
instance.updateFramerate(rate);
|
instance.updateFramerate(rate);
|
||||||
@ -109,7 +132,7 @@ Template.cineDialog.helpers({
|
|||||||
},
|
},
|
||||||
|
|
||||||
framerate() {
|
framerate() {
|
||||||
Session.get('UpdateCine');
|
Session.get('UpdateCINE');
|
||||||
return OHIF.viewer.cine.framesPerSecond.toFixed(1);
|
return OHIF.viewer.cine.framesPerSecond.toFixed(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user