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,7 @@
export * from './tab';
export { KeymapTabComponent } from './keymap';
export { KeypressTabComponent } from './keypress';
export { LayerTabComponent } from './layer';
export { MacroTabComponent } from './macro';
export { MouseTabComponent } from './mouse';
export { NoneTabComponent } from './none';

View File

@@ -0,0 +1 @@
export * from './keymap-tab.component';

View File

@@ -0,0 +1,22 @@
<template [ngIf]="keymapOptions.length === 0">
<span> No keymaps are available to choose from. Create a keymap first! </span>
</template>
<template [ngIf]="keymapOptions.length > 0">
<div>
<b>Switch to keymap:</b>
<select2
[data]="keymapOptions"
[value]="selectedKeymap?.abbreviation || -1"
(valueChanged)="onChange($event)"
[width]="'100%'"
></select2>
</div>
<div>
<div class="empty" *ngIf="!selectedKeymap?.abbreviation">
<img src="./images/base-layer--blank.svg">
</div>
<svg-keyboard *ngIf="selectedKeymap?.abbreviation"
[moduleConfig]="selectedKeymap.layers[0].modules">
</svg-keyboard>
</div>
</template>

View File

@@ -0,0 +1,43 @@
:host {
display: flex;
flex-direction: column;
> span {
text-align: center;
}
> div {
display: flex;
margin-top: 2px;
b {
display: flex;
align-items: center;
margin-right: 7px;
}
select2 {
flex: 1;
}
}
> div:last-child {
margin-top: 10px;
img {
max-height: 100%;
max-width: 100%;
}
}
}
.empty {
display: flex;
img {
display: flex;
width: 100%;
height: 100%;
position: relative;
}
}

View File

