From f34cb2df564f08610097ed481941004653aeaf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Kiss?= Date: Sun, 10 Jun 2018 21:50:49 +0200 Subject: [PATCH] feat: remap key on all keymaps / layers (#668) * add: popover checkboxs * feat: add KeyActionRemap * fix: template driven form checkbox name * fix: delete key action only if it SwitchLayerAction * feat: use remap on all keymaps/layers checkbox values in SAVE_KEY action * feat: set default value to the remapOnAllKeymap and remapOnAllLayer checkbox * fix: layer mapping --- .../components/popover/popover.component.html | 37 +++++++++++- .../components/popover/popover.component.scss | 9 ++- .../components/popover/popover.component.ts | 23 +++++--- .../svg/wrap/svg-keyboard-wrap.component.ts | 9 ++- .../directives/tooltip/tooltip.directive.ts | 28 +++++---- .../src/app/models/key-action-remap.ts | 7 +++ .../uhk-web/src/app/store/actions/keymap.ts | 11 +++- .../store/reducers/user-configuration.spec.ts | 20 ++++++- .../app/store/reducers/user-configuration.ts | 58 +++++++++++-------- packages/uhk-web/src/styles.scss | 9 +++ 10 files changed, 158 insertions(+), 53 deletions(-) create mode 100644 packages/uhk-web/src/app/models/key-action-remap.ts diff --git a/packages/uhk-web/src/app/components/popover/popover.component.html b/packages/uhk-web/src/app/components/popover/popover.component.html index 68465e91..91c1e91b 100644 --- a/packages/uhk-web/src/app/components/popover/popover.component.html +++ b/packages/uhk-web/src/app/components/popover/popover.component.html @@ -76,8 +76,41 @@ >
- - +
+
+ +
+
+ +
+
+ +
+
+ +
+ + +
diff --git a/packages/uhk-web/src/app/components/popover/popover.component.scss b/packages/uhk-web/src/app/components/popover/popover.component.scss index 6f537f2f..a67e0d54 100644 --- a/packages/uhk-web/src/app/components/popover/popover.component.scss +++ b/packages/uhk-web/src/app/components/popover/popover.component.scss @@ -70,7 +70,6 @@ background-color: #f7f7f7; border-top: 1px solid #ebebeb; border-radius: 0 0 5px 5px; - text-align: right; } .popover-title { @@ -133,3 +132,11 @@ margin-top: -1rem; } } + +.popover-action-form { + margin-top: 4px; + + label { + margin-right: 5px; + } +} diff --git a/packages/uhk-web/src/app/components/popover/popover.component.ts b/packages/uhk-web/src/app/components/popover/popover.component.ts index 18a219b7..0c2a7387 100644 --- a/packages/uhk-web/src/app/components/popover/popover.component.ts +++ b/packages/uhk-web/src/app/components/popover/popover.component.ts @@ -31,6 +31,7 @@ import { Tab } from './tab'; import { AppState } from '../../store'; import { getKeymaps } from '../../store/reducers/user-configuration'; +import { KeyActionRemap } from '../../models/key-action-remap'; enum TabName { Keypress, @@ -59,8 +60,8 @@ enum TabName { })), transition('opened => closed', [ animate('200ms ease-out', keyframes([ - style({ transform: 'translateY(0)', visibility: 'visible', opacity: 1, offset: 0 }), - style({ transform: 'translateY(30px)', visibility: 'hidden', opacity: 0, offset: 1 }) + style({transform: 'translateY(0)', visibility: 'visible', opacity: 1, offset: 0}), + style({transform: 'translateY(30px)', visibility: 'hidden', opacity: 0, offset: 1}) ])) ]), transition('closed => opened', [ @@ -68,8 +69,8 @@ enum TabName { visibility: 'visible' }), animate('200ms ease-out', keyframes([ - style({ transform: 'translateY(30px)', opacity: 0, offset: 0 }), - style({ transform: 'translateY(0)', opacity: 1, offset: 1 }) + style({transform: 'translateY(30px)', opacity: 0, offset: 0}), + style({transform: 'translateY(0)', opacity: 1, offset: 1}) ])) ]) ]) @@ -85,7 +86,7 @@ export class PopoverComponent implements OnChanges { @Input() allowLayerDoubleTap: boolean; @Output() cancel = new EventEmitter(); - @Output() remap = new EventEmitter(); + @Output() remap = new EventEmitter(); @ViewChild('tab') selectedTab: Tab; @ViewChild('popover') popoverHost: ElementRef; @@ -100,6 +101,9 @@ export class PopoverComponent implements OnChanges { leftPosition: number = 0; animationState: string; + remapOnAllKeymap: boolean; + remapOnAllLayer: boolean; + private readonly currentKeymap$ = new BehaviorSubject(undefined); constructor(store: Store) { @@ -139,6 +143,8 @@ export class PopoverComponent implements OnChanges { if (change['visible']) { if (change['visible'].currentValue) { this.animationState = 'opened'; + this.remapOnAllKeymap = false; + this.remapOnAllLayer = false; } else { this.animationState = 'closed'; } @@ -156,8 +162,11 @@ export class PopoverComponent implements OnChanges { onRemapKey(): void { if (this.keyActionValid) { try { - const keyAction = this.selectedTab.toKeyAction(); - this.remap.emit(keyAction); + this.remap.emit({ + remapOnAllKeymap: this.remapOnAllKeymap, + remapOnAllLayer: this.remapOnAllLayer, + action: this.selectedTab.toKeyAction() + }); } catch (e) { // TODO: show error dialog console.error(e); diff --git a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts index b89e5f29..b35d5f0c 100644 --- a/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts +++ b/packages/uhk-web/src/app/components/svg/wrap/svg-keyboard-wrap.component.ts @@ -42,6 +42,7 @@ import { KeymapActions } from '../../../store/actions'; import { PopoverComponent } from '../../popover'; import { KeyboardLayout } from '../../../keyboard/keyboard-layout.enum'; import { ChangeKeymapDescription } from '../../../models/ChangeKeymapDescription'; +import { KeyActionRemap } from '../../../models/key-action-remap'; interface NameValuePair { name: string; @@ -181,11 +182,15 @@ export class SvgKeyboardWrapComponent implements OnInit, OnChanges { this.currentLayer, moduleId, keyId, - keystrokeAction) + { + remapOnAllKeymap: false, + remapOnAllLayer: false, + action: keystrokeAction + }) ); } - onRemap(keyAction: KeyAction): void { + onRemap(keyAction: KeyActionRemap): void { this.store.dispatch( KeymapActions.saveKey( this.keymap, diff --git a/packages/uhk-web/src/app/directives/tooltip/tooltip.directive.ts b/packages/uhk-web/src/app/directives/tooltip/tooltip.directive.ts index f707c837..4c717af6 100644 --- a/packages/uhk-web/src/app/directives/tooltip/tooltip.directive.ts +++ b/packages/uhk-web/src/app/directives/tooltip/tooltip.directive.ts @@ -9,15 +9,10 @@ export class TooltipDirective implements AfterContentInit, OnChanges { @HostBinding('attr.data-placement') placement: string; @Input('title') title: string; @Input('html') html: boolean; + @Input() maxWidth: number; - private customTooltipTemplate = ` -
-
-
-
- `; - - constructor(private elementRef: ElementRef, private sanitizer: DomSanitizer) { } + constructor(private elementRef: ElementRef, private sanitizer: DomSanitizer) { + } ngAfterContentInit() { this.init(); @@ -33,7 +28,7 @@ export class TooltipDirective implements AfterContentInit, OnChanges { (jQuery(this.elementRef.nativeElement)).tooltip({ placement: this.placement, html: this.html, - template: this.customTooltipTemplate, + template: this.getCustomTemplate(), title: this.title }); } @@ -42,7 +37,7 @@ export class TooltipDirective implements AfterContentInit, OnChanges { (jQuery(this.elementRef.nativeElement)).tooltip({ placement: this.placement, html: this.html, - template: this.customTooltipTemplate, + template: this.getCustomTemplate(), title: this.title }); @@ -50,4 +45,17 @@ export class TooltipDirective implements AfterContentInit, OnChanges { .attr('title', this.title)) .tooltip('fixTitle'); } + + private getCustomTemplate(): string { + let style = ''; + + if (this.maxWidth) { + style = `style="max-width: ${this.maxWidth}px;"`; + } + + return `
+
+
+
`; + } } diff --git a/packages/uhk-web/src/app/models/key-action-remap.ts b/packages/uhk-web/src/app/models/key-action-remap.ts new file mode 100644 index 00000000..9cc30fbc --- /dev/null +++ b/packages/uhk-web/src/app/models/key-action-remap.ts @@ -0,0 +1,7 @@ +import { KeyAction } from 'uhk-common'; + +export interface KeyActionRemap { + remapOnAllKeymap: boolean; + remapOnAllLayer: boolean; + action: KeyAction; +} diff --git a/packages/uhk-web/src/app/store/actions/keymap.ts b/packages/uhk-web/src/app/store/actions/keymap.ts index 557467a4..56335f2f 100644 --- a/packages/uhk-web/src/app/store/actions/keymap.ts +++ b/packages/uhk-web/src/app/store/actions/keymap.ts @@ -1,7 +1,8 @@ import { Action } from '@ngrx/store'; -import { KeyAction, Keymap, Macro } from 'uhk-common'; +import { Keymap, Macro } from 'uhk-common'; import { UndoUserConfigData } from '../../models/undo-user-config-data'; import { ChangeKeymapDescription } from '../../models/ChangeKeymapDescription'; +import { KeyActionRemap } from '../../models/key-action-remap'; export type KeymapAction = KeymapActions.AddKeymapAction | @@ -60,7 +61,7 @@ export namespace KeymapActions { layer: number; module: number; key: number; - keyAction: KeyAction; + keyAction: KeyActionRemap; } }; @@ -172,7 +173,11 @@ export namespace KeymapActions { }; } - export function saveKey(keymap: Keymap, layer: number, module: number, key: number, keyAction: KeyAction): SaveKeyAction { + export function saveKey(keymap: Keymap, + layer: number, + module: number, + key: number, + keyAction: KeyActionRemap): SaveKeyAction { return { type: KeymapActions.SAVE_KEY, payload: { diff --git a/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts b/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts index 98701810..8c1b4c88 100644 --- a/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts +++ b/packages/uhk-web/src/app/store/reducers/user-configuration.spec.ts @@ -30,7 +30,11 @@ describe('user-configuration reducer', () => { layer: 0, module: 0, key: 0, - keyAction: keystrokeAction + keyAction: { + remapOnAllKeymap: false, + remapOnAllLayer: false, + action: keystrokeAction + } } }; const result = reducer(state, saveKeyAction); @@ -62,7 +66,12 @@ describe('user-configuration reducer', () => { layer: 0, module: 0, key: 0, - keyAction: switchLayerAction + keyAction: { + remapOnAllKeymap: false, + remapOnAllLayer: false, + action: switchLayerAction + } + } }; const result = reducer(state, saveKeyAction); @@ -243,7 +252,12 @@ describe('user-configuration reducer', () => { layer: 0, module: 0, key: 2, - keyAction: switchLayerAction + keyAction: { + remapOnAllKeymap: false, + remapOnAllLayer: false, + action: switchLayerAction + } + } }; const result = reducer(state, saveKeyAction); diff --git a/packages/uhk-web/src/app/store/reducers/user-configuration.ts b/packages/uhk-web/src/app/store/reducers/user-configuration.ts index 25b04211..1f29d066 100644 --- a/packages/uhk-web/src/app/store/reducers/user-configuration.ts +++ b/packages/uhk-web/src/app/store/reducers/user-configuration.ts @@ -68,7 +68,7 @@ export function reducer(state = initialState, action: Action & { payload?: any } break; } - const newKeymap = Object.assign(new Keymap(), keymapToRename, { name }); + const newKeymap = Object.assign(new Keymap(), keymapToRename, {name}); changedUserConfiguration.keymaps = insertItemInNameOrder( state.keymaps, @@ -139,38 +139,46 @@ export function reducer(state = initialState, action: Action & { payload?: any } const keyIndex: number = action.payload.key; const layerIndex: number = action.payload.layer; const moduleIndex: number = action.payload.module; - const newKeyAction = KeyActionHelper.createKeyAction(action.payload.keyAction); - const newKeymap: Keymap = Object.assign(new Keymap(), action.payload.keymap); - newKeymap.layers = newKeymap.layers.slice(); - - newKeymap.layers = newKeymap.layers.map((layer, index) => { - const newLayer = Object.assign(new Layer(), layer); - - if (index === layerIndex) { - setKeyActionToLayer(newLayer, moduleIndex, keyIndex, newKeyAction); - } - // If the key action is a SwitchLayerAction then set the same SwitchLayerAction - // on the target layer - else if (newKeyAction instanceof SwitchLayerAction) { - if (index - 1 === newKeyAction.layer) { - const clonedAction = KeyActionHelper.createKeyAction(action.payload.keyAction); - setKeyActionToLayer(newLayer, moduleIndex, keyIndex, clonedAction); - } else { - setKeyActionToLayer(newLayer, moduleIndex, keyIndex, null); - } - } - return newLayer; - }); + const keyActionRemap = action.payload.keyAction; + const newKeyAction = keyActionRemap.action; + const newKeymap: Keymap = action.payload.keymap; changedUserConfiguration.keymaps = state.keymaps.map(keymap => { - if (keymap.abbreviation === newKeymap.abbreviation) { - keymap = newKeymap; + if (keyActionRemap.remapOnAllKeymap || keymap.abbreviation === newKeymap.abbreviation) { + keymap = new Keymap(keymap); + + keymap.layers = keymap.layers.map((layer, index) => { + if (keyActionRemap.remapOnAllLayer || index === layerIndex) { + layer = new Layer(layer); + const clonedAction = KeyActionHelper.createKeyAction(newKeyAction); + + const isSwitchLayerAction = newKeyAction instanceof SwitchLayerAction; + // If the key action is a SwitchLayerAction then set the same SwitchLayerAction + // on the target layer and remove SwitchLayerAction from other layers + if (isSwitchLayerAction) { + if (index - 1 === (newKeyAction as SwitchLayerAction).layer) { + setKeyActionToLayer(layer, moduleIndex, keyIndex, clonedAction); + } else { + const actionOnLayer = layer.modules[moduleIndex].keyActions[keyIndex]; + if (actionOnLayer && actionOnLayer instanceof SwitchLayerAction) { + setKeyActionToLayer(layer, moduleIndex, keyIndex, null); + } + } + } + else { + setKeyActionToLayer(layer, moduleIndex, keyIndex, clonedAction); + } + } + + return layer; + }); } return keymap; }); break; } + case KeymapActions.CHECK_MACRO: changedUserConfiguration.keymaps = state.keymaps.map(keymap => { keymap = Object.assign(new Keymap(), keymap); diff --git a/packages/uhk-web/src/styles.scss b/packages/uhk-web/src/styles.scss index b17495b5..c20df93c 100644 --- a/packages/uhk-web/src/styles.scss +++ b/packages/uhk-web/src/styles.scss @@ -73,6 +73,11 @@ ul.btn-list { } } +ul.no-indent { + padding-left: 1em; + margin-bottom: 0; +} + .h1, .h2, .h3, h1, h2, h3 { margin-top: 10px; } @@ -178,3 +183,7 @@ pre { .ok-button { min-width: 100px; } + +.d-inline-block { + display: inline-block; +}