Seperate electron and web target building

This commit is contained in:
Farkas József
2017-01-20 02:03:27 +01:00
committed by József Farkas
parent 517aed1b1c
commit 983eb72892
276 changed files with 2154 additions and 95 deletions

View File

@@ -0,0 +1 @@
export * from './svg-keyboard.component';

View File

@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" [attr.viewBox]="svgAttributes.viewBox" height="100%" width="100%">
<svg:g [attr.transform]="svgAttributes.transform" [attr.fill]="svgAttributes.fill">
<svg:g svg-module *ngFor="let module of modules; let i = index"
[coverages]="module.coverages"
[keyboardKeys]="module.keyboardKeys"
[keybindAnimationEnabled]="keybindAnimationEnabled"
[capturingEnabled]="capturingEnabled"
[attr.transform]="module.attributes.transform"
[keyActions]="moduleConfig[i].keyActions"
(keyClick)="onKeyClick(i, $event.index, $event.keyTarget)"
(keyHover)="onKeyHover($event.index, $event.event, $event.over, i)"
(capture)="onCapture(i, $event.index, $event.captured)"
/>
</svg:g>
</svg>

After

Width:  |  Height:  |  Size: 871 B

View File

@@ -0,0 +1,6 @@
:host {
display: flex;
width: 100%;
height: 100%;
position: relative;
}

View File

@@ -0,0 +1,74 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Module } from '../../../config-serializer/config-items/Module';
import { SvgModule } from '../module';
@Component({
selector: 'svg-keyboard',
template: require('./svg-keyboard.component.html'),
styles: [require('./svg-keyboard.component.scss')]
})
export class SvgKeyboardComponent implements OnInit {
@Input() moduleConfig: Module[];
@Input() keybindAnimationEnabled: boolean;
@Input() capturingEnabled: boolean;
@Output() keyClick = new EventEmitter();
@Output() keyHover = new EventEmitter();
@Output() capture = new EventEmitter();
private modules: SvgModule[];
private svgAttributes: { viewBox: string, transform: string, fill: string };
constructor() {
this.modules = [];
this.svgAttributes = this.getKeyboardSvgAttributes();
}
ngOnInit() {
this.modules = this.getSvgModules();
}
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
this.keyClick.emit({
moduleId,
keyId,
keyTarget
});
}
onCapture(moduleId: number, keyId: number, captured: {code: number, left: boolean[], right: boolean[]}): void {
this.capture.emit({
moduleId,
keyId,
captured
});
}
onKeyHover(keyId: number, event: MouseEvent, over: boolean, moduleId: number): void {
this.keyHover.emit({
moduleId,
event,
over,
keyId
});
}
private getKeyboardSvgAttributes(): { viewBox: string, transform: string, fill: string } {
let svg: any = this.getBaseLayer();
return {
viewBox: svg.$.viewBox,
transform: svg.g[0].$.transform,
fill: svg.g[0].$.fill
};
}
private getSvgModules(): SvgModule[] {
let modules = this.getBaseLayer().g[0].g.map((obj: any) => new SvgModule(obj));
return [modules[1], modules[0]]; // TODO: remove if the svg will be correct
}
private getBaseLayer(): any {
return require('xml!../../../../../images/base-layer.svg').svg;
}
}

View File

@@ -0,0 +1,13 @@
export { SvgIconTextKeyComponent } from './svg-icon-text-key';
export { SvgKeyboardKeyComponent, SvgKeyboardKey } from './svg-keyboard-key';
export { SvgKeystrokeKeyComponent } from './svg-keystroke-key';
export { SvgMouseKeyComponent } from './svg-mouse-key';
export { SvgMouseClickKeyComponent } from './svg-mouse-click-key';
export { SvgMouseMoveKeyComponent } from './svg-mouse-move-key';
export { SvgMouseSpeedKeyComponent } from './svg-mouse-speed-key';
export { SvgMouseScrollKeyComponent } from './svg-mouse-scroll-key';
export { SvgOneLineTextKeyComponent } from './svg-one-line-text-key';
export { SvgSingleIconKeyComponent } from './svg-single-icon-key';
export { SvgSwitchKeymapKeyComponent } from './svg-switch-keymap-key';
export { SvgTextIconKeyComponent } from './svg-text-icon-key';
export { SvgTwoLineTextKeyComponent } from './svg-two-line-text-key';

View File

@@ -0,0 +1 @@
export * from './svg-icon-text-key.component';

View File

@@ -0,0 +1,13 @@
<svg:use [attr.xlink:href]="icon"
[attr.width]="useWidth"
[attr.height]="useHeight"
[attr.x]="useX"
[attr.y]="useY">
</svg:use>
<svg:text
[attr.x]="0"
[attr.y]="textY"
[attr.text-anchor]="'middle'"
[attr.font-size]="11">
<tspan [attr.x]="spanX">{{ text }}</tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 331 B

View File

@@ -0,0 +1,31 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'g[svg-icon-text-key]',
template: require('./svg-icon-text-key.component.html')
})
export class SvgIconTextKeyComponent implements OnInit {
@Input() width: number;
@Input() height: number;
@Input() icon: string;
@Input() text: string;
private useWidth: number;
private useHeight: number;
private useX: number;
private useY: number;
private textY: number;
private spanX: number;
constructor() {
}
ngOnInit() {
this.useWidth = this.width / 3;
this.useHeight = this.height / 3;
this.useX = (this.width > 2 * this.height) ? 0 : this.width / 3;
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 10;
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height * 0.6;
this.spanX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 2;
}
}

View File

@@ -0,0 +1,2 @@
export * from './svg-keyboard-key.component';
export * from './svg-keyboard-key.model';

View File

