diff --git a/packages/uhk-web/src/app/app.component.html b/packages/uhk-web/src/app/app.component.html
index c847097f..bbe29074 100644
--- a/packages/uhk-web/src/app/app.component.html
+++ b/packages/uhk-web/src/app/app.component.html
@@ -9,7 +9,7 @@
diff --git a/packages/uhk-web/src/app/app.component.ts b/packages/uhk-web/src/app/app.component.ts
index 20368e60..564cedae 100644
--- a/packages/uhk-web/src/app/app.component.ts
+++ b/packages/uhk-web/src/app/app.component.ts
@@ -1,6 +1,7 @@
-import { Component, ViewEncapsulation } from '@angular/core';
+import { Component, HostListener, ViewEncapsulation, OnDestroy } from '@angular/core';
import { animate, style, transition, trigger } from '@angular/animations';
import { Observable } from 'rxjs/Observable';
+import { Subscription } from 'rxjs/Subscription';
import { Action, Store } from '@ngrx/store';
import 'rxjs/add/operator/last';
@@ -34,17 +35,35 @@ import { ProgressButtonState } from './store/reducers/progress-button-state';
])
]
})
-export class MainAppComponent {
+export class MainAppComponent implements OnDestroy {
showUpdateAvailable$: Observable;
deviceConfigurationLoaded$: Observable;
runningInElectron$: Observable;
- saveToKeyboardState$: Observable;
+ saveToKeyboardState: ProgressButtonState;
+
+ private saveToKeyboardStateSubscription: Subscription;
constructor(private store: Store) {
this.showUpdateAvailable$ = store.select(getShowAppUpdateAvailable);
this.deviceConfigurationLoaded$ = store.select(deviceConfigurationLoaded);
this.runningInElectron$ = store.select(runningInElectron);
- this.saveToKeyboardState$ = store.select(saveToKeyboardState);
+ this.saveToKeyboardStateSubscription = store.select(saveToKeyboardState)
+ .subscribe(data => this.saveToKeyboardState = data);
+ }
+
+ ngOnDestroy(): void {
+ this.saveToKeyboardStateSubscription.unsubscribe();
+ }
+
+ @HostListener('document:keydown', ['$event'])
+ onKeyDown(event: KeyboardEvent) {
+ if (this.saveToKeyboardState.showButton &&
+ event.ctrlKey &&
+ event.key === 's' &&
+ !event.defaultPrevented) {
+ this.clickedOnProgressButton(this.saveToKeyboardState.action);
+ event.preventDefault();
+ }
}
updateApp() {
diff --git a/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.html b/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.html
index 544e08b3..c9f01e42 100644
--- a/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.html
+++ b/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.html
@@ -9,6 +9,7 @@
[keyboardLayout]="keyboardLayout"
[description]="description"
[showDescription]="true"
+ oncontextmenu="return false;"
(keyClick)="keyClick.emit($event)"
(keyHover)="keyHover.emit($event)"
(capture)="capture.emit($event)"
diff --git a/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.ts b/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.ts
index ed590348..c452d080 100644
--- a/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.ts
+++ b/packages/uhk-web/src/app/components/keyboard/slider/keyboard-slider.component.ts
@@ -3,6 +3,11 @@ import { animate, keyframes, state, style, transition, trigger } from '@angular/
import { Layer } from 'uhk-common';
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
+import {
+ SvgKeyboardCaptureEvent,
+ SvgKeyboardKeyClickEvent,
+ SvgKeyHoverEvent
+} from '../../../models/svg-key-events';
type AnimationKeyboard =
'init' |
@@ -82,9 +87,9 @@ export class KeyboardSliderComponent implements OnChanges {
@Input() selectedKey: { layerId: number, moduleId: number, keyId: number };
@Input() keyboardLayout = KeyboardLayout.ANSI;
@Input() description: string;
- @Output() keyClick = new EventEmitter();
- @Output() keyHover = new EventEmitter();
- @Output() capture = new EventEmitter();
+ @Output() keyClick = new EventEmitter();
+ @Output() keyHover = new EventEmitter();
+ @Output() capture = new EventEmitter();
@Output() descriptionChanged = new EventEmitter();
layerAnimationState: AnimationKeyboard[];
diff --git a/packages/uhk-web/src/app/components/popover/popover.component.ts b/packages/uhk-web/src/app/components/popover/popover.component.ts
index 0c2a7387..885ff0fb 100644
--- a/packages/uhk-web/src/app/components/popover/popover.component.ts
+++ b/packages/uhk-web/src/app/components/popover/popover.component.ts
@@ -84,6 +84,8 @@ export class PopoverComponent implements OnChanges {
@Input() wrapPosition: any;
@Input() visible: boolean;
@Input() allowLayerDoubleTap: boolean;
+ @Input() remapOnAllKeymap: boolean;
+ @Input() remapOnAllLayer: boolean;
@Output() cancel = new EventEmitter();
@Output() remap = new EventEmitter();
@@ -101,9 +103,6 @@ export class PopoverComponent implements OnChanges {
leftPosition: number = 0;
animationState: string;
- remapOnAllKeymap: boolean;
- remapOnAllLayer: boolean;
-
private readonly currentKeymap$ = new BehaviorSubject(undefined);
constructor(store: Store) {
@@ -143,8 +142,6 @@ export class PopoverComponent implements OnChanges {
if (change['visible']) {
if (change['visible'].currentValue) {
this.animationState = 'opened';
- this.remapOnAllKeymap = false;
- this.remapOnAllLayer = false;
} else {
this.animationState = 'closed';
}
@@ -179,6 +176,14 @@ export class PopoverComponent implements OnChanges {
this.cancel.emit();
}
+ @HostListener('document:keydown.control.enter', ['$event'])
+ onKeyDown(event: KeyboardEvent) {
+ if (this.visible) {
+ this.onRemapKey();
+ event.preventDefault();
+ }
+ }
+
selectTab(tab: TabName): void {
this.activeTab = tab;
}
diff --git a/packages/uhk-web/src/app/components/svg/keyboard/svg-keyboard.component.html b/packages/uhk-web/src/app/components/svg/keyboard/svg-keyboard.component.html
index b16e44be..9f02ef01 100644
--- a/packages/uhk-web/src/app/components/svg/keyboard/svg-keyboard.component.html
+++ b/packages/uhk-web/src/app/components/svg/keyboard/svg-keyboard.component.html
@@ -13,9 +13,9 @@
[selectedKey]="selectedKey"
[@split]="moduleAnimationStates[i]"
[selected]="selectedKey?.moduleId === i"
- (keyClick)="onKeyClick(i, $event.index, $event.keyTarget)"
+ (keyClick)="onKeyClick(i, $event)"
(keyHover)="onKeyHover($event.index, $event.event, $event.over, i)"
- (capture)="onCapture(i, $event.index, $event.captured)" />
+ (capture)="onCapture(i, $event)" />
();
+ @Output() keyHover = new EventEmitter();
+ @Output() capture = new EventEmitter();
@Output() descriptionChanged = new EventEmitter();
modules: SvgModule[];
@@ -79,19 +85,17 @@ export class SvgKeyboardComponent implements OnInit {
}
}
- onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
+ onKeyClick(moduleId: number, event: SvgModuleKeyClickEvent): void {
this.keyClick.emit({
- moduleId,
- keyId,
- keyTarget
+ ...event,
+ moduleId
});
}
- onCapture(moduleId: number, keyId: number, captured: { code: number, left: boolean[], right: boolean[] }): void {
+ onCapture(moduleId: number, event: SvgKeyboardCaptureEvent): void {
this.capture.emit({
- moduleId,
- keyId,
- captured
+ ...event,
+ moduleId
});
}
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 d6e45ddc..704b89ae 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
@@ -26,6 +26,7 @@ import { MapperService } from '../../../../services/mapper.service';
import { AppState } from '../../../../store';
import { getMacros } from '../../../../store/reducers/user-configuration';
+import { SvgKeyCaptureEvent, SvgKeyClickEvent } from '../../../../models/svg-key-events';
enum LabelTypes {
KeystrokeKey,
@@ -82,8 +83,8 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
@Input() capturingEnabled: boolean;
@Input() active: boolean;
- @Output() keyClick = new EventEmitter();
- @Output() capture = new EventEmitter();
+ @Output() keyClick = new EventEmitter();
+ @Output() capture = new EventEmitter();
enumLabelTypes = LabelTypes;
@@ -96,6 +97,10 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
macros: Macro[];
private subscription: Subscription;
private scanCodePressed: boolean;
+ private pressedShiftLocation = -1;
+ private pressedAltLocation = -1;
+ private altPressed = false;
+ private shitPressed = false;
constructor(
private mapper: MapperService,
@@ -115,12 +120,16 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
@HostListener('click')
onClick() {
this.reset();
- this.keyClick.emit(this.element.nativeElement);
+ this.keyClick.emit({
+ keyTarget: this.element.nativeElement,
+ shiftPressed: this.pressedShiftLocation > -1,
+ altPressed: this.pressedAltLocation > -1
+ });
}
@HostListener('mousedown', ['$event'])
onMouseDown(e: MouseEvent) {
- if ((e.which === 2 || e.button === 1) && this.capturingEnabled) {
+ if ((e.which === 2 || e.button === 2) && this.capturingEnabled) {
e.preventDefault();
this.renderer.invokeElementMethod(this.element.nativeElement, 'focus');
@@ -129,13 +138,29 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
} else {
this.recording = true;
this.recordAnimation = 'active';
+
+ if (this.pressedShiftLocation > -1) {
+ this.shitPressed = true;
+ }
+
+ if (this.pressedAltLocation > -1) {
+ this.altPressed = true;
+ }
}
}
}
- @HostListener('keyup', ['$event'])
+ @HostListener('document:keyup', ['$event'])
onKeyUp(e: KeyboardEvent) {
- if (this.scanCodePressed) {
+ if (e.keyCode === 18 && this.pressedAltLocation > -1) {
+ this.pressedAltLocation = -1;
+ e.preventDefault();
+ }
+ else if (e.keyCode === 16 && this.pressedShiftLocation > -1) {
+ this.pressedShiftLocation = -1;
+ e.preventDefault();
+ }
+ else if (this.scanCodePressed) {
e.preventDefault();
this.scanCodePressed = false;
} else if (this.recording) {
@@ -144,7 +169,7 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
}
}
- @HostListener('keydown', ['$event'])
+ @HostListener('document:keydown', ['$event'])
onKeyDown(e: KeyboardEvent) {
const code: number = e.keyCode;
@@ -152,11 +177,29 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
e.preventDefault();
if (this.captureService.hasMap(code)) {
+ // If the Alt or Shift key not released after start the capturing
+ // then add them as a modifier
+ if (this.pressedShiftLocation > -1) {
+ this.captureService.setModifier((this.pressedShiftLocation === 1), 16);
+ }
+
+ if (this.pressedAltLocation > -1) {
+ this.captureService.setModifier((this.pressedAltLocation === 1), 18);
+ }
+
this.saveScanCode(this.captureService.getMap(code));
this.scanCodePressed = true;
} else {
this.captureService.setModifier((e.location === 1), code);
}
+ } else {
+ if (e.keyCode === 16) {
+ this.pressedShiftLocation = e.location;
+ }
+
+ if (e.keyCode === 18) {
+ this.pressedAltLocation = e.location;
+ }
}
}
@@ -198,22 +241,25 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
this.recording = false;
this.changeAnimation = 'inactive';
this.captureService.initModifiers();
+ this.shitPressed = false;
+ this.altPressed = false;
}
private saveScanCode(code = 0) {
- this.recording = false;
- this.changeAnimation = 'inactive';
-
const left: boolean[] = this.captureService.getModifiers(true);
const right: boolean[] = this.captureService.getModifiers(false);
this.capture.emit({
- code,
- left,
- right
+ captured: {
+ code,
+ left,
+ right
+ },
+ shiftPressed: this.shitPressed,
+ altPressed: this.altPressed
});
- this.captureService.initModifiers();
+ this.reset();
}
private setLabels(): void {
diff --git a/packages/uhk-web/src/app/components/svg/module/svg-module.component.ts b/packages/uhk-web/src/app/components/svg/module/svg-module.component.ts
index 22ce34f7..066f5b05 100644
--- a/packages/uhk-web/src/app/components/svg/module/svg-module.component.ts
+++ b/packages/uhk-web/src/app/components/svg/module/svg-module.component.ts
@@ -2,6 +2,12 @@ import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from
import { KeyAction } from 'uhk-common';
import { SvgKeyboardKey } from '../keys';
+import {
+ SvgKeyCaptureEvent,
+ SvgKeyClickEvent,
+ SvgModuleCaptureEvent,
+ SvgModuleKeyClickEvent
+} from '../../../models/svg-key-events';
@Component({
selector: 'g[svg-module]',
@@ -17,18 +23,18 @@ export class SvgModuleComponent {
@Input() selected: boolean;
@Input() keybindAnimationEnabled: boolean;
@Input() capturingEnabled: boolean;
- @Output() keyClick = new EventEmitter();
+ @Output() keyClick = new EventEmitter();
@Output() keyHover = new EventEmitter();
- @Output() capture = new EventEmitter();
+ @Output() capture = new EventEmitter();
constructor() {
this.keyboardKeys = [];
}
- onKeyClick(index: number, keyTarget: HTMLElement): void {
+ onKeyClick(keyId: number, event: SvgKeyClickEvent): void {
this.keyClick.emit({
- index,
- keyTarget
+ ...event,
+ keyId
});
}
@@ -40,10 +46,10 @@ export class SvgModuleComponent {
});
}
- onCapture(index: number, captured: {code: number, left: boolean[], right: boolean[]}) {
+ onCapture(keyId: number, event: SvgKeyCaptureEvent) {
this.capture.emit({
- index,
- captured
+ ...event,
+ keyId
});
}
}
diff --git a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.html b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.html
index 48327568..2e1d70d2 100644
--- a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.html
+++ b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.html
@@ -8,9 +8,9 @@
[halvesSplit]="halvesSplit"
[keyboardLayout]="keyboardLayout"
[description]="keymap.description"
- (keyClick)="onKeyClick($event.moduleId, $event.keyId, $event.keyTarget)"
- (keyHover)="onKeyHover($event.moduleId, $event.event, $event.over, $event.keyId)"
- (capture)="onCapture($event.moduleId, $event.keyId, $event.captured)"
+ (keyClick)="onKeyClick($event)"
+ (keyHover)="onKeyHover($event)"
+ (capture)="onCapture($event)"
(descriptionChanged)="onDescriptionChanged($event)"
>
@@ -22,6 +22,8 @@
[currentKeymap]="keymap"
[currentLayer]="currentLayer"
[allowLayerDoubleTap]="allowLayerDoubleTap"
+ [remapOnAllKeymap]="remapOnAllKeymap"
+ [remapOnAllLayer]="remapOnAllLayer"
(cancel)="hidePopover()"
(remap)="onRemap($event)">
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 7b020409..c735d2d4 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
@@ -43,6 +43,11 @@ import { PopoverComponent } from '../../popover';
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription';
import { KeyActionRemap } from '../../../models/key-action-remap';
+import {
+ SvgKeyboardCaptureEvent,
+ SvgKeyboardKeyClickEvent,
+ SvgKeyHoverEvent
+} from '../../../models/svg-key-events';
interface NameValuePair {
name: string;
@@ -65,7 +70,7 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
@Output() descriptionChanged = new EventEmitter();
- @ViewChild(PopoverComponent, { read: ElementRef }) popover: ElementRef;
+ @ViewChild(PopoverComponent, {read: ElementRef}) popover: ElementRef;
popoverShown: boolean;
keyEditConfig: { moduleId: number, keyId: number };
@@ -82,6 +87,9 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
layers: Layer[];
keyPosition: ClientRect;
wrapPosition: ClientRect;
+ remapOnAllKeymap: boolean;
+ remapOnAllLayer: boolean;
+
private wrapHost: HTMLElement;
private keyElement: HTMLElement;
@@ -139,36 +147,38 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
}
- onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
+ onKeyClick(event: SvgKeyboardKeyClickEvent): void {
if (!this.popoverShown && this.popoverEnabled) {
this.keyEditConfig = {
- moduleId,
- keyId
+ moduleId: event.moduleId,
+ keyId: event.keyId
};
- this.selectedKey = { layerId: this.currentLayer, moduleId, keyId };
- const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[moduleId].keyActions[keyId];
- this.keyElement = keyTarget;
+ this.selectedKey = {layerId: this.currentLayer, moduleId: event.moduleId, keyId: event.keyId};
+ const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[event.moduleId].keyActions[event.keyId];
+ this.keyElement = event.keyTarget;
+ this.remapOnAllKeymap = event.shiftPressed;
+ this.remapOnAllLayer = event.altPressed;
this.showPopover(keyActionToEdit);
}
}
- onKeyHover(moduleId: number, event: MouseEvent, over: boolean, keyId: number): void {
+ onKeyHover(event: SvgKeyHoverEvent): void {
if (this.tooltipEnabled) {
- const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[moduleId].keyActions[keyId];
+ const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[event.moduleId].keyActions[event.keyId];
- if (over) {
- this.showTooltip(keyActionToEdit, event);
+ if (event.over) {
+ this.showTooltip(keyActionToEdit, event.event);
} else {
this.hideTooltip();
}
}
}
- onCapture(moduleId: number, keyId: number, captured: { code: number, left: boolean[], right: boolean[] }): void {
+ onCapture(event: SvgKeyboardCaptureEvent): void {
const keystrokeAction: KeystrokeAction = new KeystrokeAction();
- const modifiers = captured.left.concat(captured.right).map(x => x ? 1 : 0);
+ const modifiers = event.captured.left.concat(event.captured.right).map(x => x ? 1 : 0);
- keystrokeAction.scancode = captured.code;
+ keystrokeAction.scancode = event.captured.code;
keystrokeAction.modifierMask = 0;
for (let i = 0; i < modifiers.length; ++i) {
@@ -179,11 +189,11 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
KeymapActions.saveKey(
this.keymap,
this.currentLayer,
- moduleId,
- keyId,
+ event.moduleId,
+ event.keyId,
{
- remapOnAllKeymap: false,
- remapOnAllLayer: false,
+ remapOnAllKeymap: event.shiftPressed,
+ remapOnAllLayer: event.altPressed,
action: keystrokeAction
})
);
diff --git a/packages/uhk-web/src/app/models/svg-key-events.ts b/packages/uhk-web/src/app/models/svg-key-events.ts
new file mode 100644
index 00000000..8a94a72d
--- /dev/null
+++ b/packages/uhk-web/src/app/models/svg-key-events.ts
@@ -0,0 +1,42 @@
+export interface SvgKeyClickEvent {
+ keyTarget: HTMLElement;
+ shiftPressed?: boolean;
+ altPressed?: boolean;
+}
+
+export interface SvgModuleKeyClickEvent extends SvgKeyClickEvent {
+ keyId: number;
+}
+
+export interface SvgKeyboardKeyClickEvent extends SvgModuleKeyClickEvent {
+ moduleId: number;
+}
+
+export interface KeyCaptureData {
+ code: number;
+ left: boolean[];
+ right: boolean[];
+}
+
+export interface SvgKeyCaptureEvent {
+ captured: KeyCaptureData;
+ shiftPressed?: boolean;
+ altPressed?: boolean;
+}
+
+export interface SvgModuleCaptureEvent extends SvgKeyCaptureEvent {
+ keyId: number;
+}
+
+export interface SvgKeyboardCaptureEvent extends SvgModuleCaptureEvent {
+ moduleId: number;
+}
+
+export interface SvgKeyHoverEvent {
+ keyId: number;
+ event: MouseEvent;
+ over: boolean;
+ moduleId: number;
+ shiftPressed?: boolean;
+ altPressed?: boolean;
+}