From c86abe5ff7d7ba3bf7c10d79df0b7361480a1c49 Mon Sep 17 00:00:00 2001 From: sguenter Date: Wed, 27 Dec 2023 19:01:12 +0100 Subject: [PATCH] update --- src/{HotkeyManager.ts => HotKeyManager.ts} | 91 +++++++++++++--------- 1 file changed, 53 insertions(+), 38 deletions(-) rename src/{HotkeyManager.ts => HotKeyManager.ts} (70%) diff --git a/src/HotkeyManager.ts b/src/HotKeyManager.ts similarity index 70% rename from src/HotkeyManager.ts rename to src/HotKeyManager.ts index ff3e47b..17f63a0 100644 --- a/src/HotkeyManager.ts +++ b/src/HotKeyManager.ts @@ -1,24 +1,21 @@ import { HotkeyDefinitionType, specialKeys } from './HotkeyDefinitionType'; import { HotkeyListener } from './HotkeyListener'; -import { JsonHelper, ObjectHelper } from '@ainias42/js-helper'; +import { JsonHelper, ObjectHelper, Override } from '@ainias42/js-helper'; import { HotkeyEntry } from './HotkeyEntry'; import { SubKeyType } from './SubKeyType'; import { HotkeyPressedMap } from './HotkeyPressedMap'; import { HotkeyConfigWithOptionals } from './HotkeyConfigWithOptionals'; -export class HotkeyManager>> { +export class HotKeyManager>> { private keyPressedMap = new Map(); - private hotkeys: HotkeyConfig; - private hotkeysPressedMap: HotkeyPressedMap; + private hotKeys: HotkeyConfig; + private hotKeysPressedMap: HotkeyPressedMap; private enabled = true; - private ignoreFormElements = true; + private readonly ignoreFormElements: boolean = true; constructor(hotkeys: HotkeyConfigWithOptionals, ignoreFormElements?: boolean) { - this.hotkeys = ObjectHelper.entries(hotkeys).reduce((acc, [key, value]) => { - acc[key] = { subKeys: {}, callbacks: [], ...value } as unknown as HotkeyConfig[typeof key]; - return acc; - }, {} as HotkeyConfig); - this.hotkeysPressedMap = this.generateHotkeyPressedMap(); + this.hotKeys = {} as HotkeyConfig; + this.addHotKeys(hotkeys); if (ignoreFormElements !== undefined) { this.ignoreFormElements = ignoreFormElements; @@ -29,7 +26,8 @@ export class HotkeyManager HotkeyManager.checkAffection(keyDefinition, key)); + return keyDefinitions.some((keyDefinition) => HotKeyManager.checkAffection(keyDefinition, key)); } private static checkAffection(keyDefinition: HotkeyDefinitionType, key: string): boolean { @@ -48,11 +46,28 @@ export class HotkeyManager>>( + hotkeys: HotkeyConfigWithOptionals, + ) { + type NewConfig = Override; + + this.hotKeys = { + ...this.hotKeys, + ...ObjectHelper.entries(hotkeys).reduce((acc, [key, value]) => { + acc[key] = { subKeys: {}, callbacks: [], ...value } as unknown as NewConfig[typeof key]; + return acc; + }, {} as NewConfig), + }; + this.hotKeysPressedMap = this.generateHotkeyPressedMap(); + + return this as unknown as HotKeyManager; + } + addListener( hotkeyName: HotkeyName, callback: HotkeyListener>, ) { - const { callbacks } = this.hotkeys[hotkeyName]; + const { callbacks } = this.hotKeys[hotkeyName]; callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); @@ -71,15 +86,15 @@ export class HotkeyManager !HotkeyManager.isEqual(key, definition)); + removeHotKeyDefinition(hotkey: keyof HotkeyConfig, definition: HotkeyDefinitionType) { + this.hotKeys[hotkey].keys = this.hotKeys[hotkey].keys.filter((key) => !HotKeyManager.isEqual(key, definition)); } - setHotkeyDefinitions(hotkey: keyof HotkeyConfig, definitions: HotkeyDefinitionType[]) { - this.hotkeys[hotkey].keys = definitions; + setHotKeyDefinitions(hotkey: keyof HotkeyConfig, definitions: HotkeyDefinitionType[]) { + this.hotKeys[hotkey].keys = definitions; } addSubKeyDefinition( @@ -87,7 +102,7 @@ export class HotkeyManager, definition: HotkeyDefinitionType, ) { - this.hotkeys[hotkey].subKeys[subKey as string].push(definition); + this.hotKeys[hotkey].subKeys[subKey as string].push(definition); } removeSubKeyDefinition( @@ -95,8 +110,8 @@ export class HotkeyManager, definition: HotkeyDefinitionType, ) { - const { subKeys } = this.hotkeys[hotkey]; - subKeys[subKey as string] = subKeys[subKey as string].filter((key) => !HotkeyManager.isEqual(key, definition)); + const { subKeys } = this.hotKeys[hotkey]; + subKeys[subKey as string] = subKeys[subKey as string].filter((key) => !HotKeyManager.isEqual(key, definition)); } setSubKeyDefinitions( @@ -104,16 +119,16 @@ export class HotkeyManager, definitions: HotkeyDefinitionType[], ) { - this.hotkeys[hotkey].subKeys[subKey as string] = definitions; + this.hotKeys[hotkey].subKeys[subKey as string] = definitions; } getConfig() { - return this.hotkeys; + return this.hotKeys; } addKeyListeners() { window.addEventListener('keydown', (e) => { - if (this.ignoreFormElements && HotkeyManager.isFormElement(e.target)) { + if (this.ignoreFormElements && HotKeyManager.isFormElement(e.target)) { return; } @@ -134,16 +149,16 @@ export class HotkeyManager(hotkey: Hotkey, subkey: SubKeyType) { - return this.hotkeysPressedMap[hotkey].isPressed && this.hotkeysPressedMap[hotkey].subKeys[subkey]; + return this.hotKeysPressedMap[hotkey].isPressed && this.hotKeysPressedMap[hotkey].subKeys[subkey]; } private checkHotkeyDefinitions(keyDefinitions: HotkeyDefinitionType[]): boolean { @@ -165,7 +180,7 @@ export class HotkeyManager { + return ObjectHelper.entries(this.hotKeys).reduce((acc, [key, value]) => { const isPressed = this.checkHotkeyDefinitions(value.keys); acc[key] = { isPressed, @@ -183,8 +198,8 @@ export class HotkeyManager + const pressedEntry = this.hotKeysPressedMap[key]; + this.hotKeys[key].callbacks.forEach((callback) => callback({ event, subKeys: pressedEntry.subKeys, isPressed: pressedEntry.isPressed }), ); } @@ -192,9 +207,9 @@ export class HotkeyManager { + const oldMap = this.hotKeysPressedMap; + this.hotKeysPressedMap = this.generateHotkeyPressedMap(); + const hotkeysToCheckAffection = ObjectHelper.entries(this.hotKeysPressedMap).filter(([key, value]) => { const oldValue = oldMap[key]; if ( oldValue.isPressed !== value.isPressed || @@ -209,12 +224,12 @@ export class HotkeyManager { - const keyDefinition = this.hotkeys[key]; - if (HotkeyManager.checkAffections(keyDefinition.keys, eventKey)) { + const keyDefinition = this.hotKeys[key]; + if (HotKeyManager.checkAffections(keyDefinition.keys, eventKey)) { hotkeysToTrigger.push(key); } else { ObjectHelper.values(keyDefinition.subKeys).forEach((subKeyDefinitions) => { - if (HotkeyManager.checkAffections(subKeyDefinitions, eventKey)) { + if (HotKeyManager.checkAffections(subKeyDefinitions, eventKey)) { hotkeysToTrigger.push(key); } });