@@ -0,0 +1,65 @@
<svg:rect [@change]="changeAnimation"
(@change.done)="onChangeAnimationDone()"
[id]="id" [attr.rx]="rx" [attr.ry]="ry"
[attr.height]="height" [attr.width]="width"
[attr.fill]="fill"
/>
<template [ngIf]="recording">
<svg:circle
[@recording]="recordAnimation"
(@recording.done)="onRecordingAnimationDone()"
[attr.cx]="(width / 2)"
[attr.cy]="(height / 2)"
[attr.r]="10"
[attr.fill]="'#c00'"
></svg:circle>
</template>
<template [ngIf]="!recording">
<svg:g [ngSwitch]="labelType"
[attr.font-size]="19"
[attr.font-family]="'Helvetica'"
[attr.fill]="'white'">
<svg:g svg-keystroke-key *ngSwitchCase="enumLabelTypes.KeystrokeKey"
[height]="height"
[width]="width"
[keystrokeAction]="labelSource">
</svg:g>
<svg:g svg-one-line-text-key *ngSwitchCase="enumLabelTypes.OneLineText"
[height]="height"
[width]="width"
[text]="labelSource">
</svg:g>
<svg:g svg-two-line-text-key *ngSwitchCase="enumLabelTypes.TwoLineText"
[height]="height"
[width]="width"
[texts]="labelSource">
</svg:g>
<svg:g svg-text-icon-key *ngSwitchCase="enumLabelTypes.TextIcon"
[height]="height"
[width]="width"
[text]="labelSource.text"
[icon]="labelSource.icon">
</svg:g>
<svg:g svg-icon-text-key *ngSwitchCase="enumLabelTypes.IconText"
[height]="height"
[width]="width"
[icon]="labelSource.icon"
[text]="labelSource.text">
</svg:g>
<svg:g svg-single-icon-key *ngSwitchCase="enumLabelTypes.SingleIcon"
[height]="height"
[width]="width"
[icon]="labelSource">
</svg:g>
<svg:g svg-switch-keymap-key *ngSwitchCase="enumLabelTypes.SwitchKeymap"
[height]="height"
[width]="width"
[abbreviation]="labelSource">
</svg:g>
<svg *ngSwitchCase="enumLabelTypes.MouseKey" [attr.viewBox]="'0 0 100 100'"
[attr.width]="width"
[attr.height]="height">
<svg:g svg-mouse-key [mouseAction]="labelSource"></svg:g>
</svg>
</svg:g>
</template>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,12 @@
:host {
/deep/ text {
dominant-baseline: central;
}
cursor: pointer;
outline: none;
&:hover {
fill: #494949;
}
}

View File

@@ -0,0 +1,310 @@
import {
Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, Renderer,
SimpleChange, animate, group, state, style, transition, trigger
} from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs/Subscription';
import {
KeyAction,
KeystrokeAction,
LayerName,
MouseAction,
PlayMacroAction,
SwitchKeymapAction,
SwitchLayerAction
} from '../../../../config-serializer/config-items/key-action';
import { KeyModifiers } from '../../../../config-serializer/config-items/KeyModifiers';
import { Macro } from '../../../../config-serializer/config-items/Macro';
import { CaptureService } from '../../../../services/capture.service';
import { MapperService } from '../../../../services/mapper.service';
import { AppState } from '../../../../store/index';
import { getMacroEntities } from '../../../../store/reducers/macro';
enum LabelTypes {
KeystrokeKey,
MouseKey,
OneLineText,
TwoLineText,
TextIcon,
SingleIcon,
SwitchKeymap,
IconText
}
@Component({
animations: [
trigger('change', [
transition('inactive => active', [
style({ fill: '#fff' }),
group([
animate('1s ease-out', style({
fill: '#333'
}))
])
])
]),
trigger('recording', [
state('inactive', style({
fill: 'rgba(204, 0, 0, 1)'
})),
state('active', style({
fill: 'rgba(204, 0, 0, 0.6)'
})),
transition('inactive <=> active', animate('600ms ease-in-out'))
])
],
selector: 'g[svg-keyboard-key]',
template: require('./svg-keyboard-key.component.html'),
styles: [require('./svg-keyboard-key.component.scss')]
})
export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
@Input() id: string;
@Input() rx: string;
@Input() ry: string;
@Input() height: number;
@Input() width: number;
@Input() keyAction: KeyAction;
@Input() keybindAnimationEnabled: boolean;
@Input() capturingEnabled: boolean;
@Output() keyClick = new EventEmitter();
@Output() capture = new EventEmitter();
enumLabelTypes = LabelTypes;
public changeAnimation: string = 'inactive';
public recordAnimation: string;
private labelSource: any;
private labelType: LabelTypes;
private macros: Macro[];
private subscription: Subscription;
private recording: boolean;
private scanCodePressed: boolean;
@HostListener('click')
onClick() {
this.reset();
this.keyClick.emit(this.element.nativeElement);
}
@HostListener('mousedown', ['$event'])
onMouseDown(e: MouseEvent) {
if ((e.which === 2 || e.button === 1) && this.capturingEnabled) {
e.preventDefault();
this.renderer.invokeElementMethod(this.element.nativeElement, 'focus');
if (this.recording) {
this.reset();
} else {
this.recording = true;
this.recordAnimation = 'active';
}
}
}
@HostListener('keyup', ['$event'])
onKeyUpe(e: KeyboardEvent) {
if (this.scanCodePressed) {
e.preventDefault();
this.scanCodePressed = false;
} else if (this.recording) {
e.preventDefault();
this.saveScanCode();
}
}
@HostListener('keydown', ['$event'])
onKeyDown(e: KeyboardEvent) {
const code: number = e.keyCode;
if (this.recording) {
e.preventDefault();
if (this.captureService.hasMap(code)) {
this.saveScanCode(this.captureService.getMap(code));
this.scanCodePressed = true;
} else {
this.captureService.setModifier((e.location === 1), code);
}
}
}
@HostListener('focusout')
onFocusOut() {
this.reset();
}
constructor(
private mapper: MapperService,
private store: Store<AppState>,
private element: ElementRef,
private captureService: CaptureService,
private renderer: Renderer
) {
this.subscription = store.let(getMacroEntities())
.subscribe((macros: Macro[]) => this.macros = macros);
this.reset();
this.captureService.populateMapping();
this.scanCodePressed = false;
}
ngOnInit() {
this.setLabels();
}
ngOnChanges(changes: { [propertyName: string]: SimpleChange }) {
if (changes['keyAction']) {
this.setLabels();
if (this.keybindAnimationEnabled) {
this.changeAnimation = 'active';
}
}
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
onChangeAnimationDone() {
this.changeAnimation = 'inactive';
}
onRecordingAnimationDone() {
if (this.recording && this.recordAnimation === 'inactive') {
this.recordAnimation = 'active';
} else {
this.recordAnimation = 'inactive';
}
}
private reset() {
this.recording = false;
this.changeAnimation = 'inactive';
this.captureService.initModifiers();
}
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
});
this.captureService.initModifiers();
}
private setLabels(): void {
if (!this.keyAction) {
this.labelSource = undefined;
this.labelType = LabelTypes.OneLineText;
return;
}
this.labelType = LabelTypes.OneLineText;
if (this.keyAction instanceof KeystrokeAction) {
let keyAction: KeystrokeAction = this.keyAction as KeystrokeAction;
let newLabelSource: string[];
if (!keyAction.hasActiveModifier() && keyAction.hasScancode()) {
let scancode: number = keyAction.scancode;
newLabelSource = this.mapper.scanCodeToText(scancode);
if (this.mapper.hasScancodeIcon(scancode)) {
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode);
this.labelType = LabelTypes.SingleIcon;
} else if (newLabelSource !== undefined) {
if (newLabelSource.length === 1) {
this.labelSource = newLabelSource[0];
this.labelType = LabelTypes.OneLineText;
} else {
this.labelSource = newLabelSource;
this.labelType = LabelTypes.TwoLineText;
}
}
} else if (keyAction.hasOnlyOneActiveModifier() && !keyAction.hasScancode()) {
newLabelSource = [];
switch (keyAction.modifierMask) {
case KeyModifiers.leftCtrl:
case KeyModifiers.rightCtrl:
newLabelSource.push('Ctrl');
break;
case KeyModifiers.leftShift:
case KeyModifiers.rightShift:
newLabelSource.push('Shift');
break;
case KeyModifiers.leftAlt:
case KeyModifiers.rightAlt:
newLabelSource.push('Alt');
break;
case KeyModifiers.leftGui:
case KeyModifiers.rightGui:
newLabelSource.push('Super');
break;
default:
newLabelSource.push('Undefined');
break;
}
this.labelSource = newLabelSource;
} else {
this.labelType = LabelTypes.KeystrokeKey;
this.labelSource = this.keyAction;
}
} else if (this.keyAction instanceof SwitchLayerAction) {
let keyAction: SwitchLayerAction = this.keyAction as SwitchLayerAction;
let newLabelSource: string;
switch (keyAction.layer) {
case LayerName.mod:
newLabelSource = 'Mod';
break;
case LayerName.fn:
newLabelSource = 'Fn';
break;
case LayerName.mouse:
newLabelSource = 'Mouse';
break;
default:
break;
}
if (keyAction.isLayerToggleable) {
this.labelType = LabelTypes.TextIcon;
this.labelSource = {
text: newLabelSource,
icon: this.mapper.getIcon('toggle')
};
} else {
this.labelType = LabelTypes.OneLineText;
this.labelSource = newLabelSource;
}
} else if (this.keyAction instanceof SwitchKeymapAction) {
let keyAction: SwitchKeymapAction = this.keyAction as SwitchKeymapAction;
this.labelType = LabelTypes.SwitchKeymap;
this.labelSource = keyAction.keymapAbbreviation;
} else if (this.keyAction instanceof PlayMacroAction) {
let keyAction: PlayMacroAction = this.keyAction as PlayMacroAction;
const macro: Macro = this.macros.find((_macro: Macro) => _macro.id === keyAction.macroId);
this.labelType = LabelTypes.IconText;
this.labelSource = {
icon: this.mapper.getIcon('macro'),
text: macro.name
};
} else if (this.keyAction instanceof MouseAction) {
this.labelType = LabelTypes.MouseKey;
this.labelSource = this.keyAction;
} else {
this.labelSource = undefined;
}
}
}

