feat: make double tap to hold layer optional per key (#662)

* feat: make double tap to hold layer optional per key

* test: fix test serializer

* fix: remove "application start" text

* Add double-tap.svg

* Add closing dot at the end of the sentence.

* fead: add double-tap icon

* Bundle firmware version 8.3.0

* feat: 'layer-double-tap' feature flag

* feat: convert SwitchLayerMode to string enum
This commit is contained in:
Róbert Kiss
2018-06-07 22:11:41 +02:00
committed by László Monda
parent 81a83994ab
commit 4ae577f936
25 changed files with 1284 additions and 144 deletions

View File

@@ -5,6 +5,7 @@
<svg-keyboard-wrap [keymap]="keymap$ | async"
[halvesSplit]="keyboardSplit"
[keyboardLayout]="keyboardLayout$ | async"
[allowLayerDoubleTap]="allowLayerDoubleTap$ | async"
(descriptionChanged)="descriptionChanged($event)"></svg-keyboard-wrap>
</ng-template>

View File

@@ -1,4 +1,4 @@
import { Component, HostListener, ViewChild } from '@angular/core';
import { Component, HostListener } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { Keymap } from 'uhk-common';
@@ -14,9 +14,8 @@ import 'rxjs/add/operator/combineLatest';
import { saveAs } from 'file-saver';
import { AppState, getKeyboardLayout } from '../../../store';
import { allowLayerDoubleTap, AppState, getKeyboardLayout } from '../../../store';
import { getKeymap, getKeymaps, getUserConfiguration } from '../../../store/reducers/user-configuration';
import { SvgKeyboardWrapComponent } from '../../svg/wrap';
import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum';
import { KeymapActions } from '../../../store/actions';
import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription';
@@ -31,13 +30,12 @@ import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription
})
export class KeymapEditComponent {
@ViewChild(SvgKeyboardWrapComponent) wrap: SvgKeyboardWrapComponent;
keyboardSplit: boolean;
deletable$: Observable<boolean>;
keymap$: Observable<Keymap>;
keyboardLayout$: Observable<KeyboardLayout>;
allowLayerDoubleTap$: Observable<boolean>;
constructor(protected store: Store<AppState>,
route: ActivatedRoute) {
@@ -52,6 +50,7 @@ export class KeymapEditComponent {
.map((keymaps: Keymap[]) => keymaps.length > 1);
this.keyboardLayout$ = store.select(getKeyboardLayout);
this.allowLayerDoubleTap$ = store.select(allowLayerDoubleTap);
}
downloadKeymap() {

View File

@@ -55,6 +55,7 @@
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content"
[defaultKeyAction]="defaultKeyAction"
[currentLayer]="currentLayer"
[allowLayerDoubleTap]="allowLayerDoubleTap"
(validAction)="keyActionValid=$event"
></layer-tab>
<mouse-tab #tab *ngSwitchCase="tabName.Mouse" class="popover-content"

View File

@@ -27,7 +27,7 @@ import {
SwitchLayerAction
} from 'uhk-common';
import { Tab } from './tab/tab';
import { Tab } from './tab';
import { AppState } from '../../store';
import { getKeymaps } from '../../store/reducers/user-configuration';
@@ -82,6 +82,7 @@ export class PopoverComponent implements OnChanges {
@Input() keyPosition: any;
@Input() wrapPosition: any;
@Input() visible: boolean;
@Input() allowLayerDoubleTap: boolean;
@Output() cancel = new EventEmitter<any>();
@Output() remap = new EventEmitter<KeyAction>();

View File

@@ -1,20 +1,32 @@
<ng-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">
<ng-template [ngSwitchCase]="true">layer by tapping this key.</ng-template>
<ng-template ngSwitchDefault>layer by holding this key.</ng-template>
</span>
<div>
<div>
<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">
<ng-template [ngSwitchCase]="'toggle'">layer by tapping this key.</ng-template>
<ng-template ngSwitchDefault>layer by holding this key.</ng-template>
</span>
</div>
<div *ngIf="toggle === 'active' && allowLayerDoubleTap">
<div class="checkbox">
<label>
<input type="checkbox"
[(ngModel)]="lockLayerWhenDoubleTapping"> Lock layer when double tapping this key.
</label>
</div>
</div>
</div>
</ng-template>
<ng-template [ngIf]="isNotBase">
<span> Layer switching is only possible from the base layer. </span>
</ng-template>
</ng-template>

View File

@@ -1,8 +1,10 @@
import { Component, HostBinding, Input, OnChanges, SimpleChanges } from '@angular/core';
import { KeyAction, LayerName, SwitchLayerAction } from 'uhk-common';
import { KeyAction, LayerName, SwitchLayerAction, SwitchLayerMode } from 'uhk-common';
import { Tab } from '../tab';
export type toggleType = 'active' | 'toggle';
@Component({
selector: 'layer-tab',
templateUrl: './layer-tab.component.html',
@@ -11,16 +13,17 @@ import { Tab } from '../tab';
export class LayerTabComponent extends Tab implements OnChanges {
@Input() defaultKeyAction: KeyAction;
@Input() currentLayer: number;
@Input() allowLayerDoubleTap: boolean;
@HostBinding('class.no-base') isNotBase: boolean;
toggleData: { id: boolean, text: string }[] = [
toggleData: { id: toggleType, text: string }[] = [
{
id: false,
id: 'active',
text: 'Activate'
},
{
id: true,
id: 'toggle',
text: 'Toggle'
}
];
@@ -40,12 +43,13 @@ export class LayerTabComponent extends Tab implements OnChanges {
}
];
toggle: boolean;
toggle: toggleType;
layer: LayerName;
lockLayerWhenDoubleTapping: boolean;
constructor() {
super();
this.toggle = false;
this.toggle = 'active';
this.layer = LayerName.mod;
}
@@ -71,14 +75,39 @@ export class LayerTabComponent extends Tab implements OnChanges {
}
const switchLayerAction: SwitchLayerAction = <SwitchLayerAction>keyAction;
this.toggle = switchLayerAction.isLayerToggleable;
switch (switchLayerAction.switchLayerMode) {
case SwitchLayerMode.holdAndDoubleTapToggle: {
this.toggle = 'active';
this.lockLayerWhenDoubleTapping = true;
break;
}
case SwitchLayerMode.hold: {
this.toggle = 'active';
this.lockLayerWhenDoubleTapping = false;
break;
}
default: {
this.toggle = 'toggle';
this.lockLayerWhenDoubleTapping = false;
}
}
this.layer = switchLayerAction.layer;
return true;
}
toKeyAction(): SwitchLayerAction {
const keyAction = new SwitchLayerAction();
keyAction.isLayerToggleable = this.toggle;
if (this.toggle === 'toggle') {
keyAction.switchLayerMode = SwitchLayerMode.toggle;
} else if (!this.allowLayerDoubleTap || this.lockLayerWhenDoubleTapping) {
keyAction.switchLayerMode = SwitchLayerMode.holdAndDoubleTapToggle;
} else {
keyAction.switchLayerMode = SwitchLayerMode.hold;
}
keyAction.layer = this.layer;
if (!this.keyActionValid()) {
throw new Error('KeyAction is invalid!');
@@ -86,8 +115,8 @@ export class LayerTabComponent extends Tab implements OnChanges {
return keyAction;
}
toggleChanged(value: string) {
this.toggle = value === 'true';
toggleChanged(value: toggleType) {
this.toggle = value;
}
layerChanged(value: number) {

View File

@@ -17,13 +17,14 @@ import {
MouseAction,
PlayMacroAction,
SwitchKeymapAction,
SwitchLayerAction
SwitchLayerAction,
SwitchLayerMode
} from 'uhk-common';
import { CaptureService } from '../../../../services/capture.service';
import { MapperService } from '../../../../services/mapper.service';
import { AppState } from '../../../../store/index';
import { AppState } from '../../../../store';
import { getMacros } from '../../../../store/reducers/user-configuration';
enum LabelTypes {
@@ -288,12 +289,18 @@ export class SvgKeyboardKeyComponent implements OnInit, OnChanges, OnDestroy {
break;
}
if (keyAction.isLayerToggleable) {
if (keyAction.switchLayerMode === SwitchLayerMode.toggle) {
this.labelType = LabelTypes.TextIcon;
this.labelSource = {
text: newLabelSource,
icon: this.mapper.getIcon('toggle')
};
} else if (keyAction.switchLayerMode === SwitchLayerMode.holdAndDoubleTapToggle) {
this.labelType = LabelTypes.TextIcon;
this.labelSource = {
text: newLabelSource,
icon: this.mapper.getIcon('double-tap')
};
} else {
this.labelType = LabelTypes.OneLineText;
this.labelSource = newLabelSource;

View File

@@ -13,8 +13,18 @@
(capture)="onCapture($event.moduleId, $event.keyId, $event.captured)"
(descriptionChanged)="onDescriptionChanged($event)"
></keyboard-slider>
<popover tabindex="0" [visible]="popoverShown" [keyPosition]="keyPosition" [wrapPosition]="wrapPosition" [defaultKeyAction]="popoverInitKeyAction"
[currentKeymap]="keymap" [currentLayer]="currentLayer" (cancel)="hidePopover()" (remap)="onRemap($event)"></popover>
<popover tabindex="0"
[visible]="popoverShown"
[keyPosition]="keyPosition"
[wrapPosition]="wrapPosition"
[defaultKeyAction]="popoverInitKeyAction"
[currentKeymap]="keymap"
[currentLayer]="currentLayer"
[allowLayerDoubleTap]="allowLayerDoubleTap"
(cancel)="hidePopover()"
(remap)="onRemap($event)"></popover>
<div class="tooltip bottom"
[class.in]="tooltipData.show"
[style.top.px]="tooltipData.posTop"

View File

@@ -32,7 +32,8 @@ import {
PlayMacroAction,
SecondaryRoleAction,
SwitchKeymapAction,
SwitchLayerAction
SwitchLayerAction,
SwitchLayerMode
} from 'uhk-common';
import { MapperService } from '../../../services/mapper.service';
@@ -59,6 +60,8 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
@Input() tooltipEnabled: boolean = false;
@Input() halvesSplit: boolean;
@Input() keyboardLayout: KeyboardLayout.ANSI;
@Input() allowLayerDoubleTap: boolean;
@Output() descriptionChanged = new EventEmitter<ChangeKeymapDescription>();
@ViewChild(PopoverComponent, { read: ElementRef }) popover: ElementRef;
@@ -350,7 +353,7 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges {
},
{
name: 'Toogle',
value: switchLayerAction.isLayerToggleable ? 'On' : 'Off'
value: switchLayerAction.switchLayerMode === SwitchLayerMode.toggle ? 'On' : 'Off'
}
];
return Observable.of(content);