ohif-viewer/Packages/ohif-hotkeys/client/components/form.js
2017-09-29 14:01:39 -03:00

216 lines
7.5 KiB
JavaScript

import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
Template.hotkeysForm.onCreated(() => {
const instance = Template.instance();
instance.api = {
save() {
const { contextName } = instance.data;
const form = instance.$('form').first().data('component');
const definitions = form.value();
const promise = OHIF.hotkeys.store(contextName, definitions);
promise.then(() => OHIF.ui.notifications.success({
text: 'The keyboard shortcut preferences were successfully saved.'
}));
return promise;
},
resetDefaults() {
const { contextName } = instance.data;
const dialogOptions = {
class: 'themed',
title: 'Reset Keyboard Shortcuts',
message: 'Are you sure you want to reset all the shortcuts to their defaults?'
};
return OHIF.ui.showDialog('dialogConfirm', dialogOptions).then(() => {
return OHIF.hotkeys.resetDefauls(contextName);
});
}
};
const rg = (start, end) => _.range(start, end + 1);
instance.allowedKeys = _.union(rg(32, 40), rg(48, 57), rg(65, 90), rg(112, 121), [123]);
instance.updateInputText = (event, displayPressedKey=false) => {
const $target = $(event.currentTarget);
const keysPressedArray = instance.getKeysPressedArray(event);
if (displayPressedKey) {
const specialKeyName = jQuery.hotkeys.specialKeys[event.which];
const keyName = specialKeyName || event.key;
keysPressedArray.push(keyName.toUpperCase());
}
$target.val(keysPressedArray.join('+'));
};
instance.getKeysPressedArray = event => {
const keysPressedArray = [];
if (event.ctrlKey && !event.altKey) {
keysPressedArray.push('CTRL');
}
if (event.shiftKey && !event.altKey) {
keysPressedArray.push('SHIFT');
}
if (event.altKey && !event.ctrlKey) {
keysPressedArray.push('ALT');
}
return keysPressedArray;
};
instance.getConflictingCommand = (currentCommand, currentCombination) => {
const form = instance.$('form').first().data('component');
const hotkeys = form.value();
let conflict = '';
_.each(hotkeys, (combination, command) => {
if (combination && combination === currentCombination && command !== currentCommand) {
conflict = command;
}
});
return conflict;
};
instance.disallowedCombinations = {
'': [],
ALT: ['SPACE'],
SHIFT: [],
CTRL: ['F4', 'F5', 'F11', 'W', 'R', 'T', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'PAGEDOWN', 'PAGEUP'],
'CTRL+SHIFT': ['Q', 'W', 'R', 'T', 'P', 'A', 'H', 'V', 'B', 'N']
};
});
Template.hotkeysForm.events({
'keydown .hotkey'(event, instance) {
if (instance.allowedKeys.indexOf(event.keyCode) > -1) {
instance.updateInputText(event, true);
$(event.currentTarget).trigger('hotkeyChange');
} else {
instance.updateInputText(event);
}
event.preventDefault();
},
'hotkeyChange .hotkey'(event, instance, data={}) {
const $target = $(event.currentTarget);
const combination = $target.val();
const keys = combination.split('+');
const lastKey = keys.pop();
const modifierCombination = keys.join('+');
const isModifier = ['CTRL', 'ALT', 'SHIFT'].indexOf(lastKey) > -1;
const formItem = $target.data('component');
const conflictedCommand = instance.getConflictingCommand(this.key, combination);
if (isModifier) {
// Clean the input if left with only a modifier key or browser specific command
formItem.error(`It's not possible to define only modifier keys (CTRL, ALT and SHIFT) as a shortcut`);
$target.val('').focus();
} else if (instance.disallowedCombinations[modifierCombination].indexOf(lastKey) > -1) {
// Clean the input and show error if combination is not allowed
formItem.error(`The "${combination}" shortcut combination is not allowed`);
$target.val('').focus();
} else if (conflictedCommand) {
if (data.blurTrigger) return;
// Remove the error message
formItem.error(false);
formItem.toggleTooltip(false);
const placement = $target.closest('.hotkeys-left').length ? 'right' : 'left';
const commandsContext = OHIF.commands.getContext(instance.data.contextName);
const popoverData = {
conflictedFunctionName: commandsContext[conflictedCommand].name,
newFunctionName: commandsContext[this.key].name,
hotkeyCombination: combination,
};
const popoverOptions = {
event,
placement
};
const conflictedFormItem = instance.$('form').first().data('component').item(conflictedCommand);
formItem.state('error', true);
conflictedFormItem.state('error', true);
const cleanup = () => {
instance.popoverVisible = false;
formItem.state('error', false);
conflictedFormItem.state('error', false);
};
const popoverTemplate = 'hotkeysConfirmReplacementPopover';
instance.popoverVisible = true;
OHIF.ui.showPopover(popoverTemplate, popoverData, popoverOptions).then(() => {
cleanup();
formItem.value(combination);
conflictedFormItem.value('');
$target.blur();
}).catch(() => {
cleanup();
$target.val('').focus();
});
} else {
// Remove the error message and blur the component if everything is fine
formItem.error(false);
if (!data.blurTrigger) {
$target.blur();
}
}
},
'blur .hotkey'(event, instance, data={}) {
$(event.currentTarget).trigger('hotkeyChange', { blurTrigger: true });
},
'keyup .hotkey'(event, instance) {
if (!instance.popoverVisible) {
instance.updateInputText(event);
}
}
});
Template.hotkeysForm.helpers({
getHotkeyInputInformationLists() {
OHIF.hotkeys.changeObserver.depend();
const instance = Template.instance();
const { contextName } = instance.data;
const hotkeysContext = OHIF.hotkeys.getContext(contextName);
const commandsContext = OHIF.commands.getContext(contextName);
if (!hotkeysContext || !commandsContext) return {};
const hotkeyDefinitions = hotkeysContext.definitions;
const commands = Object.keys(OHIF.hotkeys.defaults[contextName] || {});
const list = [];
commands.forEach(commandName => {
const commandDefinitions = commandsContext[commandName];
if (!commandDefinitions) return;
list.push({
key: commandName,
label: commandDefinitions.name,
value: hotkeyDefinitions[commandName] || ''
});
});
const left = list.splice(0, Math.ceil(list.length / 2));
const right = list;
return {
left,
right
};
}
});