View File

@@ -0,0 +1,9 @@
export interface SvgKeyboardKey {
id: string;
x: string;
y: string;
rx: string;
ry: string;
height: number;
width: number;
}

View File

@@ -0,0 +1 @@
export * from './svg-keystroke-key.component';

View File

@@ -0,0 +1,32 @@
<svg [attr.viewBox]="viewBox" [attr.width]="textContainer.width" [attr.height]="textContainer.height"
[attr.x]="textContainer.x" [attr.y]="textContainer.y" [ngSwitch]="labelType">
<svg:g svg-one-line-text-key *ngSwitchCase="'one-line'"
[height]="height"
[width]="width"
[text]="labelSource">
</svg:g>
<svg:g svg-two-line-text-key *ngSwitchCase="'two-line'"
[height]="height"
[width]="width"
[texts]="labelSource">
</svg:g>
</svg>
<svg [attr.viewBox]="viewBox" [attr.width]="modifierContainer.width" [attr.height]="modifierContainer.height" [attr.x]="modifierContainer.x"
[attr.y]="modifierContainer.y" preserveAspectRatio="none">
<svg viewBox="0 0 100 100" [attr.width]="shift.width" [attr.height]="shift.height" [attr.x]="shift.x" [attr.y]="shift.y"
preserveAspectRatio="none" [class.disabled]="shift.disabled">
<svg:use [attr.xlink:href]="modifierIconNames.shift" />
</svg>
<svg viewBox="0 0 100 100" [attr.width]="control.width" [attr.height]="control.height" [attr.x]="control.x" [attr.y]="control.y"
preserveAspectRatio="none" [class.disabled]="control.disabled">
<svg:text [attr.text-anchor]="'middle'" [attr.x]="50" [attr.y]="50">C</svg:text>
</svg>
<svg viewBox="0 0 100 100" [attr.width]="option.width" [attr.height]="option.height" [attr.x]="option.x" [attr.y]="option.y"
preserveAspectRatio="none" [class.disabled]="option.disabled">
<svg:use [attr.xlink:href]="modifierIconNames.option" />
</svg>
<svg viewBox="0 0 100 100" [attr.width]="command.width" [attr.height]="command.height" [attr.x]="command.x" [attr.y]="command.y"
preserveAspectRatio="none" [class.disabled]="command.disabled">
<svg:use [attr.xlink:href]="modifierIconNames.command" />
</svg>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,7 @@
.disabled {
fill: gray;
}
text {
font-size: 100px;
}

