diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/settings/Key.ts | 61 | ||||
-rw-r--r-- | src/shared/settings/KeySequence.ts | 54 |
2 files changed, 115 insertions, 0 deletions
diff --git a/src/shared/settings/Key.ts b/src/shared/settings/Key.ts new file mode 100644 index 0000000..b11eeb2 --- /dev/null +++ b/src/shared/settings/Key.ts @@ -0,0 +1,61 @@ +export default class Key { + public readonly key: string; + + public readonly shift: boolean; + + public readonly ctrl: boolean; + + public readonly alt: boolean; + + public readonly meta: boolean; + + constructor({ key, shift, ctrl, alt, meta }: { + key: string; + shift: boolean; + ctrl: boolean; + alt: boolean; + meta: boolean; + }) { + this.key = key; + this.shift = shift; + this.ctrl = ctrl; + this.alt = alt; + this.meta = meta; + } + + static fromMapKey(str: string): Key { + if (str.startsWith('<') && str.endsWith('>')) { + let inner = str.slice(1, -1); + let shift = inner.includes('S-'); + let base = inner.slice(inner.lastIndexOf('-') + 1); + if (shift && base.length === 1) { + base = base.toUpperCase(); + } else if (!shift && base.length === 1) { + base = base.toLowerCase(); + } + return new Key({ + key: base, + shift: shift, + ctrl: inner.includes('C-'), + alt: inner.includes('A-'), + meta: inner.includes('M-'), + }); + } + + return new Key({ + key: str, + shift: str.toLowerCase() !== str, + ctrl: false, + alt: false, + meta: false, + }); + } + + equals(key: Key) { + return this.key === key.key && + this.ctrl === key.ctrl && + this.meta === key.meta && + this.alt === key.alt && + this.shift === key.shift; + } +} diff --git a/src/shared/settings/KeySequence.ts b/src/shared/settings/KeySequence.ts new file mode 100644 index 0000000..4955583 --- /dev/null +++ b/src/shared/settings/KeySequence.ts @@ -0,0 +1,54 @@ +import Key from '../../shared/settings/Key'; + +export default class KeySequence { + constructor( + public readonly keys: Key[], + ) { + } + + push(key: Key): number { + return this.keys.push(key); + } + + length(): number { + return this.keys.length; + } + + startsWith(o: KeySequence): boolean { + if (this.keys.length < o.keys.length) { + return false; + } + for (let i = 0; i < o.keys.length; ++i) { + if (!this.keys[i].equals(o.keys[i])) { + return false; + } + } + return true; + } + + static fromMapKeys(keys: string): KeySequence { + const fromMapKeysRecursive = ( + remaining: string, mappedKeys: Key[], + ): Key[] => { + if (remaining.length === 0) { + return mappedKeys; + } + + let nextPos = 1; + if (remaining.startsWith('<')) { + let ltPos = remaining.indexOf('>'); + if (ltPos > 0) { + nextPos = ltPos + 1; + } + } + + return fromMapKeysRecursive( + remaining.slice(nextPos), + mappedKeys.concat([Key.fromMapKey(remaining.slice(0, nextPos))]) + ); + }; + + let data = fromMapKeysRecursive(keys, []); + return new KeySequence(data); + } +} |