TeaWeb/shared/js/PPTListener.ts

226 lines
6.0 KiB
TypeScript
Raw Permalink Normal View History

import { tr } from "./i18n/localize";
2019-05-25 18:43:03 +00:00
2020-03-30 11:44:18 +00:00
export enum EventType {
KEY_PRESS,
KEY_RELEASE,
KEY_TYPED
}
2020-03-30 11:44:18 +00:00
export enum SpecialKey {
CTRL,
WINDOWS,
SHIFT,
ALT
}
2020-03-30 11:44:18 +00:00
export interface KeyDescriptor {
keyCode: string;
keyCtrl: boolean;
keyWindows: boolean;
keyShift: boolean;
keyAlt: boolean;
2020-03-30 11:44:18 +00:00
}
2020-03-30 11:44:18 +00:00
export interface KeyEvent extends KeyDescriptor {
readonly type: EventType;
readonly key: string;
}
2021-03-24 16:47:45 +00:00
export interface KeyHook extends Partial<KeyDescriptor> {
callbackPress: () => any;
callbackRelease: () => any;
}
2021-03-24 16:47:45 +00:00
interface RegisteredKeyHook extends KeyHook {
triggered: boolean
}
export interface KeyBoardBackend {
registerListener(listener: (event: KeyEvent) => void);
unregisterListener(listener: (event: KeyEvent) => void);
registerHook(hook: KeyHook): () => void;
unregisterHook(hook: KeyHook);
isKeyPressed(key: string | SpecialKey): boolean;
}
export class AbstractKeyBoard implements KeyBoardBackend {
protected readonly registeredListener: ((event: KeyEvent) => void)[];
protected readonly activeSpecialKeys: { [key: number]: boolean };
protected readonly activeKeys;
2021-03-24 16:47:45 +00:00
protected registeredKeyHooks: RegisteredKeyHook[] = [];
constructor() {
this.activeSpecialKeys = {};
this.activeKeys = {};
this.registeredListener = [];
}
protected destroy() { }
isKeyPressed(key: string | SpecialKey): boolean {
if (typeof (key) === 'string') {
return typeof this.activeKeys[key] !== "undefined";
}
return this.activeSpecialKeys[key];
}
registerHook(hook: KeyHook) {
2021-03-24 16:47:45 +00:00
const registeredHook: RegisteredKeyHook = {
triggered: false,
...hook
};
this.registeredKeyHooks.push(registeredHook);
if (this.shouldHookBeActive(registeredHook)) {
2021-03-24 16:47:45 +00:00
registeredHook.triggered = true;
registeredHook.callbackPress();
}
return () => this.unregisterHook(hook);
}
unregisterHook(hook: KeyHook) {
if (!("triggered" in hook)) {
2021-03-24 16:47:45 +00:00
return;
}
this.registeredKeyHooks.remove(hook as RegisteredKeyHook);
}
registerListener(listener: (event: KeyEvent) => void) {
this.registeredListener.push(listener);
}
unregisterListener(listener: (event: KeyEvent) => void) {
this.registeredListener.remove(listener);
}
2021-03-24 16:47:45 +00:00
private shouldHookBeActive(hook: KeyHook) {
if (typeof hook.keyAlt !== "undefined" && hook.keyAlt != this.activeSpecialKeys[SpecialKey.ALT]) {
2021-03-24 16:47:45 +00:00
return false;
}
if (typeof hook.keyCtrl !== "undefined" && hook.keyCtrl != this.activeSpecialKeys[SpecialKey.CTRL]) {
2021-03-24 16:47:45 +00:00
return false;
}
if (typeof hook.keyShift !== "undefined" && hook.keyShift != this.activeSpecialKeys[SpecialKey.SHIFT]) {
2021-03-24 16:47:45 +00:00
return false;
}
if (typeof hook.keyWindows !== "undefined" && hook.keyWindows != this.activeSpecialKeys[SpecialKey.WINDOWS]) {
2021-03-24 16:47:45 +00:00
return false;
}
return typeof hook.keyCode === "undefined" || typeof this.activeKeys[hook.keyCode] !== "undefined";
}
protected fireKeyEvent(event: KeyEvent) {
//console.debug("Trigger key event %o", key_event);
for (const listener of this.registeredListener) {
listener(event);
}
if (event.type == EventType.KEY_TYPED) {
return;
}
this.activeSpecialKeys[SpecialKey.ALT] = event.keyAlt;
this.activeSpecialKeys[SpecialKey.CTRL] = event.keyCtrl;
this.activeSpecialKeys[SpecialKey.SHIFT] = event.keyShift;
this.activeSpecialKeys[SpecialKey.WINDOWS] = event.keyWindows;
if (event.type == EventType.KEY_PRESS) {
this.activeKeys[event.keyCode] = event;
2021-03-24 16:47:45 +00:00
} else {
delete this.activeKeys[event.keyCode];
}
for (const hook of this.registeredKeyHooks) {
2021-03-24 16:47:45 +00:00
const hookActive = this.shouldHookBeActive(hook);
if (hookActive === hook.triggered) {
2021-03-24 16:47:45 +00:00
continue;
}
2021-03-24 16:47:45 +00:00
hook.triggered = hookActive;
if (hookActive) {
if (hook.callbackPress) {
hook.callbackPress();
}
2021-03-24 16:47:45 +00:00
} else {
if (hook.callbackRelease) {
hook.callbackRelease();
}
}
}
}
protected resetKeyboardState() {
this.activeSpecialKeys[SpecialKey.ALT] = false;
this.activeSpecialKeys[SpecialKey.CTRL] = false;
this.activeSpecialKeys[SpecialKey.SHIFT] = false;
this.activeSpecialKeys[SpecialKey.WINDOWS] = false;
for (const code of Object.keys(this.activeKeys)) {
delete this.activeKeys[code];
}
for (const hook of this.registeredKeyHooks) {
if (hook.triggered) {
if (hook.callbackRelease) {
2021-03-24 16:47:45 +00:00
hook.callbackRelease();
}
2021-03-24 16:47:45 +00:00
hook.triggered = false;
}
}
}
}
let keyBoardBackend: KeyBoardBackend;
export function getKeyBoard(): KeyBoardBackend {
return keyBoardBackend;
}
export function setKeyBoardBackend(newBackend: KeyBoardBackend) {
keyBoardBackend = newBackend;
2020-03-30 11:44:18 +00:00
}
export function getKeyDescription(key: KeyDescriptor) {
2020-03-30 11:44:18 +00:00
let result = "";
if (key.keyShift) {
2020-03-30 11:44:18 +00:00
result += " + " + tr("Shift");
2020-09-07 10:42:00 +00:00
}
if (key.keyAlt) {
2020-03-30 11:44:18 +00:00
result += " + " + tr("Alt");
2020-09-07 10:42:00 +00:00
}
if (key.keyCtrl) {
2020-03-30 11:44:18 +00:00
result += " + " + tr("CTRL");
2020-09-07 10:42:00 +00:00
}
if (key.keyWindows) {
2020-09-07 10:42:00 +00:00
result += " + " + tr("Win");
}
2019-08-21 08:00:01 +00:00
if (key.keyCode) {
let keyName;
if (key.keyCode.startsWith("Key")) {
keyName = key.keyCode.substr(3);
} else if (key.keyCode.startsWith("Digit")) {
keyName = key.keyCode.substr(5);
} else if (key.keyCode.startsWith("Numpad")) {
keyName = "Numpad " + key.keyCode.substr(6);
2020-09-07 10:42:00 +00:00
} else {
keyName = key.keyCode;
2020-09-07 10:42:00 +00:00
}
result += " + " + keyName;
2020-04-10 18:57:50 +00:00
}
2020-09-07 10:42:00 +00:00
return result ? result.substr(3) : tr("unset");
}