diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.html b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.html index bdb3f2d2..ca121791 100644 --- a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.html +++ b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.html @@ -36,20 +36,20 @@
diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts index 686c49e5..16e97791 100644 --- a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts +++ b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts @@ -4,6 +4,8 @@ import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } import { Tab } from '../tab'; import { MapperService } from '../../../../services/mapper.service'; import { SelectOptionData } from '../../../../models/select-option-data'; +import { KeyModifierModel } from '../../../../models/key-modifier-model'; +import { mapLeftRigthModifierToKeyActionModifier } from '../../../../util'; @Component({ selector: 'keypress-tab', @@ -15,11 +17,8 @@ export class KeypressTabComponent extends Tab implements OnChanges { @Input() defaultKeyAction: KeyAction; @Input() secondaryRoleEnabled: boolean; - leftModifiers: string[]; - rightModifiers: string[]; - - leftModifierSelects: boolean[]; - rightModifierSelects: boolean[]; + leftModifiers: KeyModifierModel[]; + rightModifiers: KeyModifierModel[]; scanCodeGroups: Array; secondaryRoleGroups: Array; @@ -29,26 +28,15 @@ export class KeypressTabComponent extends Tab implements OnChanges { constructor(private mapper: MapperService) { super(); - this.leftModifiers = [ - 'LShift', - 'LCtrl', - mapper.getOsSpecificText('LAlt'), - mapper.getOsSpecificText('LSuper') - ]; - this.rightModifiers = [ - 'RShift', - 'RCtrl', - mapper.getOsSpecificText('RAlt'), - mapper.getOsSpecificText('RSuper') - ]; + this.leftModifiers = mapper.getLeftKeyModifiers(); + this.rightModifiers = mapper.getRightKeyModifiers(); + this.scanCodeGroups = [{ id: '0', text: 'None' }]; this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES); this.secondaryRoleGroups = SECONDARY_ROLES; - this.leftModifierSelects = Array(this.leftModifiers.length).fill(false); - this.rightModifierSelects = Array(this.rightModifiers.length).fill(false); this.selectedScancodeOption = this.scanCodeGroups[0]; this.selectedSecondaryRoleIndex = -1; } @@ -66,15 +54,15 @@ export class KeypressTabComponent extends Tab implements OnChanges { return (keystrokeAction) ? (keystrokeAction.scancode > 0 || keystrokeAction.modifierMask > 0) : false; } - onKeysCapture(event: { code: number, left: boolean[], right: boolean[] }) { + onKeysCapture(event: { code: number, left: KeyModifierModel[], right: KeyModifierModel[] }) { if (event.code) { this.selectedScancodeOption = this.findScancodeOptionByScancode(event.code, KeystrokeType.basic); } else { this.selectedScancodeOption = this.scanCodeGroups[0]; } - this.leftModifierSelects = event.left; - this.rightModifierSelects = event.right; + this.leftModifiers = event.left; + this.rightModifiers = event.right; this.validAction.emit(this.keyActionValid()); } @@ -86,16 +74,12 @@ export class KeypressTabComponent extends Tab implements OnChanges { // Restore selectedScancodeOption this.selectedScancodeOption = this.findScancodeOptionByScancode(keystrokeAction.scancode || 0, keystrokeAction.type); - const leftModifiersLength: number = this.leftModifiers.length; - - // Restore modifiers - for (let i = 0; i < leftModifiersLength; ++i) { - this.leftModifierSelects[this.mapper.modifierMapper(i)] = ((keystrokeAction.modifierMask >> i) & 1) === 1; + for (const modifier of this.leftModifiers) { + modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0; } - for (let i = leftModifiersLength; i < leftModifiersLength + this.rightModifierSelects.length; ++i) { - const index: number = this.mapper.modifierMapper(i) - leftModifiersLength; - this.rightModifierSelects[index] = ((keystrokeAction.modifierMask >> i) & 1) === 1; + for (const modifier of this.rightModifiers) { + modifier.checked = (keystrokeAction.modifierMask & modifier.value) > 0; } // Restore secondaryRoleAction @@ -117,11 +101,7 @@ export class KeypressTabComponent extends Tab implements OnChanges { } else { keystrokeAction.type = KeystrokeType[scTypePair[1]]; } - keystrokeAction.modifierMask = 0; - const modifiers = this.leftModifierSelects.concat(this.rightModifierSelects).map(x => x ? 1 : 0); - for (let i = 0; i < modifiers.length; ++i) { - keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i); - } + keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(this.leftModifiers, this.rightModifiers); keystrokeAction.secondaryRoleAction = this.selectedSecondaryRoleIndex === -1 ? undefined @@ -132,9 +112,8 @@ export class KeypressTabComponent extends Tab implements OnChanges { } } - toggleModifier(right: boolean, index: number) { - const modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects; - modifierSelects[index] = !modifierSelects[index]; + toggleModifier(modifier: KeyModifierModel): void { + modifier.checked = !modifier.checked; this.validAction.emit(this.keyActionValid()); } @@ -149,6 +128,10 @@ export class KeypressTabComponent extends Tab implements OnChanges { this.validAction.emit(this.keyActionValid()); } + modifiersTrackBy(index: number, modifier: KeyModifierModel): string { + return `${modifier.value}${modifier.checked}`; + } + private findScancodeOptionBy(predicate: (option: SelectOptionData) => boolean): SelectOptionData { let selectedOption: SelectOptionData; diff --git a/packages/uhk-web/src/app/components/popover/widgets/capture-keystroke/capture-keystroke-button.component.ts b/packages/uhk-web/src/app/components/popover/widgets/capture-keystroke/capture-keystroke-button.component.ts index 90a4335e..b4d52462 100644 --- a/packages/uhk-web/src/app/components/popover/widgets/capture-keystroke/capture-keystroke-button.component.ts +++ b/packages/uhk-web/src/app/components/popover/widgets/capture-keystroke/capture-keystroke-button.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output } from '@angular/core'; import { CaptureService } from '../../../../services/capture.service'; +import { KeyModifierModel } from '../../../../models/key-modifier-model'; @Component({ selector: 'capture-keystroke-button', @@ -68,8 +69,8 @@ export class CaptureKeystrokeButtonComponent { private saveScanCode(code?: number) { this.record = false; - const left: boolean[] = this.captureService.getModifiers(true); - const right: boolean[] = this.captureService.getModifiers(false); + const left: KeyModifierModel[] = this.captureService.getModifiers(true); + const right: KeyModifierModel[] = this.captureService.getModifiers(false); this.capture.emit({ code, diff --git a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts index 84707d32..10fd4f97 100644 --- a/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts +++ b/packages/uhk-web/src/app/components/svg/keys/svg-keyboard-key/svg-keyboard-key.component.ts @@ -28,6 +28,7 @@ import { AppState } from '../../../../store'; import { getMacros } from '../../../../store/reducers/user-configuration'; import { SvgKeyCaptureEvent, SvgKeyClickEvent } from '../../../../models/svg-key-events'; import { OperatingSystem } from '../../../../models/operating-system'; +import { KeyModifierModel } from '../../../../models/key-modifier-model'; enum LabelTypes { KeystrokeKey, @@ -250,8 +251,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy { } private saveScanCode(code = 0) { - const left: boolean[] = this.captureService.getModifiers(true); - const right: boolean[] = this.captureService.getModifiers(false); + const left: KeyModifierModel[] = this.captureService.getModifiers(true); + const right: KeyModifierModel[] = this.captureService.getModifiers(false); this.capture.emit({ captured: { diff --git a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts index 44928606..7fc260f5 100644 --- a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts +++ b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts @@ -49,6 +49,7 @@ import { SvgKeyHoverEvent } from '../../../models/svg-key-events'; import { RemapInfo } from '../../../models/remap-info'; +import { mapLeftRigthModifierToKeyActionModifier } from '../../../util'; interface NameValuePair { name: string; @@ -181,14 +182,9 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges { onCapture(event: SvgKeyboardCaptureEvent): void { const keystrokeAction: KeystrokeAction = new KeystrokeAction(); - const modifiers = event.captured.left.concat(event.captured.right).map(x => x ? 1 : 0); keystrokeAction.scancode = event.captured.code; - keystrokeAction.modifierMask = 0; - - for (let i = 0; i < modifiers.length; ++i) { - keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i); - } + keystrokeAction.modifierMask = mapLeftRigthModifierToKeyActionModifier(event.captured.left, event.captured.right); this.store.dispatch( KeymapActions.saveKey( diff --git a/packages/uhk-web/src/app/models/key-modifier-model.ts b/packages/uhk-web/src/app/models/key-modifier-model.ts new file mode 100644 index 00000000..46eea689 --- /dev/null +++ b/packages/uhk-web/src/app/models/key-modifier-model.ts @@ -0,0 +1,7 @@ +import { KeyModifiers } from 'uhk-common'; + +export interface KeyModifierModel { + text: string; + value: KeyModifiers; + checked: boolean; +} diff --git a/packages/uhk-web/src/app/models/svg-key-events.ts b/packages/uhk-web/src/app/models/svg-key-events.ts index 8a94a72d..e0831d2b 100644 --- a/packages/uhk-web/src/app/models/svg-key-events.ts +++ b/packages/uhk-web/src/app/models/svg-key-events.ts @@ -1,3 +1,5 @@ +import { KeyModifierModel } from './key-modifier-model'; + export interface SvgKeyClickEvent { keyTarget: HTMLElement; shiftPressed?: boolean; @@ -14,8 +16,8 @@ export interface SvgKeyboardKeyClickEvent extends SvgModuleKeyClickEvent { export interface KeyCaptureData { code: number; - left: boolean[]; - right: boolean[]; + left: KeyModifierModel[]; + right: KeyModifierModel[]; } export interface SvgKeyCaptureEvent { diff --git a/packages/uhk-web/src/app/services/capture.service.ts b/packages/uhk-web/src/app/services/capture.service.ts index 1362820c..13d10215 100644 --- a/packages/uhk-web/src/app/services/capture.service.ts +++ b/packages/uhk-web/src/app/services/capture.service.ts @@ -1,14 +1,18 @@ import { Injectable } from '@angular/core'; +import { MapperService } from './mapper.service'; +import { KeyModifiers } from 'uhk-common'; +import { KeyModifierModel } from '../models/key-modifier-model'; + @Injectable() export class CaptureService { private mapping: Map; - private leftModifiers: Map; - private rightModifiers: Map; + private readonly leftModifiers: Map; + private readonly rightModifiers: Map; - constructor() { - this.leftModifiers = new Map(); - this.rightModifiers = new Map(); + constructor(private mapper: MapperService) { + this.leftModifiers = new Map(); + this.rightModifiers = new Map(); this.mapping = new Map(); } @@ -21,26 +25,61 @@ export class CaptureService { } public setModifier(left: boolean, code: number) { - return left ? this.leftModifiers.set(code, true) : this.rightModifiers.set(code, true); + const map = left ? this.leftModifiers : this.rightModifiers; + map.get(code).checked = true; } public getModifiers(left: boolean) { - return left ? this.reMap(this.leftModifiers) : this.reMap(this.rightModifiers); + const map = left ? this.leftModifiers : this.rightModifiers; + + return Array.from(map.values()); } public initModifiers() { - this.leftModifiers.set(16, false); // Shift - this.leftModifiers.set(17, false); // Ctrl - this.leftModifiers.set(18, false); // Alt - this.leftModifiers.set(91, false); // Super + this.leftModifiers.set(16, { + text: 'LShift', + value: KeyModifiers.leftShift, + checked: false + }); + this.leftModifiers.set(17, { + text: 'LCtrl', + value: KeyModifiers.leftCtrl, + checked: false + }); + this.leftModifiers.set(18, { + text: this.mapper.getOsSpecificText('LAlt'), + value: KeyModifiers.leftAlt, + checked: false + }); + this.leftModifiers.set(91, { + text: this.mapper.getOsSpecificText('LSuper'), + value: KeyModifiers.leftGui, + checked: false + }); - this.rightModifiers.set(16, false); // Shift - this.rightModifiers.set(17, false); // Ctrl - this.rightModifiers.set(18, false); // Alt - this.rightModifiers.set(91, false); // Super + this.rightModifiers.set(16, { + text: 'RShift', + value: KeyModifiers.rightShift, + checked: false + }); + this.rightModifiers.set(17, { + text: 'RCtrl', + value: KeyModifiers.rightCtrl, + checked: false + }); + this.rightModifiers.set(18, { + text: this.mapper.getOsSpecificText('RAlt'), + value: KeyModifiers.rightAlt, + checked: false + }); + this.rightModifiers.set(91, { + text: this.mapper.getOsSpecificText('RSuper'), + value: KeyModifiers.rightGui, + checked: false + }); } - public populateMapping () { + public populateMapping() { this.mapping.set(8, 42); // Backspace this.mapping.set(9, 43); // Tab this.mapping.set(13, 40); // Enter @@ -136,8 +175,4 @@ export class CaptureService { this.mapping.set(221, 48); // Close bracket this.mapping.set(222, 52); // Single quote } - - private reMap(value: Map): boolean[] { - return [value.get(16), value.get(17), value.get(91), value.get(18)]; - } } diff --git a/packages/uhk-web/src/app/services/mapper.service.ts b/packages/uhk-web/src/app/services/mapper.service.ts index 12a1e72d..29f701ea 100644 --- a/packages/uhk-web/src/app/services/mapper.service.ts +++ b/packages/uhk-web/src/app/services/mapper.service.ts @@ -1,10 +1,11 @@ import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; -import { KeystrokeType, SecondaryRoleAction } from 'uhk-common'; +import { KeyModifiers, KeystrokeType, SecondaryRoleAction } from 'uhk-common'; import { Subscription } from 'rxjs/Subscription'; import { AppState, getOperatingSystem } from '../store'; import { OperatingSystem } from '../models/operating-system'; +import { KeyModifierModel } from '../models/key-modifier-model'; @Injectable() export class MapperService { @@ -124,6 +125,56 @@ export class MapperService { return this.secondaryRoleTexts.get(secondaryRoleAction); } + public getLeftKeyModifiers(): KeyModifierModel[] { + return [ + { + text: 'LShift', + value: KeyModifiers.leftShift, + checked: false + }, + { + text: 'LCtrl', + value: KeyModifiers.leftCtrl, + checked: false + }, + { + text: this.getOsSpecificText('LAlt'), + value: KeyModifiers.leftAlt, + checked: false + }, + { + text: this.getOsSpecificText('LSuper'), + value: KeyModifiers.leftGui, + checked: false + } + ]; + } + + public getRightKeyModifiers(): KeyModifierModel[] { + return [ + { + text: 'RShift', + value: KeyModifiers.rightShift, + checked: false + }, + { + text: 'RCtrl', + value: KeyModifiers.rightCtrl, + checked: false + }, + { + text: this.getOsSpecificText('RAlt'), + value: KeyModifiers.rightAlt, + checked: false + }, + { + text: this.getOsSpecificText('RSuper'), + value: KeyModifiers.rightGui, + checked: false + } + ]; + } + private initOsSpecificText(): void { this.osSpecificTexts = new Map(); diff --git a/packages/uhk-web/src/app/util/index.ts b/packages/uhk-web/src/app/util/index.ts index ed8b9d83..5080c45d 100644 --- a/packages/uhk-web/src/app/util/index.ts +++ b/packages/uhk-web/src/app/util/index.ts @@ -1,4 +1,5 @@ export * from './find-new-item'; export * from './html-helper'; +export * from './key-modifier-model-mapper'; export * from './validators'; export * from './version-helper'; diff --git a/packages/uhk-web/src/app/util/key-modifier-model-mapper.ts b/packages/uhk-web/src/app/util/key-modifier-model-mapper.ts new file mode 100644 index 00000000..611367ba --- /dev/null +++ b/packages/uhk-web/src/app/util/key-modifier-model-mapper.ts @@ -0,0 +1,13 @@ +import { KeyModifierModel } from '../models/key-modifier-model'; + +export const mapLeftRigthModifierToKeyActionModifier = (left: KeyModifierModel[], right: KeyModifierModel[]): number => { + const modifiers = [...left, ...right]; + let result = 0; + for (const modifier of modifiers) { + if (modifier.checked) { + result |= modifier.value; + } + } + + return result; +};