import {Component, OnInit, Input} from '@angular/core'; import {SELECT2_DIRECTIVES} from 'ng2-select2/dist/ng2-select2'; import {OptionData} from 'ng2-select2/dist/select2'; import {KeyAction} from '../../../../../config-serializer/config-items/KeyAction'; import {KeystrokeAction} from '../../../../../config-serializer/config-items/KeystrokeAction'; import {IconComponent} from '../../widgets/icon/icon.component'; import {CaptureKeystrokeButtonComponent} from '../../widgets/capture-keystroke/capture-keystroke-button.component'; import {Tab} from '../tab'; @Component({ moduleId: module.id, selector: 'keypress-tab', template: require('./keypress-tab.component.html'), styles: [require('./keypress-tab.component.scss')], directives: [CaptureKeystrokeButtonComponent, IconComponent, SELECT2_DIRECTIVES] }) export class KeypressTabComponent implements OnInit, Tab { @Input() defaultKeyAction: KeyAction; private leftModifiers: string[]; private rightModifiers: string[]; private leftModifierSelects: boolean[]; private rightModifierSelects: boolean[]; private scanCodeGroups: Array; private longPressGroups: Array; private scanCode: number; private selectedLongPressIndex: number; constructor() { this.leftModifiers = ['LShift', 'LCtrl', 'LSuper', 'LAlt']; this.rightModifiers = ['RShift', 'RCtrl', 'RSuper', 'RAlt']; this.scanCodeGroups = [{ id: '0', text: 'None' }]; this.scanCodeGroups = this.scanCodeGroups.concat(require('json!./scancodes.json')); this.longPressGroups = require('json!./longPress.json'); this.leftModifierSelects = Array(this.leftModifiers.length).fill(false); this.rightModifierSelects = Array(this.rightModifiers.length).fill(false); this.selectedLongPressIndex = -1; } ngOnInit() { this.fromKeyAction(this.defaultKeyAction); } keyActionValid(keystrokeAction?: KeystrokeAction): boolean { if (!keystrokeAction) { keystrokeAction = this.toKeyAction(); } return keystrokeAction.scancode > 0 || keystrokeAction.modifierMask > 0; } fromKeyAction(keyAction: KeyAction): boolean { if (!(keyAction instanceof KeystrokeAction)) { return false; } let keystrokeAction: KeystrokeAction = keyAction; // Restore scancode this.scanCode = keystrokeAction.scancode || 0; let leftModifiersLength: number = this.leftModifiers.length; // Restore modifiers for (let i = 0; i < leftModifiersLength; ++i) { this.leftModifierSelects[this.modifierMapper(i)] = ((keystrokeAction.modifierMask >> i) & 1) === 1; } for (let i = leftModifiersLength; i < leftModifiersLength + this.rightModifierSelects.length; ++i) { let index: number = this.modifierMapper(i) - leftModifiersLength; this.rightModifierSelects[index] = ((keystrokeAction.modifierMask >> i) & 1) === 1; } // Restore longPressAction if (keystrokeAction.longPressAction !== undefined) { this.selectedLongPressIndex = this.modifierMapper(keystrokeAction.longPressAction); } return true; } toKeyAction(): KeystrokeAction { let keystrokeAction: KeystrokeAction = new KeystrokeAction(); keystrokeAction.scancode = this.scanCode; keystrokeAction.modifierMask = 0; let modifiers = this.leftModifierSelects.concat(this.rightModifierSelects).map(x => x ? 1 : 0); for (let i = 0; i < modifiers.length; ++i) { keystrokeAction.modifierMask |= modifiers[i] << this.modifierMapper(i); } keystrokeAction.longPressAction = this.selectedLongPressIndex === -1 ? undefined : this.modifierMapper(this.selectedLongPressIndex); if (!this.keyActionValid(keystrokeAction)) { throw new Error('KeyAction is invalid!'); } return keystrokeAction; } scanCodeTemplateResult: Function = (state: any) => { if (!state.id) { return state.text; } if (state.additional && state.additional.explanation) { return jQuery( '' + state.text + ' ' + state.additional.explanation + '' ); } else { return jQuery('' + state.text + ''); } } toggleModifier(right: boolean, index: number) { let modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects; modifierSelects[index] = !modifierSelects[index]; } // TODO: change to the correct type when the wrapper has added it. private onLongpressChange(event: any) { this.selectedLongPressIndex = +event.value; } // TODO: change to the correct type when the wrapper has added it. private onScancodeChange(event: any) { this.scanCode = +event.value; } private modifierMapper(x: number) { if (x < 8) { return Math.floor(x / 2) * 4 + 1 - x; // 1, 0, 3, 2, 5, 4, 7, 6 } else { return x; } }; }