@@ -0,0 +1,77 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { Select2OptionData } from 'ng2-select2/ng2-select2';
import { KeyAction, SwitchKeymapAction } from '../../../../config-serializer/config-items/key-action';
import { Keymap } from '../../../../config-serializer/config-items/Keymap';
import { Tab } from '../tab';
@Component({
selector: 'keymap-tab',
template: require('./keymap-tab.component.html'),
styles: [require('./keymap-tab.component.scss')],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class KeymapTabComponent extends Tab implements OnInit, OnChanges {
@Input() defaultKeyAction: KeyAction;
@Input() keymaps: Keymap[];
private keymapOptions: Array<Select2OptionData>;
private selectedKeymap: Keymap;
constructor() {
super();
this.keymapOptions = [];
}
ngOnInit() {
this.keymapOptions = this.keymaps
.map((keymap: Keymap): Select2OptionData => {
return {
id: keymap.abbreviation,
text: keymap.name
};
});
if (this.keymaps.length > 0) {
this.selectedKeymap = this.keymaps[0];
}
}
ngOnChanges() {
this.fromKeyAction(this.defaultKeyAction);
this.validAction.emit(true);
}
// TODO: change to the correct type when the wrapper has added it.
onChange(event: any) {
if (event.value === '-1') {
this.selectedKeymap = undefined;
} else {
this.selectedKeymap = this.keymaps.find((keymap: Keymap) => keymap.abbreviation === event.value);
}
}
keyActionValid(): boolean {
return !!this.selectedKeymap;
}
fromKeyAction(keyAction: KeyAction): boolean {
if (!(keyAction instanceof SwitchKeymapAction)) {
return false;
}
const switchKeymapAction: SwitchKeymapAction = <SwitchKeymapAction>keyAction;
this.selectedKeymap = this.keymaps
.find((keymap: Keymap) => keymap.abbreviation === switchKeymapAction.keymapAbbreviation);
}
toKeyAction(): SwitchKeymapAction {
if (!this.keyActionValid()) {
throw new Error('KeyAction is not valid. No selected keymap!');
}
const keymapAction = new SwitchKeymapAction();
keymapAction.keymapAbbreviation = this.selectedKeymap.abbreviation;
return keymapAction;
}
}

View File

@@ -0,0 +1 @@
export * from './keypress-tab.component';

View File

@@ -0,0 +1,50 @@
<div class="scancode-options">
<b class="setting-label">Scancode:</b>
<select2
[data]="scanCodeGroups"
[value]="scanCode.toString()"
(valueChanged)="onScancodeChange($event)"
[width]="200"
[options]="options"
></select2>
<capture-keystroke-button (capture)="onKeysCapture($event)"></capture-keystroke-button>
</div>
<div class="modifier-options">
<b class="setting-label">Modifiers:</b>
<div class="btn-toolbar modifiers">
<div class="btn-group btn-group-sm modifiers__left">
<button type="button" class="btn btn-default"
*ngFor="let modifier of leftModifiers; let index = index"
[class.btn-primary]="leftModifierSelects[index]"
(click)="toggleModifier(false, index)"
>
{{modifier}}
</button>
</div>
<div class="btn-group btn-group-sm modifiers__right">
<button type="button" class="btn btn-default"
*ngFor="let modifier of rightModifiers; let index = index"
[class.btn-primary]="rightModifierSelects[index]"
(click)="toggleModifier(true, index)"
>
{{modifier}}
</button>
</div>
</div>
</div>
<div class="long-press-container" *ngIf="longPressEnabled">
<b class="setting-label">Long press action:</b>
<select2 #longPressSelect
[data]="longPressGroups"
[value]="selectedLongPressIndex.toString()"
(valueChanged)="onLongpressChange($event)"
[width]="140"
></select2>
<icon name="question-circle" title="This action happens when the key is being held along with another key."></icon>
</div>
<div class="disabled-state--text">
<i class="fa fa-info-circle"></i>
When a key is configured as layer switcher key, you can't assign other functions to it.
To assign a scancode to the key, set the <em>Layer action</em> to <em>None</em>.
</div>

View File

@@ -0,0 +1,78 @@
:host {
display: flex;
flex-direction: column;
position: relative;
.scancode-options {
margin-bottom: 10px;
margin-top: 2px;
> b {
position: relative;
top: 2px;
}
}
.modifier-options {
> b {
position: relative;
top: -9px;
margin-right: 4px;
}
.btn-toolbar {
display: inline-block;
}
}
.long-press-container {
display: flex;
margin-top: 3rem;
> b {
margin-right: 0.6em;
align-items: center;
display: flex;
}
.secondary-role {
width: 135px;
}
icon {
margin-left: 0.6em;
}
}
.setting-label {
&.disabled {
color: #999;
}
}
.disabled-state--text {
display: none;
position: absolute;
top: 50%;
margin-top: -4rem;
color: #31708f;
padding-right: 40px;
.fa {
font-size: 2.6rem;
float: left;
padding: 1rem 1.5rem 2rem;
}
}
&.disabled {
.scancode-options,
.modifier-options,
.long-press-container {
visibility: hidden;
}
.disabled-state--text {
display: block;
}
}
}

View File

@@ -0,0 +1,166 @@
import { Component, Input, EventEmitter, OnChanges, Output } from '@angular/core';
import { Select2OptionData, Select2TemplateFunction } from 'ng2-select2';
import { KeyAction, KeystrokeAction } from '../../../../config-serializer/config-items/key-action';
import { Tab } from '../tab';
import { MapperService } from '../../../../services/mapper.service';
@Component({
selector: 'keypress-tab',
template: require('./keypress-tab.component.html'),
styles: [require('./keypress-tab.component.scss')]
})
export class KeypressTabComponent extends Tab implements OnChanges {
@Input() defaultKeyAction: KeyAction;
@Input() longPressEnabled: boolean;
private leftModifiers: string[];
private rightModifiers: string[];
private leftModifierSelects: boolean[];
private rightModifierSelects: boolean[];
private scanCodeGroups: Array<Select2OptionData>;
private longPressGroups: Array<Select2OptionData>;
private options: Select2Options;
private scanCode: number;
private selectedLongPressIndex: number;
constructor(private mapper: MapperService) {
super();
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.scanCode = 0;
this.selectedLongPressIndex = -1;
this.options = {
templateResult: this.scanCodeTemplateResult,
matcher: (term: string, text: string, data: Select2OptionData) => {
let found = text.toUpperCase().indexOf(term.toUpperCase()) > -1;
if (!found && data.additional && data.additional.explanation) {
found = data.additional.explanation.toUpperCase().indexOf(term.toUpperCase()) > -1;
}
return found;
}
};
}
ngOnChanges() {
this.fromKeyAction(this.defaultKeyAction);
this.validAction.emit(this.keyActionValid());
}
keyActionValid(keystrokeAction?: KeystrokeAction): boolean {
if (!keystrokeAction) {
keystrokeAction = this.toKeyAction();
}
return (keystrokeAction) ? (keystrokeAction.scancode > 0 || keystrokeAction.modifierMask > 0) : false;
}
onKeysCapture(event: {code: number, left: boolean[], right: boolean[]}) {
if (event.code) {
this.scanCode = event.code;
} else {
this.scanCode = 0;
}
this.leftModifierSelects = event.left;
this.rightModifierSelects = event.right;
this.validAction.emit(this.keyActionValid());
}
fromKeyAction(keyAction: KeyAction): boolean {
if (!(keyAction instanceof KeystrokeAction)) {
return false;
}
let keystrokeAction: 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.mapper.modifierMapper(i)] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
}
for (let i = leftModifiersLength; i < leftModifiersLength + this.rightModifierSelects.length; ++i) {
let index: number = this.mapper.modifierMapper(i) - leftModifiersLength;
this.rightModifierSelects[index] = ((keystrokeAction.modifierMask >> i) & 1) === 1;
}
// Restore longPressAction
if (keystrokeAction.longPressAction !== undefined) {
this.selectedLongPressIndex = this.mapper.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.mapper.modifierMapper(i);
}
keystrokeAction.longPressAction = this.selectedLongPressIndex === -1
? undefined
: this.mapper.modifierMapper(this.selectedLongPressIndex);
if (this.keyActionValid(keystrokeAction)) {
return keystrokeAction;
}
}
scanCodeTemplateResult: Select2TemplateFunction = (state: Select2OptionData): JQuery | string => {
if (!state.id) {
return state.text;
}
if (state.additional && state.additional.explanation) {
return jQuery(
'<span class="select2-item">'
+ '<span>' + state.text + '</span>'
+ '<span class="scancode--searchterm"> '
+ state.additional.explanation
+ '</span>' +
'</span>'
);
} else {
return jQuery('<span class="select2-item">' + state.text + '</span>');
}
}
toggleModifier(right: boolean, index: number) {
let modifierSelects: boolean[] = right ? this.rightModifierSelects : this.leftModifierSelects;
modifierSelects[index] = !modifierSelects[index];
this.validAction.emit(this.keyActionValid());
}
onLongpressChange(event: {value: string}) {
this.selectedLongPressIndex = +event.value;
}
onScancodeChange(event: {value: string}) {
this.scanCode = +event.value;
this.validAction.emit(this.keyActionValid());
}
}