View File

@@ -0,0 +1,161 @@
import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { KeystrokeAction } from '../../../../config-serializer/config-items/key-action';
import { KeyModifiers } from '../../../../config-serializer/config-items/KeyModifiers';
import { MapperService } from '../../../../services/mapper.service';
class SvgAttributes {
width: number;
height: number;
x: number;
y: number;
disabled: boolean;
constructor() {
this.width = 0;
this.height = 0;
this.x = 0;
this.y = 0;
this.disabled = true;
}
}
enum Modifiers {
Shift, Control, Alt, Command
}
@Component({
selector: 'g[svg-keystroke-key]',
template: require('./svg-keystroke-key.component.html'),
styles: [require('./svg-keystroke-key.component.scss')]
})
export class SvgKeystrokeKeyComponent implements OnInit, OnChanges {
@Input() height: number;
@Input() width: number;
@Input() keystrokeAction: KeystrokeAction;
private viewBox: string;
private textContainer: SvgAttributes;
private modifierContainer: SvgAttributes;
private shift: SvgAttributes;
private control: SvgAttributes;
private option: SvgAttributes;
private command: SvgAttributes;
private labelSource: any;
private labelType: 'empty' | 'one-line' | 'two-line' | 'icon';
private modifierIconNames: {
shift?: string,
option?: string,
command?: string
};
constructor(private mapper: MapperService) {
this.modifierIconNames = {};
this.textContainer = new SvgAttributes();
this.modifierContainer = new SvgAttributes();
this.shift = new SvgAttributes();
this.control = new SvgAttributes();
this.option = new SvgAttributes();
this.command = new SvgAttributes();
}
ngOnInit() {
this.viewBox = [0, 0, this.width, this.height].join(' ');
this.modifierIconNames.shift = this.mapper.getIcon('shift');
this.modifierIconNames.option = this.mapper.getIcon('option');
this.modifierIconNames.command = this.mapper.getIcon('command');
let bottomSideMode: boolean = this.width < this.height * 1.8;
const heightWidthRatio = this.height / this.width;
if (bottomSideMode) {
const maxIconWidth = this.width / 4;
const maxIconHeight = this.height;
const iconScalingFactor = 0.8;
let iconWidth = iconScalingFactor * heightWidthRatio * maxIconWidth;
let iconHeight = iconScalingFactor * maxIconHeight;
this.modifierContainer.width = this.width;
this.modifierContainer.height = this.height / 5;
this.modifierContainer.y = this.height - this.modifierContainer.height;
this.shift.width = iconWidth;
this.shift.height = iconHeight;
this.shift.x = (maxIconWidth - iconWidth) / 2;
this.shift.y = (maxIconHeight - iconHeight) / 2;
this.control.width = iconWidth;
this.control.height = iconHeight;
this.control.x = this.shift.x + maxIconWidth;
this.control.y = this.shift.y;
this.option.width = iconWidth;
this.option.height = iconHeight;
this.option.x = this.control.x + maxIconWidth;
this.option.y = this.shift.y;
this.command.width = iconWidth;
this.command.height = iconHeight;
this.command.x = this.option.x + maxIconWidth;
this.command.y = this.shift.y;
this.textContainer.y = -this.modifierContainer.height / 2;
} else {
this.modifierContainer.width = this.width / 4;
this.modifierContainer.height = this.height;
this.modifierContainer.x = this.width - this.modifierContainer.width;
const length = Math.min(this.modifierContainer.width / 2, this.modifierContainer.height / 2);
const iconScalingFactor = 0.8;
const iconWidth = iconScalingFactor * this.width * (length / this.modifierContainer.width);
const iconHeight = iconScalingFactor * this.height * (length / this.modifierContainer.height);
this.shift.width = iconWidth;
this.shift.height = iconHeight;
this.shift.x = this.width / 4 - iconWidth / 2;
this.shift.y = this.height / 4 - iconHeight / 2;
this.control.width = iconWidth;
this.control.height = iconHeight;
this.control.x = this.shift.x + this.width / 2;
this.control.y = this.shift.y;
this.option.width = iconWidth;
this.option.height = iconHeight;
this.option.x = this.shift.x;
this.option.y = this.shift.y + this.height / 2;
this.command.width = iconWidth;
this.command.height = iconHeight;
this.command.x = this.option.x + this.width / 2;
this.command.y = this.option.y;
this.textContainer.x = -this.modifierContainer.width / 2;
}
this.textContainer.width = this.width;
this.textContainer.height = this.height;
}
ngOnChanges() {
let newLabelSource: string[];
if (this.keystrokeAction.hasScancode()) {
let scancode: number = this.keystrokeAction.scancode;
newLabelSource = this.mapper.scanCodeToText(scancode);
if (newLabelSource) {
if (newLabelSource.length === 1) {
this.labelSource = newLabelSource[0];
this.labelType = 'one-line';
} else {
this.labelSource = newLabelSource;
this.labelType = 'two-line';
}
} else {
this.labelSource = this.mapper.scanCodeToSvgImagePath(scancode);
this.labelType = 'icon';
}
} else {
this.labelType = 'empty';
}
this.shift.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftShift | KeyModifiers.rightShift);
this.control.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftCtrl | KeyModifiers.rightCtrl);
this.option.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftAlt | KeyModifiers.rightAlt);
this.command.disabled = !this.keystrokeAction.isActive(KeyModifiers.leftGui | KeyModifiers.rightGui);
}
}

View File

@@ -0,0 +1 @@
export * from './svg-mouse-click-key';

View File

@@ -0,0 +1,16 @@
<svg:use [attr.xlink:href]="icon" width="20" height="20" x="10" y="25">
</svg:use>
<svg:text
[attr.x]="60"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="25">
<tspan dy="34"> Click </tspan>
</svg:text>
<svg:text
[attr.x]="50"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="25">
<tspan dy="70"> {{ button }} </tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 403 B

View File

@@ -0,0 +1,19 @@
import { Component, Input, OnInit } from '@angular/core';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'g[svg-mouse-click-key]',
template: require('./svg-mouse-click-key.html')
})
export class SvgMouseClickKeyComponent implements OnInit {
@Input() button: string;
private icon: string;
constructor(private mapper: MapperService) {
this.icon = this.mapper.getIcon('mouse');
}
ngOnInit() { }
}

