Integrating hotkeys with commands
This commit is contained in:
1 parent
199115a9d3
commit
1a0729336b
7 files changed
+102
-89
No files matched your search
+23
-7
@@ -7,7 +7,7 @@ Template.toolbarSectionButton.onCreated(() => {
|
||||
const instance = Template.instance();
|
||||
|
||||
instance.isActive = activeToolId => {
|
||||
// TODO: Find a way to prevent the 'flash' after a click, but before this helper runs
|
||||
OHIF.commands.last.dep.depend();
|
||||
const instance = Template.instance();
|
||||
const subTools = instance.data.subTools;
|
||||
const currentId = instance.data.id;
|
||||
@@ -15,9 +15,10 @@ Template.toolbarSectionButton.onCreated(() => {
|
||||
const isSubTool = subTools && _.findWhere(subTools, { id: activeToolId });
|
||||
const activeCommandButtons = Session.get('ToolManagerActiveCommandButtons') || [];
|
||||
const isActiveCommandButton = activeCommandButtons.indexOf(instance.data.id) !== -1;
|
||||
const isActive = typeof instance.data.active === 'function' && instance.data.active();
|
||||
|
||||
// Check if the current tool, a sub tool or a command button is active
|
||||
return isCurrentTool || isSubTool || isActiveCommandButton;
|
||||
return isActive || isCurrentTool || isSubTool || isActiveCommandButton;
|
||||
};
|
||||
|
||||
instance.getActiveToolSubProperty = (propertyName, activeToolId) => {
|
||||
@@ -36,19 +37,34 @@ Template.toolbarSectionButton.onCreated(() => {
|
||||
|
||||
instance.autorun(computation => {
|
||||
// Get the last executed command
|
||||
const lastCommand = Session.get('lastCommand');
|
||||
const lastCommand = OHIF.commands.last.get();
|
||||
|
||||
// Prevent running this computation on its first run
|
||||
if (computation.firstRun) return;
|
||||
|
||||
// Stop here if it's not the last command or if it's already an active tool
|
||||
const { id } = instance.data;
|
||||
if (lastCommand !== id || instance.isActive(id)) return;
|
||||
const activeToolId = OHIF.viewerbase.toolManager.getActiveTool();
|
||||
if (lastCommand !== id || instance.isActive(activeToolId)) return;
|
||||
|
||||
// Add an active class to a button for 100ms to give the impression the button was pressed
|
||||
const $button = instance.$('.toolbarSectionButton:first');
|
||||
$button.addClass('active');
|
||||
setTimeout(() => $button.removeClass('active'), 100);
|
||||
const flashButton = $element => {
|
||||
$element.addClass('active');
|
||||
setTimeout(() => {
|
||||
if ($element.hasClass('expandable') && $element.find('.toolbarSectionButton.active').length) return;
|
||||
$element.removeClass('active');
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// Flash the active button
|
||||
const $button = instance.$('.toolbarSectionButton').first();
|
||||
flashButton($button);
|
||||
|
||||
// Flash the parent button as well in case of this button is inside a drawer
|
||||
const $parentButton = $button.closest('.toolbarSectionButton.expandable');
|
||||
if ($parentButton.length) {
|
||||
flashButton($parentButton);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Meteor.startup(function() {
|
||||
flipH: 'H',
|
||||
wwwc: 'W',
|
||||
zoom: 'Z',
|
||||
cinePlay: 'SPACE',
|
||||
toggleCinePlay: 'SPACE',
|
||||
rotateR: 'R',
|
||||
rotateL: 'L',
|
||||
toggleOverlayTags: 'SHIFT',
|
||||
@@ -71,6 +71,7 @@ Meteor.startup(function() {
|
||||
angle: 'Angle',
|
||||
dragProbe: 'Probe',
|
||||
ellipticalRoi: 'Ellipse',
|
||||
rectangleRoi: 'Rectangle',
|
||||
magnify: 'Magnify',
|
||||
annotate: 'Annotate',
|
||||
stackScroll: 'Stack Scroll',
|
||||
@@ -98,7 +99,10 @@ Meteor.startup(function() {
|
||||
flipV: 'Flip vertically',
|
||||
rotateR: 'Rotate right',
|
||||
rotateL: 'Rotate left',
|
||||
toggleCinePlay: 'Play/Pause'
|
||||
toggleCinePlay: 'Play/Pause',
|
||||
toggleCineDialog: 'CINE dialog',
|
||||
resetViewport: 'Reset',
|
||||
clearTools: 'Clear'
|
||||
});
|
||||
|
||||
// Functions to register the preset switching commands
|
||||
@@ -172,10 +176,6 @@ Meteor.startup(function() {
|
||||
const $dicomTags = $('.imageViewerViewportOverlay .dicomTag');
|
||||
$dicomTags.toggle($dicomTags.eq(0).css('display') === 'none');
|
||||
}
|
||||
},
|
||||
cineDialog: {
|
||||
name: 'Toggle CINE',
|
||||
action: viewportUtils.toggleCineDialog()
|
||||
}
|
||||
}, true);
|
||||
|
||||
@@ -203,45 +203,14 @@ function setOHIFHotkeys(hotkeys) {
|
||||
OHIF.viewer.hotkeys = hotkeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an active class to a button for 100ms only
|
||||
* to give the impressiont the button was pressed.
|
||||
* This is for tools that don't keep the button "pressed"
|
||||
* all the time the tool is active.
|
||||
*
|
||||
* @param button DOM Element for the button to be "flashed"
|
||||
*/
|
||||
function flashButton(button) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.classList.add('active');
|
||||
setTimeout(() => {
|
||||
button.classList.remove('active');
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds all hotkeys keydown events to the tasks defined in
|
||||
* OHIF.viewer.hotkeys or a given param
|
||||
* @param {Object} hotkeys hotkey and task mapping (not required). If not given, uses OHIF.viewer.hotkeys
|
||||
*/
|
||||
function enableHotkeys(hotkeys) {
|
||||
const viewerHotkeys = hotkeys || OHIF.viewer.hotkeys;
|
||||
|
||||
const definitions = {};
|
||||
Object.keys(viewerHotkeys).forEach(definition => {
|
||||
const hotkey = viewerHotkeys[definition];
|
||||
const action = OHIF.viewer.hotkeyFunctions[definition];
|
||||
definitions[definition] = {
|
||||
hotkey,
|
||||
action
|
||||
};
|
||||
});
|
||||
|
||||
OHIF.hotkeys.setContext('viewer', definitions);
|
||||
OHIF.hotkeys.switchToContext('viewer');
|
||||
const definitions = hotkeys || OHIF.viewer.hotkeys;
|
||||
OHIF.hotkeys.set('viewer', definitions);
|
||||
OHIF.context.set('viewer');
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user