View File

@@ -0,0 +1,60 @@
[
{
"id": "-1",
"text": "None"
},
{
"text": "Modifiers",
"children": [
{
"id": "0",
"text": "LShift"
},
{
"id": "1",
"text": "LCtrl"
},
{
"id": "2",
"text": "LSuper"
},
{
"id": "3",
"text": "LAlt"
},
{
"id": "4",
"text": "RShift"
},
{
"id": "5",
"text": "RCtrl"
},
{
"id": "6",
"text": "RSuper"
},
{
"id": "7",
"text": "RAlt"
}
]
},
{
"text": "Layer switcher",
"children": [
{
"id": "8",
"text": "Mod"
},
{
"id": "9",
"text": "Mouse"
},
{
"id": "10",
"text": "Fn"
}
]
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
export * from './layer-tab.component';

View File

@@ -0,0 +1,20 @@
<template [ngIf]="!isNotBase">
<select (change)="toggleChanged($event.target.value)">
<option *ngFor="let item of toggleData" [value]="item.id" [selected]="toggle === item.id">
{{ item.text }}
</option>
</select>
<span>the</span>
<select (change)="layerChanged($event.target.value)">
<option *ngFor="let item of layerData" [value]="item.id" [selected]="layer === item.id">
{{ item.text }}
</option>
</select>
<span [ngSwitch]="toggle">
<template ngSwitchCase="true">layer by pressing this key.</template>
<template ngSwitchDefault="false">layer by holding this key.</template>
</span>
</template>
<template [ngIf]="isNotBase">
<span> Layer switching is only possible from the base layer. </span>
</template>

View File

@@ -0,0 +1,22 @@
:host {
display: flex;
margin: 0 -5px;
&.no-base {
justify-content: center;
}
> span,
> select {
margin: 0 5px;
display: flex;
align-items: center;
}
}
select {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px;
padding: 4px 20px 4px 8px;
}

View File

@@ -0,0 +1,97 @@
import { Component, EventEmitter, HostBinding, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { KeyAction, LayerName, SwitchLayerAction } from '../../../../config-serializer/config-items/key-action';
import { Tab } from '../tab';
@Component({
selector: 'layer-tab',
template: require('./layer-tab.component.html'),
styles: [require('./layer-tab.component.scss')]
})
export class LayerTabComponent extends Tab implements OnChanges {
@Input() defaultKeyAction: KeyAction;
@Input() currentLayer: number;
@HostBinding('class.no-base') isNotBase: boolean;
toggleData: { id: boolean, text: string }[] = [
{
id: false,
text: 'Activate'
},
{
id: true,
text: 'Toggle'
}
];
layerData: { id: number, text: string }[] = [
{
id: 0,
text: 'Mod'
},
{
id: 1,
text: 'Fn'
},
{
id: 2,
text: 'Mouse'
}
];
private toggle: boolean;
private layer: LayerName;
constructor() {
super();
this.toggle = false;
this.layer = LayerName.mod;
}
ngOnChanges(changes: SimpleChanges) {
if (changes['defaultKeyAction']) {
this.fromKeyAction(this.defaultKeyAction);
}
if (changes['currentLayer']) {
this.isNotBase = this.currentLayer > 0;
}
this.validAction.emit(true);
}
keyActionValid(): boolean {
return !this.isNotBase;
}
fromKeyAction(keyAction: KeyAction): boolean {
if (!(keyAction instanceof SwitchLayerAction)) {
return false;
}
let switchLayerAction: SwitchLayerAction = <SwitchLayerAction>keyAction;
this.toggle = switchLayerAction.isLayerToggleable;
this.layer = switchLayerAction.layer;
return true;
}
toKeyAction(): SwitchLayerAction {
let keyAction = new SwitchLayerAction();
keyAction.isLayerToggleable = this.toggle;
keyAction.layer = this.layer;
if (!this.keyActionValid()) {
throw new Error('KeyAction is invalid!');
}
return keyAction;
}
toggleChanged(value: string) {
this.toggle = value === 'true';
}
layerChanged(value: number) {
this.layer = +value;
}
}

View File

@@ -0,0 +1 @@
export * from './macro-tab.component';

View File

@@ -0,0 +1,16 @@
<template [ngIf]="macroOptions.length === 0">
<span> No macros are available to choose from. Create a macro first! </span>
</template>
<template [ngIf]="macroOptions.length > 0">
<div class="macro-selector">
<b> Play macro: </b>
<select2 [data]="macroOptions" [value]="macroOptions[selectedMacroIndex].id" (valueChanged)="onChange($event)" [width]="'100%'"></select2>
</div>
<div class="macro-action-container">
<div class="list-group">
<macro-item *ngFor="let macroAction of macros[selectedMacroIndex].macroActions"
[macroAction]="macroAction" [editable]="false">
</macro-item>
</div>
</div>
</template>

View File

@@ -0,0 +1,40 @@
:host {
display: flex;
flex-direction: column;
> span {
text-align: center;
}
.macro-selector {
display: flex;
margin-top: 2px;
b {
display: flex;
align-items: center;
margin-right: 7px;
}
select2 {
flex: 1;
}
}
.macro-action-container {
display: flex;
flex-direction: column;
min-height: 200px;
max-height: 300px;
margin: 20px 0;
overflow-x: hidden;
overflow-y: auto;
border-radius: 4px;
border: 1px solid #ddd;
.list-group {
margin-bottom: 0;
border: 0;
}
}
}

View File

@@ -0,0 +1,83 @@
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs/Subscription';
import { Select2OptionData } from 'ng2-select2/ng2-select2';
import { KeyAction, PlayMacroAction } from '../../../../config-serializer/config-items/key-action';
import { Macro } from '../../../../config-serializer/config-items/Macro';
import { Tab } from '../tab';
import { AppState } from '../../../../store/index';
import { getMacroEntities } from '../../../../store/reducers/macro';
@Component({
selector: 'macro-tab',
template: require('./macro-tab.component.html'),
styles: [require('./macro-tab.component.scss')]
})
export class MacroTabComponent extends Tab implements OnInit, OnChanges, OnDestroy {
@Input() defaultKeyAction: KeyAction;
private macros: Macro[];
private macroOptions: Array<Select2OptionData>;
private selectedMacroIndex: number;
private subscription: Subscription;
constructor(private store: Store<AppState>) {
super();
this.subscription = store.let(getMacroEntities())
.subscribe((macros: Macro[]) => this.macros = macros);
this.macroOptions = [];
this.selectedMacroIndex = 0;
}
ngOnInit() {
this.macroOptions = this.macros.map(function (macro: Macro, index: number): Select2OptionData {
return {
id: index.toString(),
text: macro.name
};
});
}
ngOnChanges() {
this.fromKeyAction(this.defaultKeyAction);
this.validAction.emit(true);
}
// TODO: change to the correct type when the wrapper has added it.
onChange(event: any) {
this.selectedMacroIndex = +event.value;
}
keyActionValid(): boolean {
return this.selectedMacroIndex >= 0;
}
fromKeyAction(keyAction: KeyAction): boolean {
if (!(keyAction instanceof PlayMacroAction)) {
return false;
}
const playMacroAction: PlayMacroAction = <PlayMacroAction>keyAction;
this.selectedMacroIndex = this.macros.findIndex(macro => playMacroAction.macroId === macro.id);
return true;
}
toKeyAction(): PlayMacroAction {
if (!this.keyActionValid()) {
throw new Error('KeyAction is not valid. No selected macro!');
}
const keymapAction = new PlayMacroAction();
keymapAction.macroId = this.macros[this.selectedMacroIndex].id;
return keymapAction;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}

View File

@@ -0,0 +1 @@
export * from './mouse-tab.component';

View File

@@ -0,0 +1,110 @@
<div class="mouse-action col-sm-4">
<ul class="nav nav-pills nav-stacked">
<li *ngFor="let page of pages; let i = index" [class.active]="selectedPageIndex === i" (click)="changePage(i)">
<a> {{ page }}</a>
</li>
</ul>
</div>
<div class="details col-sm-8" [ngSwitch]="selectedPageIndex">
<div *ngSwitchCase="0" class="mouse__config mouse__config--move text-center">
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.moveUp"
(click)="setMouseActionParam(MouseActionParam.moveUp)">
<i class="fa fa-arrow-up"></i>
</button>
</div>
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.moveLeft"
(click)="setMouseActionParam(MouseActionParam.moveLeft)">
<i class="fa fa-arrow-left"></i>
</button>
<button type="button" class="btn btn-default btn-lg btn-placeholder">
<i class="fa fa-square"></i>
</button>
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.moveRight"
(click)="setMouseActionParam(MouseActionParam.moveRight)">
<i class="fa fa-arrow-right"></i>
</button>
</div>
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.moveDown"
(click)="setMouseActionParam(MouseActionParam.moveDown)">
<i class="fa fa-arrow-down"></i>
</button>
</div>
</div>
<div *ngSwitchCase="1" class="mouse__config mouse__config--scroll text-center">
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.scrollUp"
(click)="setMouseActionParam(MouseActionParam.scrollUp)">
<i class="fa fa-angle-double-up"></i>
</button>
</div>
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.scrollLeft"
(click)="setMouseActionParam(MouseActionParam.scrollLeft)">
<i class="fa fa-angle-double-left"></i>
</button>
<button type="button" class="btn btn-default btn-lg btn-placeholder">
<i class="fa fa-square"></i>
</button>
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.scrollRight"
(click)="setMouseActionParam(MouseActionParam.scrollRight)">
<i class="fa fa-angle-double-right"></i>
</button>
</div>
<div class="row">
<button type="button" class="btn btn-default btn-lg"
[class.btn-primary]="mouseActionParam === MouseActionParam.scrollDown"
(click)="setMouseActionParam(MouseActionParam.scrollDown)">
<i class="fa fa-angle-double-down"></i>
</button>
</div>
</div>
<div *ngSwitchCase="2" class="mouse__config mouse__config--click">
<div class="btn-group col-xs-12" role="group">
<button type="button" class="btn btn-default col-xs-4"
[class.btn-primary]="mouseActionParam === MouseActionParam.leftClick"
(click)="setMouseActionParam(MouseActionParam.leftClick)">Left</button>
<button type="button" class="btn btn-default col-xs-4"
[class.btn-primary]="mouseActionParam === MouseActionParam.middleClick"
(click)="setMouseActionParam(MouseActionParam.middleClick)">Middle</button>
<button type="button" class="btn btn-default col-xs-4"
[class.btn-primary]="mouseActionParam === MouseActionParam.rightClick"
(click)="setMouseActionParam(MouseActionParam.rightClick)">Right</button>
</div>
</div>
<div *ngSwitchCase="3" class="mouse__config mouse__config--speed text-center">
<div class="help-text--mouse-speed text-left">
<p>Press this key along with mouse movement/scrolling to accelerate/decelerate the speed of the action.</p>
</div>
<div class="btn-group btn-group-lg" role="group">
<button class="btn btn-default"
[class.btn-primary]="mouseActionParam === MouseActionParam.decelerate"
(click)="setMouseActionParam(MouseActionParam.decelerate)"
>
-
<span>Decelerate</span>
</button>
<button class="btn btn-default"
[class.btn-primary]="mouseActionParam === MouseActionParam.accelerate"
(click)="setMouseActionParam(MouseActionParam.accelerate)"
>
+
<span>Accelerate</span>
</button>
</div>
<div class="help-text--mouse-speed last-help text-left">
<p>You can set the multiplier in the <a [routerLink]="['/settings']" title="Settings">settings</a>.</p>
</div>
</div>
<div *ngSwitchDefault>
</div>
</div>

View File

@@ -0,0 +1,85 @@
@import '../../../../global-styles';
:host {
display: flex;
&.popover-content {
padding: 10px;
display: flex;
align-items: center;
}
.mouse-action {
.nav {
border-right: 1px solid #ccc;
li {
a {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
&.selected {
font-style: italic;
}
}
&.active {
a {
&.selected {
font-style: normal;
}
&:after {
content: '';
display: block;
position: absolute;
width: 0;
height: 0;
top: 0;
right: -4rem;
border-color: transparent transparent transparent $icon-hover;
border-style: solid;
border-width: 2rem;
}
}
}
}
}
}
.help-text--mouse-speed {
margin-bottom: 2rem;
font-size: 0.9em;
color: #666;
p {
margin: 0;
}
}
.details {
.btn-placeholder {
visibility: hidden;
}
}
}
.mouse__config--speed {
.btn-default {
font-size: 25px;
line-height: 22px;
padding-top: 4px;
padding-bottom: 4px;
span {
font-size: 13px;
display: block;
text-align: center;
}
}
}
.help-text--mouse-speed.last-help {
margin-bottom: 0;
margin-top: 2rem;
}

View File

@@ -0,0 +1,100 @@
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
import { KeyAction, MouseAction, MouseActionParam } from '../../../../config-serializer/config-items/key-action';
import { Tab } from '../tab';
@Component({
selector: 'mouse-tab',
template: require('./mouse-tab.component.html'),
styles: [require('./mouse-tab.component.scss')]
})
export class MouseTabComponent extends Tab implements OnChanges {
@Input() defaultKeyAction: KeyAction;
private mouseActionParam: MouseActionParam;
private selectedPageIndex: number;
/* tslint:disable:variable-name: It is an enum type. So it can start with uppercase. */
/* tslint:disable:no-unused-variable: It is used in the template. */
private MouseActionParam = MouseActionParam;
/* tslint:enable:no-unused-variable tslint:enable:variable-name */
private pages: string[];
constructor() {
super();
this.selectedPageIndex = 0;
this.pages = ['Move', 'Scroll', 'Click', 'Speed'];
}
ngOnChanges() {
this.fromKeyAction(this.defaultKeyAction);
this.validAction.emit(this.keyActionValid());
}
keyActionValid(): boolean {
return this.mouseActionParam !== undefined;
}
fromKeyAction(keyAction: KeyAction): boolean {
if (!(keyAction instanceof MouseAction)) {
return false;
}
let mouseAction: MouseAction = <MouseAction>keyAction;
this.mouseActionParam = mouseAction.mouseAction;
if (mouseAction.mouseAction === MouseActionParam.moveUp) {
this.selectedPageIndex = 0;
}
switch (mouseAction.mouseAction) {
case MouseActionParam.moveDown:
case MouseActionParam.moveUp:
case MouseActionParam.moveLeft:
case MouseActionParam.moveRight:
this.selectedPageIndex = 0;
break;
case MouseActionParam.scrollDown:
case MouseActionParam.scrollUp:
case MouseActionParam.scrollLeft:
case MouseActionParam.scrollRight:
this.selectedPageIndex = 1;
break;
case MouseActionParam.leftClick:
case MouseActionParam.middleClick:
case MouseActionParam.rightClick:
this.selectedPageIndex = 2;
break;
case MouseActionParam.decelerate:
case MouseActionParam.accelerate:
this.selectedPageIndex = 3;
break;
default:
return false;
}
return true;
}
toKeyAction(): MouseAction {
let mouseAction: MouseAction = new MouseAction();
mouseAction.mouseAction = this.mouseActionParam;
return mouseAction;
}
changePage(index: number) {
if (index < -1 || index > 3) {
console.error(`Invalid index error: ${index}`);
return;
}
this.selectedPageIndex = index;
this.mouseActionParam = undefined;
this.validAction.emit(false);
}
setMouseActionParam(mouseActionParam: MouseActionParam) {
this.mouseActionParam = mouseActionParam;
this.validAction.emit(true);
}
}

View File

@@ -0,0 +1 @@
export * from './none-tab.component';

View File

@@ -0,0 +1 @@
This key is unassigned and has no functionality.

View File

@@ -0,0 +1,5 @@
:host {
display: flex;
justify-content: center;
padding: 2rem 0;
}

View File

@@ -0,0 +1,27 @@
import { Component, EventEmitter, OnChanges, Output } from '@angular/core';
import { Tab } from '../tab';
@Component({
selector: 'none-tab',
template: require('./none-tab.component.html'),
styles: [require('./none-tab.component.scss')]
})
export class NoneTabComponent extends Tab implements OnChanges {
ngOnChanges(event: any) {
this.validAction.emit(true);
}
keyActionValid(): boolean {
return true;
}
fromKeyAction(): boolean {
return false;
}
toKeyAction(): undefined {
return undefined;
}
}

View File

@@ -0,0 +1,11 @@
import { EventEmitter, Output } from '@angular/core';
import { KeyAction } from '../../../config-serializer/config-items/key-action';
export abstract class Tab {
@Output() validAction = new EventEmitter<boolean>();
abstract keyActionValid(): boolean;
abstract fromKeyAction(keyAction: KeyAction): boolean;
abstract toKeyAction(): KeyAction;
}