View File

@@ -0,0 +1 @@
export * from './svg-mouse-key';

View File

@@ -0,0 +1,6 @@
<svg:g [ngSwitch]="type">
<svg:g *ngSwitchCase="'click'" svg-mouse-click-key [button]="param"></svg:g>
<svg:g *ngSwitchCase="'move'" svg-mouse-move-key [direction]="param"></svg:g>
<svg:g *ngSwitchCase="'scroll'" svg-mouse-scroll-key [direction]="param"></svg:g>
<svg:g *ngSwitchCase="'speed'" svg-mouse-speed-key [plus]="param"></svg:g>
</svg:g>

After

Width:  |  Height:  |  Size: 378 B

View File

@@ -0,0 +1,74 @@
import { Component, Input, OnChanges } from '@angular/core';
import { MouseAction, MouseActionParam } from '../../../../config-serializer/config-items/key-action';
@Component({
selector: 'g[svg-mouse-key]',
template: require('./svg-mouse-key.html')
})
export class SvgMouseKeyComponent implements OnChanges {
@Input() mouseAction: MouseAction;
private type: 'click' | 'scroll' | 'move' | 'speed';
private param: any;
constructor() { }
ngOnChanges() {
switch (this.mouseAction.mouseAction) {
case MouseActionParam.leftClick:
this.type = 'click';
this.param = 'Left';
break;
case MouseActionParam.rightClick:
this.type = 'click';
this.param = 'Right';
break;
case MouseActionParam.middleClick:
this.type = 'click';
this.param = 'Middle';
break;
case MouseActionParam.scrollDown:
this.type = 'scroll';
this.param = 'down';
break;
case MouseActionParam.scrollLeft:
this.type = 'scroll';
this.param = 'left';
break;
case MouseActionParam.scrollRight:
this.type = 'scroll';
this.param = 'right';
break;
case MouseActionParam.scrollUp:
this.type = 'scroll';
this.param = 'up';
break;
case MouseActionParam.moveDown:
this.type = 'move';
this.param = 'down';
break;
case MouseActionParam.moveLeft:
this.type = 'move';
this.param = 'left';
break;
case MouseActionParam.moveRight:
this.type = 'move';
this.param = 'right';
break;
case MouseActionParam.moveUp:
this.type = 'move';
this.param = 'up';
break;
case MouseActionParam.accelerate:
this.type = 'speed';
this.param = true;
break;
case MouseActionParam.decelerate:
this.type = 'speed';
this.param = false;
break;
default:
break;
}
}
}

View File

@@ -0,0 +1 @@
export * from './svg-mouse-move-key';

View File

@@ -0,0 +1,9 @@
<svg:use [attr.xlink:href]="mouseIcon" width="20" height="20" x="8" y="25"></svg:use>
<svg:text
[attr.x]="60"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="24">
<tspan dy="34"> Move </tspan>
</svg:text>
<svg:use [attr.xlink:href]="directionIcon" width="30" height="30" x="35" y="55"></svg:use>

After

Width:  |  Height:  |  Size: 332 B

View File

@@ -0,0 +1,21 @@
import { Component, Input, OnChanges } from '@angular/core';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'g[svg-mouse-move-key]',
template: require('./svg-mouse-move-key.html')
})
export class SvgMouseMoveKeyComponent implements OnChanges {
@Input() direction: string;
private mouseIcon: string;
private directionIcon: string;
constructor(private mapper: MapperService) { }
ngOnChanges() {
this.mouseIcon = this.mapper.getIcon('mouse');
this.directionIcon = this.mapper.getIcon(`${this.direction}-arrow`);
}
}

View File

@@ -0,0 +1 @@
export * from './svg-mouse-scroll-key';

View File

@@ -0,0 +1,9 @@
<svg:use [attr.xlink:href]="mouseIcon" width="20" height="20" x="8" y="25"></svg:use>
<svg:text
[attr.x]="60"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="24">
<tspan dy="34"> Scroll </tspan>
</svg:text>
<svg:use [attr.xlink:href]="directionIcon" width="30" height="30" x="35" y="55"></svg:use>

After

Width:  |  Height:  |  Size: 334 B

View File

@@ -0,0 +1,21 @@
import { Component, Input, OnChanges } from '@angular/core';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'g[svg-mouse-scroll-key]',
template: require('./svg-mouse-scroll-key.html')
})
export class SvgMouseScrollKeyComponent implements OnChanges {
@Input() direction: string;
private mouseIcon: string;
private directionIcon: string;
constructor(private mapper: MapperService) { }
ngOnChanges() {
this.mouseIcon = this.mapper.getIcon('mouse');
this.directionIcon = this.mapper.getIcon(`scroll-${this.direction}`);
}
}

View File

@@ -0,0 +1 @@
export * from './svg-mouse-speed-key';

View File

@@ -0,0 +1,16 @@
<svg:use [attr.xlink:href]="icon" width="20" height="20" x="4" y="25">
</svg:use>
<svg:text
[attr.x]="60"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="25">
<tspan dy="34"> Speed </tspan>
</svg:text>
<svg:text
[attr.x]="50"
[attr.y]="0"
[attr.text-anchor]="'middle'"
[attr.font-size]="30">
<tspan dy="70"> {{ sign }} </tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 400 B

View File

@@ -0,0 +1,22 @@
import { Component, Input, OnChanges } from '@angular/core';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'g[svg-mouse-speed-key]',
template: require('./svg-mouse-speed-key.html')
})
export class SvgMouseSpeedKeyComponent implements OnChanges {
@Input() plus: boolean;
private icon: string;
private sign: string;
constructor(private mapper: MapperService) {
this.icon = this.mapper.getIcon('mouse');
}
ngOnChanges() {
this.sign = this.plus ? '+' : '-';
}
}

View File

@@ -0,0 +1 @@
export * from './svg-one-line-text-key.component';

View File

@@ -0,0 +1,6 @@
<svg:text
[attr.x]="0"
[attr.y]="textY"
[attr.text-anchor]="'middle'">
<tspan [attr.x]="spanX" dy="0">{{ text }}</tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 154 B

