feat: allow Layer Switcher secondary roles only on base layer (#790)
This commit is contained in:
committed by
László Monda
parent
eb421e0681
commit
aa243ac7b0
@@ -1,9 +1,11 @@
|
|||||||
import { assertUInt8, assertUInt16 } from '../assert';
|
import { assertUInt16, assertUInt8 } from '../assert';
|
||||||
import { UhkBuffer } from '../uhk-buffer';
|
import { UhkBuffer } from '../uhk-buffer';
|
||||||
import { Keymap } from './keymap';
|
import { Keymap } from './keymap';
|
||||||
import { Macro } from './macro';
|
import { Macro } from './macro';
|
||||||
import { ModuleConfiguration } from './module-configuration';
|
import { ModuleConfiguration } from './module-configuration';
|
||||||
import { ConfigSerializer } from '../config-serializer';
|
import { ConfigSerializer } from '../config-serializer';
|
||||||
|
import { KeystrokeAction } from './key-action';
|
||||||
|
import { SecondaryRoleAction } from './secondary-role-action';
|
||||||
|
|
||||||
export class UserConfiguration {
|
export class UserConfiguration {
|
||||||
|
|
||||||
@@ -102,7 +104,9 @@ export class UserConfiguration {
|
|||||||
return macro;
|
return macro;
|
||||||
});
|
});
|
||||||
this.keymaps = jsonObject.keymaps.map((keymap: any) => new Keymap().fromJsonObject(keymap, this.macros));
|
this.keymaps = jsonObject.keymaps.map((keymap: any) => new Keymap().fromJsonObject(keymap, this.macros));
|
||||||
|
this.clean();
|
||||||
this.recalculateConfigurationLength();
|
this.recalculateConfigurationLength();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +142,8 @@ export class UserConfiguration {
|
|||||||
this.keymaps = buffer.readArray<Keymap>(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros));
|
this.keymaps = buffer.readArray<Keymap>(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros));
|
||||||
ConfigSerializer.resolveSwitchKeymapActions(this.keymaps);
|
ConfigSerializer.resolveSwitchKeymapActions(this.keymaps);
|
||||||
|
|
||||||
|
this.clean();
|
||||||
|
|
||||||
if (this.userConfigurationLength === 0) {
|
if (this.userConfigurationLength === 0) {
|
||||||
this.recalculateConfigurationLength();
|
this.recalculateConfigurationLength();
|
||||||
}
|
}
|
||||||
@@ -222,4 +228,30 @@ export class UserConfiguration {
|
|||||||
this.deviceName = 'My UHK';
|
this.deviceName = 'My UHK';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove not allowed settings/bugs
|
||||||
|
* 1. Layer Switcher secondary roles allowed only on base layers
|
||||||
|
*/
|
||||||
|
private clean(): void {
|
||||||
|
for (const keymap of this.keymaps) {
|
||||||
|
for (let layerId = 1; layerId < keymap.layers.length; layerId++) {
|
||||||
|
const layer = keymap.layers[layerId];
|
||||||
|
|
||||||
|
for (const module of layer.modules) {
|
||||||
|
for (let keyActionId = 0; keyActionId < module.keyActions.length; keyActionId++) {
|
||||||
|
const keyAction = module.keyActions[keyActionId];
|
||||||
|
if (!keyAction || !(keyAction instanceof KeystrokeAction)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyAction.secondaryRoleAction === SecondaryRoleAction.fn ||
|
||||||
|
keyAction.secondaryRoleAction === SecondaryRoleAction.mod ||
|
||||||
|
keyAction.secondaryRoleAction === SecondaryRoleAction.mouse) {
|
||||||
|
(keyAction as any)._secondaryRoleAction = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,11 +48,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div [ngSwitch]="activeTab">
|
<div [ngSwitch]="activeTab">
|
||||||
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content pr-10"
|
<keypress-tab #tab *ngSwitchCase="tabName.Keypress" class="popover-content pr-10"
|
||||||
[defaultKeyAction]="defaultKeyAction"
|
[defaultKeyAction]="shadowKeyAction"
|
||||||
[secondaryRoleEnabled]="true"
|
[secondaryRoleEnabled]="true"
|
||||||
[allowRemapOnAllKeymapWarning]="true"
|
[allowRemapOnAllKeymapWarning]="true"
|
||||||
[remapInfo]="remapInfo"
|
[remapInfo]="remapInfo"
|
||||||
|
[showLayerSwitcherInSecondaryRoles]="currentLayer === 0"
|
||||||
(validAction)="keyActionValid=$event"
|
(validAction)="keyActionValid=$event"
|
||||||
|
(keyActionChange)="keystrokeActionChange($event)"
|
||||||
></keypress-tab>
|
></keypress-tab>
|
||||||
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content"
|
<layer-tab #tab *ngSwitchCase="tabName.Layer" class="popover-content"
|
||||||
[defaultKeyAction]="defaultKeyAction"
|
[defaultKeyAction]="defaultKeyAction"
|
||||||
@@ -87,10 +89,11 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label [ngClass]="{ disabled: disableRemapOnAllLayer }">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="remapOnAllLayer"
|
name="remapOnAllLayer"
|
||||||
[(ngModel)]="remapInfo.remapOnAllLayer"
|
[(ngModel)]="remapInfo.remapOnAllLayer"
|
||||||
|
[disabled]="disableRemapOnAllLayer"
|
||||||
(ngModelChange)="remapInfoChange()"> Remap on all layers
|
(ngModelChange)="remapInfoChange()"> Remap on all layers
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -125,5 +125,10 @@
|
|||||||
|
|
||||||
label {
|
label {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #959595;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@@ -24,6 +25,7 @@ import {
|
|||||||
KeystrokeAction,
|
KeystrokeAction,
|
||||||
MouseAction,
|
MouseAction,
|
||||||
PlayMacroAction,
|
PlayMacroAction,
|
||||||
|
SecondaryRoleAction,
|
||||||
SwitchKeymapAction,
|
SwitchKeymapAction,
|
||||||
SwitchLayerAction
|
SwitchLayerAction
|
||||||
} from 'uhk-common';
|
} from 'uhk-common';
|
||||||
@@ -104,10 +106,13 @@ export class PopoverComponent implements OnChanges {
|
|||||||
topPosition: number = 0;
|
topPosition: number = 0;
|
||||||
leftPosition: number = 0;
|
leftPosition: number = 0;
|
||||||
animationState: string;
|
animationState: string;
|
||||||
|
shadowKeyAction: KeyAction;
|
||||||
|
disableRemapOnAllLayer = false;
|
||||||
|
|
||||||
private readonly currentKeymap$ = new BehaviorSubject<Keymap>(undefined);
|
private readonly currentKeymap$ = new BehaviorSubject<Keymap>(undefined);
|
||||||
|
|
||||||
constructor(store: Store<AppState>) {
|
constructor(private store: Store<AppState>,
|
||||||
|
private cdRef: ChangeDetectorRef) {
|
||||||
this.animationState = 'closed';
|
this.animationState = 'closed';
|
||||||
this.keymaps$ = store.let(getKeymaps())
|
this.keymaps$ = store.let(getKeymaps())
|
||||||
.combineLatest(this.currentKeymap$)
|
.combineLatest(this.currentKeymap$)
|
||||||
@@ -123,8 +128,10 @@ export class PopoverComponent implements OnChanges {
|
|||||||
|
|
||||||
if (change['defaultKeyAction']) {
|
if (change['defaultKeyAction']) {
|
||||||
let tab: TabName;
|
let tab: TabName;
|
||||||
|
this.disableRemapOnAllLayer = false;
|
||||||
|
|
||||||
if (this.defaultKeyAction instanceof KeystrokeAction) {
|
if (this.defaultKeyAction instanceof KeystrokeAction) {
|
||||||
|
this.keystrokeActionChange(this.defaultKeyAction);
|
||||||
tab = TabName.Keypress;
|
tab = TabName.Keypress;
|
||||||
} else if (this.defaultKeyAction instanceof SwitchLayerAction) {
|
} else if (this.defaultKeyAction instanceof SwitchLayerAction) {
|
||||||
tab = TabName.Layer;
|
tab = TabName.Layer;
|
||||||
@@ -188,6 +195,9 @@ export class PopoverComponent implements OnChanges {
|
|||||||
|
|
||||||
selectTab(tab: TabName): void {
|
selectTab(tab: TabName): void {
|
||||||
this.activeTab = tab;
|
this.activeTab = tab;
|
||||||
|
if (tab === TabName.Keypress) {
|
||||||
|
this.keystrokeActionChange(this.defaultKeyAction as KeystrokeAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onOverlay() {
|
onOverlay() {
|
||||||
@@ -198,6 +208,26 @@ export class PopoverComponent implements OnChanges {
|
|||||||
this.selectedTab.remapInfoChanged(this.remapInfo);
|
this.selectedTab.remapInfoChanged(this.remapInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keystrokeActionChange(keystrokeAction: KeystrokeAction): void {
|
||||||
|
this.shadowKeyAction = keystrokeAction;
|
||||||
|
const disableRemapOnAllLayer =
|
||||||
|
keystrokeAction &&
|
||||||
|
this.currentLayer === 0 &&
|
||||||
|
(keystrokeAction.secondaryRoleAction === SecondaryRoleAction.fn ||
|
||||||
|
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mod ||
|
||||||
|
keystrokeAction.secondaryRoleAction === SecondaryRoleAction.mouse);
|
||||||
|
|
||||||
|
if (this.disableRemapOnAllLayer !== disableRemapOnAllLayer) {
|
||||||
|
this.disableRemapOnAllLayer = disableRemapOnAllLayer;
|
||||||
|
|
||||||
|
if (disableRemapOnAllLayer) {
|
||||||
|
this.remapInfo.remapOnAllLayer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cdRef.markForCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private calculatePosition() {
|
private calculatePosition() {
|
||||||
const offsetLeft: number = this.wrapPosition.left + 265; // 265 is a width of the side menu with a margin
|
const offsetLeft: number = this.wrapPosition.left + 265; // 265 is a width of the side menu with a margin
|
||||||
const popover: HTMLElement = this.popoverHost.nativeElement;
|
const popover: HTMLElement = this.popoverHost.nativeElement;
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges } from '@angular/core';
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
Output,
|
||||||
|
SimpleChanges
|
||||||
|
} from '@angular/core';
|
||||||
import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } from 'uhk-common';
|
import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } from 'uhk-common';
|
||||||
|
|
||||||
import { Tab } from '../tab';
|
import { Tab } from '../tab';
|
||||||
@@ -8,6 +17,16 @@ import { KeyModifierModel } from '../../../../models/key-modifier-model';
|
|||||||
import { mapLeftRigthModifierToKeyActionModifier } from '../../../../util';
|
import { mapLeftRigthModifierToKeyActionModifier } from '../../../../util';
|
||||||
import { RemapInfo } from '../../../../models/remap-info';
|
import { RemapInfo } from '../../../../models/remap-info';
|
||||||
|
|
||||||
|
export const secondaryRoleFilter = (showLayerSwitchers: boolean) => {
|
||||||
|
return (data): boolean => {
|
||||||
|
if (showLayerSwitchers) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.text !== 'Layer switcher';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'keypress-tab',
|
selector: 'keypress-tab',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
@@ -19,12 +38,15 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
@Input() secondaryRoleEnabled: boolean;
|
@Input() secondaryRoleEnabled: boolean;
|
||||||
@Input() allowRemapOnAllKeymapWarning: boolean;
|
@Input() allowRemapOnAllKeymapWarning: boolean;
|
||||||
@Input() remapInfo: RemapInfo;
|
@Input() remapInfo: RemapInfo;
|
||||||
|
@Input() showLayerSwitcherInSecondaryRoles: boolean;
|
||||||
|
|
||||||
|
@Output() keyActionChange = new EventEmitter<KeystrokeAction>();
|
||||||
|
|
||||||
leftModifiers: KeyModifierModel[];
|
leftModifiers: KeyModifierModel[];
|
||||||
rightModifiers: KeyModifierModel[];
|
rightModifiers: KeyModifierModel[];
|
||||||
|
|
||||||
scanCodeGroups: Array<SelectOptionData>;
|
scanCodeGroups: Array<SelectOptionData>;
|
||||||
secondaryRoleGroups: Array<SelectOptionData>;
|
secondaryRoleGroups: Array<SelectOptionData> = [];
|
||||||
|
|
||||||
selectedScancodeOption: SelectOptionData;
|
selectedScancodeOption: SelectOptionData;
|
||||||
selectedSecondaryRoleIndex: number;
|
selectedSecondaryRoleIndex: number;
|
||||||
@@ -41,14 +63,16 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
text: 'None'
|
text: 'None'
|
||||||
}];
|
}];
|
||||||
this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES);
|
this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES);
|
||||||
this.secondaryRoleGroups = SECONDARY_ROLES;
|
|
||||||
this.selectedScancodeOption = this.scanCodeGroups[0];
|
this.selectedScancodeOption = this.scanCodeGroups[0];
|
||||||
this.selectedSecondaryRoleIndex = -1;
|
this.selectedSecondaryRoleIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes.showLayerSwitcherInSecondaryRoles) {
|
||||||
|
this.fillSecondaryRoles();
|
||||||
|
}
|
||||||
this.fromKeyAction(this.defaultKeyAction);
|
this.fromKeyAction(this.defaultKeyAction);
|
||||||
this.keyActionChanged();
|
this.keyActionChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyActionValid(keystrokeAction?: KeystrokeAction): boolean {
|
keyActionValid(keystrokeAction?: KeystrokeAction): boolean {
|
||||||
@@ -124,6 +148,7 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
|
|
||||||
onSecondaryRoleChange(id: string) {
|
onSecondaryRoleChange(id: string) {
|
||||||
this.selectedSecondaryRoleIndex = +id;
|
this.selectedSecondaryRoleIndex = +id;
|
||||||
|
this.keyActionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
onScancodeChange(id: string) {
|
onScancodeChange(id: string) {
|
||||||
@@ -200,10 +225,14 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
return [scanCode, type];
|
return [scanCode, type];
|
||||||
}
|
}
|
||||||
|
|
||||||
private keyActionChanged(): void {
|
private keyActionChanged(dispatch = true): void {
|
||||||
const keystrokeAction = this.toKeyAction();
|
const keystrokeAction = this.toKeyAction();
|
||||||
this.validAction.emit(this.keyActionValid(keystrokeAction));
|
this.validAction.emit(this.keyActionValid(keystrokeAction));
|
||||||
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
|
this.calculateRemapOnAllLayerWarningVisibility(keystrokeAction);
|
||||||
|
|
||||||
|
if (dispatch) {
|
||||||
|
this.keyActionChange.emit(keystrokeAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateRemapOnAllLayerWarningVisibility(keystrokeAction: KeystrokeAction): void {
|
private calculateRemapOnAllLayerWarningVisibility(keystrokeAction: KeystrokeAction): void {
|
||||||
@@ -214,4 +243,9 @@ export class KeypressTabComponent extends Tab implements OnChanges {
|
|||||||
!keystrokeAction.hasScancode() &&
|
!keystrokeAction.hasScancode() &&
|
||||||
keystrokeAction.hasOnlyOneActiveModifier();
|
keystrokeAction.hasOnlyOneActiveModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fillSecondaryRoles(): void {
|
||||||
|
this.secondaryRoleGroups = SECONDARY_ROLES
|
||||||
|
.filter(secondaryRoleFilter(this.showLayerSwitcherInSecondaryRoles));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user