Update KeyboardMouseInputField (#1232)
* Assign missing type * Update KeyboardMouseInputField to use an array instead of a string * Use "modifiers" instead of "value" or "inputs" * Simplify * Add support for using keys * Use bool args instead of a string
This commit is contained in:
parent
5ae3acf6ff
commit
351d9b2e8e
@ -27,7 +27,7 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
this._isPointerTypeSupported = isPointerTypeSupported;
|
this._isPointerTypeSupported = isPointerTypeSupported;
|
||||||
this._keySeparator = ' + ';
|
this._keySeparator = ' + ';
|
||||||
this._inputNameMap = new Map(DocumentUtil.getModifierKeys(os));
|
this._inputNameMap = new Map(DocumentUtil.getModifierKeys(os));
|
||||||
this._keyPriorities = new Map([
|
this._modifierPriorities = new Map([
|
||||||
['meta', -4],
|
['meta', -4],
|
||||||
['ctrl', -3],
|
['ctrl', -3],
|
||||||
['alt', -2],
|
['alt', -2],
|
||||||
@ -35,25 +35,29 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
]);
|
]);
|
||||||
this._mouseInputNamePattern = /^mouse(\d+)$/;
|
this._mouseInputNamePattern = /^mouse(\d+)$/;
|
||||||
this._eventListeners = new EventListenerCollection();
|
this._eventListeners = new EventListenerCollection();
|
||||||
this._value = '';
|
this._key = null;
|
||||||
this._type = null;
|
this._modifiers = [];
|
||||||
this._penPointerIds = new Set();
|
this._penPointerIds = new Set();
|
||||||
|
this._mouseModifiersSupported = false;
|
||||||
|
this._keySupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
get modifiers() {
|
||||||
return this._value;
|
return this._modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare(value, type) {
|
prepare(key, modifiers, mouseModifiersSupported=false, keySupported=false) {
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
|
|
||||||
this._value = value;
|
this._key = key;
|
||||||
const modifiers = this._splitValue(value);
|
this._modifiers = this._sortModifiers(modifiers);
|
||||||
const {displayValue} = this._getInputStrings(modifiers);
|
this._mouseModifiersSupported = mouseModifiersSupported;
|
||||||
|
this._keySupported = keySupported;
|
||||||
|
this._updateDisplayString();
|
||||||
const events = [
|
const events = [
|
||||||
[this._inputNode, 'keydown', this._onModifierKeyDown.bind(this), false]
|
[this._inputNode, 'keydown', this._onModifierKeyDown.bind(this), false]
|
||||||
];
|
];
|
||||||
if (type === 'modifierInputs' && this._mouseButton !== null) {
|
if (mouseModifiersSupported && this._mouseButton !== null) {
|
||||||
events.push(
|
events.push(
|
||||||
[this._mouseButton, 'mousedown', this._onMouseButtonMouseDown.bind(this), false],
|
[this._mouseButton, 'mousedown', this._onMouseButtonMouseDown.bind(this), false],
|
||||||
[this._mouseButton, 'pointerdown', this._onMouseButtonPointerDown.bind(this), false],
|
[this._mouseButton, 'pointerdown', this._onMouseButtonPointerDown.bind(this), false],
|
||||||
@ -64,7 +68,6 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
[this._mouseButton, 'contextmenu', this._onMouseButtonContextMenu.bind(this), false]
|
[this._mouseButton, 'contextmenu', this._onMouseButtonContextMenu.bind(this), false]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this._inputNode.value = displayValue;
|
|
||||||
for (const args of events) {
|
for (const args of events) {
|
||||||
this._eventListeners.addEventListener(...args);
|
this._eventListeners.addEventListener(...args);
|
||||||
}
|
}
|
||||||
@ -72,35 +75,33 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
this._eventListeners.removeAllEventListeners();
|
this._eventListeners.removeAllEventListeners();
|
||||||
this._value = '';
|
this._modifiers = [];
|
||||||
this._type = null;
|
this._key = null;
|
||||||
|
this._mouseModifiersSupported = false;
|
||||||
|
this._keySupported = false;
|
||||||
this._penPointerIds.clear();
|
this._penPointerIds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInputs() {
|
clearInputs() {
|
||||||
this._updateInputs([]);
|
this._updateModifiers([], null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
_splitValue(value) {
|
_sortModifiers(modifiers) {
|
||||||
return value.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
_sortInputs(inputs) {
|
|
||||||
const pattern = this._mouseInputNamePattern;
|
const pattern = this._mouseInputNamePattern;
|
||||||
const keyPriorities = this._keyPriorities;
|
const keyPriorities = this._modifierPriorities;
|
||||||
const inputInfos = inputs.map((value, index) => {
|
const modifierInfos = modifiers.map((modifier, index) => {
|
||||||
const match = pattern.exec(value);
|
const match = pattern.exec(modifier);
|
||||||
if (match !== null) {
|
if (match !== null) {
|
||||||
return [value, 1, Number.parseInt(match[1], 10), index];
|
return [modifier, 1, Number.parseInt(match[1], 10), index];
|
||||||
} else {
|
} else {
|
||||||
let priority = keyPriorities.get(value);
|
let priority = keyPriorities.get(modifier);
|
||||||
if (typeof priority === 'undefined') { priority = 0; }
|
if (typeof priority === 'undefined') { priority = 0; }
|
||||||
return [value, 0, priority, index];
|
return [modifier, 0, priority, index];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
inputInfos.sort((a, b) => {
|
modifierInfos.sort((a, b) => {
|
||||||
let i = a[1] - b[1];
|
let i = a[1] - b[1];
|
||||||
if (i !== 0) { return i; }
|
if (i !== 0) { return i; }
|
||||||
|
|
||||||
@ -113,36 +114,37 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
i = a[3] - b[3];
|
i = a[3] - b[3];
|
||||||
return i;
|
return i;
|
||||||
});
|
});
|
||||||
return inputInfos.map(([value]) => value);
|
return modifierInfos.map(([modifier]) => modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getInputStrings(inputs) {
|
_updateDisplayString() {
|
||||||
let value = '';
|
|
||||||
let displayValue = '';
|
let displayValue = '';
|
||||||
let first = true;
|
let first = true;
|
||||||
for (const input of inputs) {
|
for (const modifier of this._modifiers) {
|
||||||
const {name} = this._getInputName(input);
|
const {name} = this._getModifierName(modifier);
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
value += ', ';
|
|
||||||
displayValue += this._keySeparator;
|
displayValue += this._keySeparator;
|
||||||
}
|
}
|
||||||
value += input;
|
|
||||||
displayValue += name;
|
displayValue += name;
|
||||||
}
|
}
|
||||||
return {value, displayValue};
|
if (this._key !== null) {
|
||||||
|
if (!first) { displayValue += this._keySeparator; }
|
||||||
|
displayValue += this._key;
|
||||||
|
}
|
||||||
|
this._inputNode.value = displayValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getInputName(value) {
|
_getModifierName(modifier) {
|
||||||
const pattern = this._mouseInputNamePattern;
|
const pattern = this._mouseInputNamePattern;
|
||||||
const match = pattern.exec(value);
|
const match = pattern.exec(modifier);
|
||||||
if (match !== null) {
|
if (match !== null) {
|
||||||
return {name: `Mouse ${match[1]}`, type: 'mouse'};
|
return {name: `Mouse ${match[1]}`, type: 'mouse'};
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = this._inputNameMap.get(value);
|
let name = this._inputNameMap.get(modifier);
|
||||||
if (typeof name === 'undefined') { name = value; }
|
if (typeof name === 'undefined') { name = modifier; }
|
||||||
return {name, type: 'key'};
|
return {name, type: 'key'};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,24 +168,40 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isModifierKey(keyName) {
|
||||||
|
switch (keyName) {
|
||||||
|
case 'Alt':
|
||||||
|
case 'Control':
|
||||||
|
case 'Meta':
|
||||||
|
case 'Shift':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_onModifierKeyDown(e) {
|
_onModifierKeyDown(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const key = DocumentUtil.getKeyFromEvent(e);
|
const key = DocumentUtil.getKeyFromEvent(e);
|
||||||
switch (key) {
|
if (this._keySupported) {
|
||||||
case 'Escape':
|
this._updateModifiers([...this._getModifierKeys(e)], this._isModifierKey(key) ? void 0 : key);
|
||||||
case 'Backspace':
|
} else {
|
||||||
this.clearInputs();
|
switch (key) {
|
||||||
break;
|
case 'Escape':
|
||||||
default:
|
case 'Backspace':
|
||||||
this._addInputs(this._getModifierKeys(e));
|
this.clearInputs();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
this._addModifiers(this._getModifierKeys(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseButtonMouseDown(e) {
|
_onMouseButtonMouseDown(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._addInputs(DocumentUtil.getActiveButtons(e));
|
this._addModifiers(DocumentUtil.getActiveButtons(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseButtonPointerDown(e) {
|
_onMouseButtonPointerDown(e) {
|
||||||
@ -200,7 +218,7 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._addInputs(DocumentUtil.getActiveButtons(e));
|
this._addModifiers(DocumentUtil.getActiveButtons(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseButtonPointerOver(e) {
|
_onMouseButtonPointerOver(e) {
|
||||||
@ -227,22 +245,41 @@ class KeyboardMouseInputField extends EventDispatcher {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
_addInputs(newInputs) {
|
_addModifiers(newModifiers, newKey) {
|
||||||
const inputs = new Set(this._splitValue(this._value));
|
const modifiers = new Set(this._modifiers);
|
||||||
for (const input of newInputs) {
|
for (const modifier of newModifiers) {
|
||||||
inputs.add(input);
|
modifiers.add(modifier);
|
||||||
}
|
}
|
||||||
this._updateInputs([...inputs]);
|
this._updateModifiers([...modifiers], newKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateInputs(inputs) {
|
_updateModifiers(modifiers, newKey) {
|
||||||
inputs = this._sortInputs(inputs);
|
modifiers = this._sortModifiers(modifiers);
|
||||||
|
|
||||||
const node = this._inputNode;
|
let changed = false;
|
||||||
const {value, displayValue} = this._getInputStrings(inputs);
|
if (typeof newKey !== 'undefined' && this._key !== newKey) {
|
||||||
node.value = displayValue;
|
this._key = newKey;
|
||||||
if (this._value === value) { return; }
|
changed = true;
|
||||||
this._value = value;
|
}
|
||||||
this.trigger('change', {value, displayValue});
|
if (!this._areArraysEqual(this._modifiers, modifiers)) {
|
||||||
|
this._modifiers = modifiers;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateDisplayString();
|
||||||
|
if (changed) {
|
||||||
|
this.trigger('change', {modifiers: this._modifiers, key: this._key});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_areArraysEqual(array1, array2) {
|
||||||
|
const length = array1.length;
|
||||||
|
if (length !== array2.length) { return false; }
|
||||||
|
|
||||||
|
for (let i = 0; i < length; ++i) {
|
||||||
|
if (array1[i] !== array2[i]) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,11 +525,12 @@ class ProfileConditionUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onModifierInputChange({validate, normalize}, {value}) {
|
_onModifierInputChange({validate, normalize}, {modifiers}) {
|
||||||
const okay = this._validateValue(value, validate);
|
modifiers = this._joinModifiers(modifiers);
|
||||||
this._value = value;
|
const okay = this._validateValue(modifiers, validate);
|
||||||
|
this._value = modifiers;
|
||||||
if (okay) {
|
if (okay) {
|
||||||
const normalizedValue = this._normalizeValue(value, normalize);
|
const normalizedValue = this._normalizeValue(modifiers, normalize);
|
||||||
this.settingsController.setGlobalSetting(this.getPath('value'), normalizedValue);
|
this.settingsController.setGlobalSetting(this.getPath('value'), normalizedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -589,7 +590,7 @@ class ProfileConditionUI {
|
|||||||
let inputType = 'text';
|
let inputType = 'text';
|
||||||
let inputValue = value;
|
let inputValue = value;
|
||||||
let inputStep = null;
|
let inputStep = null;
|
||||||
let mouseButtonHidden = true;
|
let showMouseButton = false;
|
||||||
const events = [];
|
const events = [];
|
||||||
const inputData = {validate, normalize};
|
const inputData = {validate, normalize};
|
||||||
const node = this._valueInput;
|
const node = this._valueInput;
|
||||||
@ -603,9 +604,9 @@ class ProfileConditionUI {
|
|||||||
case 'modifierKeys':
|
case 'modifierKeys':
|
||||||
case 'modifierInputs':
|
case 'modifierInputs':
|
||||||
inputValue = null;
|
inputValue = null;
|
||||||
mouseButtonHidden = (type !== 'modifierInputs');
|
showMouseButton = (type === 'modifierInputs');
|
||||||
this._kbmInputField = this._parent.parent.createKeyboardMouseInputField(node, this._mouseButton);
|
this._kbmInputField = this._parent.parent.createKeyboardMouseInputField(node, this._mouseButton);
|
||||||
this._kbmInputField.prepare(value, type);
|
this._kbmInputField.prepare(null, this._splitModifiers(value), showMouseButton, false);
|
||||||
events.push(['on', this._kbmInputField, 'change', this._onModifierInputChange.bind(this, inputData), false]);
|
events.push(['on', this._kbmInputField, 'change', this._onModifierInputChange.bind(this, inputData), false]);
|
||||||
break;
|
break;
|
||||||
default: // 'string'
|
default: // 'string'
|
||||||
@ -624,7 +625,7 @@ class ProfileConditionUI {
|
|||||||
} else {
|
} else {
|
||||||
node.removeAttribute('step');
|
node.removeAttribute('step');
|
||||||
}
|
}
|
||||||
this._mouseButtonContainer.hidden = mouseButtonHidden;
|
this._mouseButtonContainer.hidden = !showMouseButton;
|
||||||
for (const args of events) {
|
for (const args of events) {
|
||||||
this._inputEventListeners.addGeneric(...args);
|
this._inputEventListeners.addGeneric(...args);
|
||||||
}
|
}
|
||||||
@ -645,4 +646,12 @@ class ProfileConditionUI {
|
|||||||
_removeSelf() {
|
_removeSelf() {
|
||||||
this._parent.removeCondition(this);
|
this._parent.removeCondition(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_splitModifiers(modifiersString) {
|
||||||
|
return modifiersString.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_joinModifiers(modifiersArray) {
|
||||||
|
return modifiersArray.join(', ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,8 +199,8 @@ class ScanInputField {
|
|||||||
const isPointerTypeSupported = this._isPointerTypeSupported.bind(this);
|
const isPointerTypeSupported = this._isPointerTypeSupported.bind(this);
|
||||||
this._includeInputField = new KeyboardMouseInputField(includeInputNode, includeMouseButton, this._os, isPointerTypeSupported);
|
this._includeInputField = new KeyboardMouseInputField(includeInputNode, includeMouseButton, this._os, isPointerTypeSupported);
|
||||||
this._excludeInputField = new KeyboardMouseInputField(excludeInputNode, excludeMouseButton, this._os, isPointerTypeSupported);
|
this._excludeInputField = new KeyboardMouseInputField(excludeInputNode, excludeMouseButton, this._os, isPointerTypeSupported);
|
||||||
this._includeInputField.prepare(include, 'modifierInputs');
|
this._includeInputField.prepare(null, this._splitModifiers(include), true, false);
|
||||||
this._excludeInputField.prepare(exclude, 'modifierInputs');
|
this._excludeInputField.prepare(null, this._splitModifiers(exclude), true, false);
|
||||||
|
|
||||||
this._eventListeners.on(this._includeInputField, 'change', this._onIncludeValueChange.bind(this));
|
this._eventListeners.on(this._includeInputField, 'change', this._onIncludeValueChange.bind(this));
|
||||||
this._eventListeners.on(this._excludeInputField, 'change', this._onExcludeValueChange.bind(this));
|
this._eventListeners.on(this._excludeInputField, 'change', this._onExcludeValueChange.bind(this));
|
||||||
@ -230,12 +230,14 @@ class ScanInputField {
|
|||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
_onIncludeValueChange({value}) {
|
_onIncludeValueChange({modifiers}) {
|
||||||
this._parent.setProperty(this._index, 'include', value, true);
|
modifiers = this._joinModifiers(modifiers);
|
||||||
|
this._parent.setProperty(this._index, 'include', modifiers, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onExcludeValueChange({value}) {
|
_onExcludeValueChange({modifiers}) {
|
||||||
this._parent.setProperty(this._index, 'exclude', value, true);
|
modifiers = this._joinModifiers(modifiers);
|
||||||
|
this._parent.setProperty(this._index, 'exclude', modifiers, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRemoveClick(e) {
|
_onRemoveClick(e) {
|
||||||
@ -296,4 +298,12 @@ class ScanInputField {
|
|||||||
this._node.dataset.showAdvanced = `${showAdvanced}`;
|
this._node.dataset.showAdvanced = `${showAdvanced}`;
|
||||||
this._parent.setProperty(this._index, 'options.showAdvanced', showAdvanced, false);
|
this._parent.setProperty(this._index, 'options.showAdvanced', showAdvanced, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_splitModifiers(modifiersString) {
|
||||||
|
return modifiersString.split(/[,;\s]+/).map((v) => v.trim().toLowerCase()).filter((v) => v.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_joinModifiers(modifiersArray) {
|
||||||
|
return modifiersArray.join(', ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user