View File

@@ -0,0 +1,21 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'g[svg-one-line-text-key]',
template: require('./svg-one-line-text-key.component.html')
})
export class SvgOneLineTextKeyComponent implements OnInit {
@Input() height: number;
@Input() width: number;
@Input() text: string;
private textY: number;
private spanX: number;
constructor() { }
ngOnInit() {
this.textY = this.height / 2;
this.spanX = this.width / 2;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-single-icon-key.component';

View File

@@ -0,0 +1,4 @@
<svg:use [attr.xlink:href]="icon"
[attr.width]="svgWidth" [attr.height]="svgHeight"
[attr.x]="svgWidth" [attr.y]="svgHeight">
</svg:use>

After

Width:  |  Height:  |  Size: 144 B

View File

@@ -0,0 +1,21 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'g[svg-single-icon-key]',
template: require('./svg-single-icon-key.component.html')
})
export class SvgSingleIconKeyComponent implements OnInit {
@Input() width: number;
@Input() height: number;
@Input() icon: string;
private svgHeight: number;
private svgWidth: number;
constructor() { }
ngOnInit() {
this.svgWidth = this.width / 3;
this.svgHeight = this.height / 3;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-switch-keymap-key.component';

View File

@@ -0,0 +1,12 @@
<svg:use [attr.xlink:href]="icon"
[attr.width]="useWidth"
[attr.height]="useHeight"
[attr.x]="useX"
[attr.y]="useY">
</svg:use>
<svg:text
[attr.x]="0"
[attr.y]="textY"
[attr.text-anchor]="'middle'">
<tspan [attr.x]="spanX">{{ abbreviation }}</tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 313 B

View File

@@ -0,0 +1,34 @@
import { Component, Input, OnInit } from '@angular/core';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'g[svg-switch-keymap-key]',
template: require('./svg-switch-keymap-key.component.html')
})
export class SvgSwitchKeymapKeyComponent implements OnInit {
@Input() width: number;
@Input() height: number;
@Input() abbreviation: string;
private icon: string;
private useWidth: number;
private useHeight: number;
private useX: number;
private useY: number;
private textY: number;
private spanX: number;
constructor(private mapperService: MapperService) { }
ngOnInit() {
this.icon = this.mapperService.getIcon('switch-keymap');
this.useWidth = this.width / 4;
this.useHeight = this.height / 4;
this.useX = this.width * 3 / 8;
this.useY = this.height / 5;
this.textY = this.height * 2 / 3;
this.spanX = this.width / 2;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-text-icon-key.component';

View File

@@ -0,0 +1,12 @@
<svg:text
[attr.x]="0"
[attr.y]="textY"
[attr.text-anchor]="textAnchor">
<tspan [attr.x]="spanX">{{ text }}</tspan>
</svg:text>
<svg:use [attr.xlink:href]="icon"
[attr.width]="useWidth"
[attr.height]="useHeight"
[attr.x]="useX"
[attr.y]="useY">
</svg:use>

After

Width:  |  Height:  |  Size: 309 B

View File

@@ -0,0 +1,32 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'g[svg-text-icon-key]',
template: require('./svg-text-icon-key.component.html')
})
export class SvgTextIconKeyComponent implements OnInit {
@Input() width: number;
@Input() height: number;
@Input() text: string;
@Input() icon: string;
private useWidth: number;
private useHeight: number;
private useX: number;
private useY: number;
private textY: number;
private textAnchor: string;
private spanX: number;
constructor() { }
ngOnInit() {
this.useWidth = this.width / 3;
this.useHeight = this.height / 3;
this.useX = (this.width > 2 * this.height) ? this.width * 0.6 : this.width / 3;
this.useY = (this.width > 2 * this.height) ? this.height / 3 : this.height / 2;
this.textY = (this.width > 2 * this.height) ? this.height / 2 : this.height / 3;
this.textAnchor = (this.width > 2 * this.height) ? 'end' : 'middle';
this.spanX = (this.width > 2 * this.height) ? 0.6 * this.width : this.width / 2;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-two-line-text-key.component';

View File

@@ -0,0 +1,11 @@
<svg:text
[attr.x]="0"
[attr.y]="textY"
[attr.text-anchor]="'middle'">
<tspan
*ngFor="let text of texts; let index = index"
[attr.x]="spanX"
[attr.y]="spanYs[index]"
dy="0"
>{{ text }}</tspan>
</svg:text>

After

Width:  |  Height:  |  Size: 306 B

View File

@@ -0,0 +1,27 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'g[svg-two-line-text-key]',
template: require('./svg-two-line-text-key.component.html')
})
export class SvgTwoLineTextKeyComponent implements OnInit {
@Input() height: number;
@Input() width: number;
@Input() texts: string[];
private textY: number;
private spanX: number;
private spanYs: number[];
constructor() {
this.spanYs = [];
}
ngOnInit() {
this.textY = this.height / 2;
this.spanX = this.width / 2;
for (let i = 0; i < this.texts.length; ++i) {
this.spanYs.push((0.75 - i * 0.5) * this.height);
}
}
}

View File

@@ -0,0 +1,2 @@
export * from './svg-module.component';
export * from './svg-module.model';

View File

@@ -0,0 +1,14 @@
<svg:path *ngFor="let path of coverages" [attr.d]="path.$.d" />
<svg:g svg-keyboard-key *ngFor="let key of keyboardKeys; let i = index"
[id]="key.id"
[rx]="key.rx" [ry]="key.ry"
[width]="key.width" [height]="key.height"
[attr.transform]="'translate(' + key.x + ' ' + key.y + ')'"
[keyAction]="keyActions[i]"
[keybindAnimationEnabled]="keybindAnimationEnabled"
[capturingEnabled]="capturingEnabled"
(keyClick)="onKeyClick(i, $event)"
(capture)="onCapture(i, $event)"
(mouseenter)="onKeyHover(i, $event, true)"
(mouseleave)="onKeyHover(i, $event, false)"
/>

After

Width:  |  Height:  |  Size: 643 B

View File

@@ -0,0 +1,3 @@
:host {
position: relative;
}

View File

