mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-04 22:57:19 +02:00
151 lines
4.3 KiB
TypeScript
Executable File
151 lines
4.3 KiB
TypeScript
Executable File
import { MouseButtonCode, WheelCode, type KeyCode } from "@/enums/mkb";
|
|
|
|
export const enum KeyModifier {
|
|
CTRL = 1,
|
|
SHIFT = 2,
|
|
ALT = 4,
|
|
};
|
|
|
|
export type KeyEventInfo = {
|
|
code: KeyCode | MouseButtonCode | WheelCode;
|
|
modifiers?: number;
|
|
};
|
|
|
|
export class KeyHelper {
|
|
private static readonly NON_PRINTABLE_KEYS = {
|
|
Backquote: '`',
|
|
Minus: '-',
|
|
Equal: '=',
|
|
BracketLeft: '[',
|
|
BracketRight: ']',
|
|
Backslash: '\\',
|
|
Semicolon: ';',
|
|
Quote: '\'',
|
|
Comma: ',',
|
|
Period: '.',
|
|
Slash: '/',
|
|
|
|
NumpadMultiply: 'Numpad *',
|
|
NumpadAdd: 'Numpad +',
|
|
NumpadSubtract: 'Numpad -',
|
|
NumpadDecimal: 'Numpad .',
|
|
NumpadDivide: 'Numpad /',
|
|
NumpadEqual: 'Numpad =',
|
|
|
|
// Mouse buttons
|
|
[MouseButtonCode.LEFT_CLICK]: 'Left Click',
|
|
[MouseButtonCode.RIGHT_CLICK]: 'Right Click',
|
|
[MouseButtonCode.MIDDLE_CLICK]: 'Middle Click',
|
|
|
|
[WheelCode.SCROLL_UP]: 'Scroll Up',
|
|
[WheelCode.SCROLL_DOWN]: 'Scroll Down',
|
|
[WheelCode.SCROLL_LEFT]: 'Scroll Left',
|
|
[WheelCode.SCROLL_RIGHT]: 'Scroll Right',
|
|
};
|
|
|
|
static getKeyFromEvent(e: Event): KeyEventInfo | null {
|
|
let code: KeyEventInfo['code'] | null = null;
|
|
let modifiers;
|
|
|
|
if (e instanceof KeyboardEvent) {
|
|
code = (e.code || e.key) as KeyCode;
|
|
|
|
// Modifiers
|
|
modifiers = 0;
|
|
modifiers ^= e.ctrlKey ? KeyModifier.CTRL : 0;
|
|
modifiers ^= e.shiftKey ? KeyModifier.SHIFT : 0;
|
|
modifiers ^= e.altKey ? KeyModifier.ALT : 0;
|
|
|
|
} else if (e instanceof WheelEvent) {
|
|
if (e.deltaY < 0) {
|
|
code = WheelCode.SCROLL_UP;
|
|
} else if (e.deltaY > 0) {
|
|
code = WheelCode.SCROLL_DOWN;
|
|
} else if (e.deltaX < 0) {
|
|
code = WheelCode.SCROLL_LEFT;
|
|
} else if (e.deltaX > 0) {
|
|
code = WheelCode.SCROLL_RIGHT;
|
|
}
|
|
} else if (e instanceof MouseEvent) {
|
|
code = 'Mouse' + e.button as MouseButtonCode;
|
|
}
|
|
|
|
if (code) {
|
|
const results: KeyEventInfo = { code };
|
|
if (modifiers) {
|
|
results.modifiers = modifiers;
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
static getFullKeyCodeFromEvent(e: KeyboardEvent): string {
|
|
const key = KeyHelper.getKeyFromEvent(e);
|
|
return key ? `${key.code}:${key.modifiers || 0}` : '';
|
|
}
|
|
|
|
static parseFullKeyCode(str: string | undefined | null): KeyEventInfo | null {
|
|
if (!str) {
|
|
return null;
|
|
}
|
|
|
|
const tmp = str.split(':');
|
|
|
|
const code = tmp[0] as KeyEventInfo['code'];
|
|
const modifiers = parseInt(tmp[1] as string);
|
|
|
|
return {
|
|
code,
|
|
modifiers,
|
|
} as KeyEventInfo;
|
|
}
|
|
|
|
static codeToKeyName(key: KeyEventInfo): string {
|
|
const { code, modifiers } = key;
|
|
|
|
const text = [(
|
|
KeyHelper.NON_PRINTABLE_KEYS[code as keyof typeof KeyHelper.NON_PRINTABLE_KEYS]
|
|
||
|
|
(code.startsWith('Key') && code.substring(3))
|
|
||
|
|
(code.startsWith('Digit') && code.substring(5))
|
|
||
|
|
(code.startsWith('Numpad') && ('Numpad ' + code.substring(6)))
|
|
||
|
|
(code.startsWith('Arrow') && ('Arrow ' + code.substring(5)))
|
|
||
|
|
(code.endsWith('Lock') && (code.replace('Lock', ' Lock')))
|
|
||
|
|
(code.endsWith('Left') && ('Left ' + code.replace('Left', '')))
|
|
||
|
|
(code.endsWith('Right') && ('Right ' + code.replace('Right', '')))
|
|
||
|
|
code
|
|
)];
|
|
|
|
if (modifiers && modifiers !== 0) {
|
|
if (!code.startsWith('Control') && !code.startsWith('Shift') && !code.startsWith('Alt')) {
|
|
// Shift
|
|
if (modifiers & KeyModifier.SHIFT) {
|
|
text.unshift('Shift');
|
|
}
|
|
|
|
// Alt
|
|
if (modifiers & KeyModifier.ALT) {
|
|
text.unshift('Alt');
|
|
}
|
|
|
|
// Ctrl
|
|
if (modifiers & KeyModifier.CTRL) {
|
|
text.unshift('Ctrl');
|
|
}
|
|
}
|
|
}
|
|
|
|
return text.join(' + ');
|
|
}
|
|
}
|