TeaSpeak-Client/modules/renderer/ppt.ts
2019-11-24 18:38:50 +01:00

137 lines
4.5 KiB
TypeScript

window["require_setup"](module);
import {KeyEvent as NKeyEvent} from "teaclient_ppt";
namespace _ppt {
let key_listener: ((_: ppt.KeyEvent) => any)[] = [];
let native_ppt;
function listener_key(type: ppt.EventType, nevent: NKeyEvent) {
if(nevent.key_code === 'VoidSymbol' || nevent.key_code === 'error')
nevent.key_code = undefined; /* trigger event for state update */
let event: ppt.KeyEvent = {
type: type,
key: nevent.key_code,
key_code: nevent.key_code,
key_ctrl: nevent.key_ctrl,
key_shift: nevent.key_shift,
key_alt: nevent.key_alt,
key_windows: nevent.key_windows
} as any;
//console.debug("Trigger key event %o", type);
for (const listener of key_listener)
listener && listener(event);
}
function native_keyhook(event: NKeyEvent) {
//console.log("Native event!: %o", event);
if(event.type == 0)
listener_key(ppt.EventType.KEY_PRESS, event);
else if(event.type == 1)
listener_key(ppt.EventType.KEY_RELEASE, event);
else if(event.type == 2)
listener_key(ppt.EventType.KEY_TYPED, event);
else
console.warn(tr("Received unknown native event: %o"), event);
}
export async function initialize() : Promise<void> {
native_ppt = require("teaclient_ppt");
register_key_listener(listener_hook);
native_ppt.RegisterCallback(native_keyhook);
}
export function finalize() {
unregister_key_listener(listener_hook);
native_ppt.UnregisterCallback(native_keyhook);
}
export function register_key_listener(listener: (_: ppt.KeyEvent) => any) {
key_listener.push(listener);
}
export function unregister_key_listener(listener: (_: ppt.KeyEvent) => any) {
key_listener.remove(listener);
}
let key_hooks: ppt.KeyHook[] = [];
interface CurrentState {
keys: {[code: string]:ppt.KeyEvent};
special: { [key:number]:boolean };
}
let current_state: CurrentState = {
special: []
} as any;
let key_hooks_active: ppt.KeyHook[] = [];
function listener_hook(event: ppt.KeyEvent) {
if(event.type == ppt.EventType.KEY_TYPED)
return;
let old_hooks = [...key_hooks_active];
let new_hooks = [];
current_state.special[ppt.SpecialKey.ALT] = event.key_alt;
current_state.special[ppt.SpecialKey.CTRL] = event.key_ctrl;
current_state.special[ppt.SpecialKey.SHIFT] = event.key_shift;
current_state.special[ppt.SpecialKey.WINDOWS] = event.key_windows;
current_state[event.key_code] = undefined;
if(event.type == ppt.EventType.KEY_PRESS) {
current_state[event.key_code] = event;
for(const hook of key_hooks) {
if(hook.key_code !== event.key_code) continue;
if(hook.key_alt != event.key_alt) continue;
if(hook.key_ctrl != event.key_ctrl) continue;
if(hook.key_shift != event.key_shift) continue;
if(hook.key_windows != event.key_windows) continue;
new_hooks.push(hook);
if(!old_hooks.remove(hook) && hook.callback_press) {
hook.callback_press();
log.trace(LogCategory.GENERAL, tr("Trigger key press for %o!"), hook);
}
}
}
//We have a new situation
for(const hook of old_hooks) {
//Do not test for meta key states because they could differ in a key release event
if(hook.key_code === event.key_code) {
if(hook.callback_release) {
hook.callback_release();
log.trace(LogCategory.GENERAL, tr("Trigger key release for %o!"), hook);
}
} else {
new_hooks.push(hook);
}
}
key_hooks_active = new_hooks;
}
export function register_key_hook(hook: ppt.KeyHook) {
key_hooks.push(hook);
}
export function unregister_key_hook(hook: ppt.KeyHook) {
key_hooks.remove(hook);
key_hooks_active.remove(hook);
}
export function key_pressed(code: string | ppt.SpecialKey) : boolean {
if(typeof(code) === 'string')
return typeof(current_state[code]) === "object";
return current_state.special[code];
}
}
Object.assign(window["ppt"] || (window["ppt"] = {} as any), _ppt);
console.dir(_ppt);