@@ -0,0 +1,47 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { KeyAction } from '../../../config-serializer/config-items/key-action';
import { SvgKeyboardKey } from '../keys';
@Component({
selector: 'g[svg-module]',
template: require('./svg-module.component.html'),
styles: [require('./svg-module.component.scss')]
})
export class SvgModuleComponent {
@Input() coverages: any[];
@Input() keyboardKeys: SvgKeyboardKey[];
@Input() keyActions: KeyAction[];
@Input() keybindAnimationEnabled: boolean;
@Input() capturingEnabled: boolean;
@Output() keyClick = new EventEmitter();
@Output() keyHover = new EventEmitter();
@Output() capture = new EventEmitter();
constructor() {
this.keyboardKeys = [];
}
onKeyClick(index: number, keyTarget: HTMLElement): void {
this.keyClick.emit({
index,
keyTarget
});
}
onKeyHover(index: number, event: MouseEvent, over: boolean): void {
this.keyHover.emit({
index,
event,
over
});
}
onCapture(index: number, captured: {code: number, left: boolean[], right: boolean[]}) {
this.capture.emit({
index,
captured
});
}
}

View File

@@ -0,0 +1,17 @@
import { SvgKeyboardKey } from '../keys';
export class SvgModule {
private coverages: any[];
private keyboardKeys: SvgKeyboardKey[];
private attributes: any;
constructor(obj: { rect: any[], path: any[], $: Object }) {
this.keyboardKeys = obj.rect.map(rect => rect.$).map(rect => {
rect.height = +rect.height;
rect.width = +rect.width;
return rect;
});
this.coverages = obj.path;
this.attributes = obj.$;
}
}

View File

@@ -0,0 +1 @@
export * from './svg-keyboard-wrap.component';

View File

@@ -0,0 +1,25 @@
<template ngIf="layers">
<layers [class.disabled]="popoverShown" (select)="selectLayer($event.index)" [current]="currentLayer"></layers>
<keyboard-slider [layers]="layers"
[currentLayer]="currentLayer"
[keybindAnimationEnabled]="keybindAnimationEnabled"
[capturingEnabled]="popoverEnabled"
(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)"
></keyboard-slider>
<popover tabindex="0" [visible]="popoverShown" [keyPosition]="keyPosition" [wrapPosition]="wrapPosition" [defaultKeyAction]="popoverInitKeyAction"
[currentKeymap]="keymap" [currentLayer]="currentLayer" (cancel)="hidePopover()" (remap)="onRemap($event)"></popover>
<div class="tooltip bottom"
[class.in]="tooltipData.show"
[style.top.px]="tooltipData.posTop"
[style.left.px]="tooltipData.posLeft"
>
<div class="tooltip-arrow"></div>
<div class="tooltip-inner">
<p *ngFor="let item of tooltipData.content | async">
{{ item.name }}: {{ item.value }}
</p>
</div>
</div>
</template>

View File

@@ -0,0 +1,50 @@
:host {
width: 100%;
display: block;
&.space {
margin-bottom: 405px;
}
}
keyboard-slider {
display: block;
position: relative;
overflow: hidden;
/* TODO create dynamic */
height: 500px;
margin-top: 30px;
}
.tooltip {
position: fixed;
transform: translate(-50%, -6px);
display: none;
&-inner {
background: #fff;
color: #000;
box-shadow: 0 1px 5px #000;
text-align: left;
p {
margin-bottom: 2px;
&:last-of-type {
margin-bottom: 0;
}
}
}
&.bottom {
.tooltip-arrow {
border-bottom-color: #fff;
top: 1px;
}
}
&.in {
display: block;
opacity: 1;
}
}

View File

@@ -0,0 +1,343 @@
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Renderer,
HostBinding,
HostListener,
Input,
OnChanges,
OnInit,
ViewChild,
SimpleChanges
} from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import { Store } from '@ngrx/store';
import { MapperService } from '../../../services/mapper.service';
import {
KeyAction,
KeystrokeAction,
LayerName,
MouseAction,
MouseActionParam,
PlayMacroAction,
SwitchKeymapAction,
SwitchLayerAction
} from '../../../config-serializer/config-items/key-action';
import { Keymap } from '../../../config-serializer/config-items/Keymap';
import { Layer } from '../../../config-serializer/config-items/Layer';
import { LongPressAction } from '../../../config-serializer/config-items/LongPressAction';
import { camelCaseToSentence, capitalizeFirstLetter } from '../../../util';
import { AppState } from '../../../store';
import { KeymapActions } from '../../../store/actions';
import { PopoverComponent } from '../../popover';
interface NameValuePair {
name: string;
value: string;
}
@Component({
selector: 'svg-keyboard-wrap',
template: require('./svg-keyboard-wrap.component.html'),
styles: [require('./svg-keyboard-wrap.component.scss')],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
@Input() keymap: Keymap;
@Input() popoverEnabled: boolean = true;
@Input() tooltipEnabled: boolean = false;
@ViewChild(PopoverComponent, { read: ElementRef }) popover: ElementRef;
private popoverShown: boolean;
private keyEditConfig: { moduleId: number, keyId: number };
private popoverInitKeyAction: KeyAction;
private keybindAnimationEnabled: boolean;
private currentLayer: number = 0;
private tooltipData: {
posTop: number,
posLeft: number,
content: Observable<NameValuePair[]>,
show: boolean
};
private layers: Layer[];
private keyPosition: ClientRect;
private wrapPosition: ClientRect;
private wrapHost: HTMLElement;
private keyElement: HTMLElement;
@HostBinding('class.space') get space() {
return this.popoverEnabled;
}
@HostListener('window:resize')
onResize() {
if (this.wrapHost) {
this.wrapPosition = this.wrapHost.getBoundingClientRect();
}
if (this.keyElement) {
this.keyPosition = this.keyElement.getBoundingClientRect();
}
}
constructor(
private store: Store<AppState>,
private mapper: MapperService,
private element: ElementRef,
private renderer: Renderer
) {
this.keyEditConfig = {
moduleId: undefined,
keyId: undefined
};
this.tooltipData = {
posTop: 0,
posLeft: 0,
content: Observable.of([]),
show: false
};
}
ngOnInit() {
this.wrapHost = this.element.nativeElement;
this.wrapPosition = this.wrapHost.getBoundingClientRect();
}
ngOnChanges(changes: SimpleChanges) {
const keymapChanges = changes['keymap'];
if (keymapChanges) {
this.popoverShown = false;
this.layers = this.keymap.layers;
if (keymapChanges.previousValue.abbreviation !== keymapChanges.currentValue.abbreviation) {
this.currentLayer = 0;
this.keybindAnimationEnabled = keymapChanges.isFirstChange();
} else {
this.keybindAnimationEnabled = true;
}
}
}
onKeyClick(moduleId: number, keyId: number, keyTarget: HTMLElement): void {
if (!this.popoverShown && this.popoverEnabled) {
this.keyEditConfig = {
moduleId,
keyId
};
const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[moduleId].keyActions[keyId];
this.keyElement = keyTarget;
this.showPopover(keyActionToEdit);
}
}
onKeyHover(moduleId: number, event: MouseEvent, over: boolean, keyId: number): void {
if (this.tooltipEnabled) {
const keyActionToEdit: KeyAction = this.layers[this.currentLayer].modules[moduleId].keyActions[keyId];
if (over) {
this.showTooltip(keyActionToEdit, event);
} else {
this.hideTooltip();
}
}
}
onCapture(moduleId: number, keyId: number, captured: { code: number, left: boolean[], right: boolean[] }): void {
let keystrokeAction: KeystrokeAction = new KeystrokeAction();
const modifiers = captured.left.concat(captured.right).map(x => x ? 1 : 0);
keystrokeAction.scancode = captured.code;
keystrokeAction.modifierMask = 0;
for (let i = 0; i < modifiers.length; ++i) {
keystrokeAction.modifierMask |= modifiers[i] << this.mapper.modifierMapper(i);
}
this.store.dispatch(
KeymapActions.saveKey(
this.keymap,
this.currentLayer,
moduleId,
keyId,
keystrokeAction)
);
}
onRemap(keyAction: KeyAction): void {
this.store.dispatch(
KeymapActions.saveKey(
this.keymap,
this.currentLayer,
this.keyEditConfig.moduleId,
this.keyEditConfig.keyId,
keyAction)
);
this.hidePopover();
}
showPopover(keyAction: KeyAction): void {
this.keyPosition = this.keyElement.getBoundingClientRect();
this.popoverInitKeyAction = keyAction;
this.popoverShown = true;
this.renderer.invokeElementMethod(this.popover.nativeElement, 'focus');
}
showTooltip(keyAction: KeyAction, event: MouseEvent): void {
if (keyAction === undefined) {
return;
}
const el: Element = event.target as Element || event.srcElement;
const position: ClientRect = el.getBoundingClientRect();
let posLeft: number = this.tooltipData.posLeft;
let posTop: number = this.tooltipData.posTop;
if (el.tagName === 'g') {
posLeft = position.left + (position.width / 2);
posTop = position.top + position.height;
}
this.tooltipData = {
posLeft: posLeft,
posTop: posTop,
content: this.getKeyActionContent(keyAction),
show: true
};
}
hideTooltip() {
this.tooltipData.show = false;
}
hidePopover(): void {
this.popoverShown = false;
}
selectLayer(index: number): void {
this.currentLayer = index;
}
getSelectedLayer(): number {
return this.currentLayer;
}
private getKeyActionContent(keyAction: KeyAction): Observable<NameValuePair[]> {
if (keyAction instanceof KeystrokeAction) {
const keystrokeAction: KeystrokeAction = keyAction;
const content: NameValuePair[] = [];
content.push({
name: 'Action type',
value: 'Keystroke'
});
if (keystrokeAction.hasScancode()) {
let value: string = keystrokeAction.scancode.toString();
const scanCodeTexts: string = (this.mapper.scanCodeToText(keystrokeAction.scancode) || []).join(', ');
if (scanCodeTexts.length > 0) {
value += ' (' + scanCodeTexts + ')';
}
content.push({
name: 'Scancode',
value
});
}
if (keystrokeAction.hasActiveModifier()) {
content.push({
name: 'Modifiers',
value: keystrokeAction.getModifierList().join(', ')
});
}
if (keystrokeAction.hasLongPressAction()) {
content.push({
name: 'Long press',
value: LongPressAction[keystrokeAction.longPressAction]
});
}
return Observable.of(content);
} else if (keyAction instanceof MouseAction) {
const mouseAction: MouseAction = keyAction;
const content: NameValuePair[] =
[
{
name: 'Action type',
value: 'Mouse'
},
{
name: 'Action',
value: camelCaseToSentence(MouseActionParam[mouseAction.mouseAction])
}
];
return Observable.of(content);
} else if (keyAction instanceof PlayMacroAction) {
const playMacroAction: PlayMacroAction = keyAction;
return this.store
.select(appState => appState.macros)
.map(macroState => macroState.entities.find(macro => {
return macro.id === playMacroAction.macroId;
}).name)
.map(macroName => {
const content: NameValuePair[] = [
{
name: 'Action type',
value: 'Play macro'
},
{
name: 'Macro name',
value: macroName
}
];
return content;
});
} else if (keyAction instanceof SwitchKeymapAction) {
const switchKeymapAction: SwitchKeymapAction = keyAction;
return this.store
.select(appState => appState.keymaps.entities)
.map(keymaps => keymaps.find(keymap => keymap.abbreviation === switchKeymapAction.keymapAbbreviation).name)
.map(keymapName => {
const content: NameValuePair[] = [
{
name: 'Action type',
value: 'Switch keymap'
},
{
name: 'Keymap',
value: keymapName
}
];
return content;
});
} else if (keyAction instanceof SwitchLayerAction) {
const switchLayerAction: SwitchLayerAction = keyAction;
const content: NameValuePair[] =
[
{
name: 'Action type',
value: 'Switch layer'
},
{
name: 'Layer',
value: capitalizeFirstLetter(LayerName[switchLayerAction.layer])
},
{
name: 'Toogle',
value: switchLayerAction.isLayerToggleable ? 'On' : 'Off'
}
];
return Observable.of(content);
}
return Observable.of([]);
}
}