2018-11-17 11:28:16 +00:00
|
|
|
/// <reference path="../declarations/imports_shared.d.ts"/>
|
|
|
|
|
|
|
|
namespace ppt {
|
2018-11-17 15:25:44 +00:00
|
|
|
interface WebKeyEvent extends KeyEvent {
|
|
|
|
canceled: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
let key_listener: ((_: KeyEvent) => any)[] = [];
|
|
|
|
|
|
|
|
function listener_key(type: EventType, event: KeyboardEvent) {
|
|
|
|
const key_event = {
|
|
|
|
type: type,
|
|
|
|
|
|
|
|
key: event.key,
|
|
|
|
key_code: event.code,
|
|
|
|
|
|
|
|
key_ctrl: event.ctrlKey,
|
|
|
|
key_shift: event.shiftKey,
|
|
|
|
key_alt: event.altKey,
|
|
|
|
key_windows: event.metaKey,
|
|
|
|
|
|
|
|
canceled: event.defaultPrevented
|
|
|
|
} as WebKeyEvent;
|
|
|
|
//console.debug("Trigger key event %o", key_event);
|
|
|
|
|
|
|
|
for(const listener of key_listener)
|
|
|
|
listener(key_event);
|
|
|
|
|
|
|
|
if(key_event.canceled)
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
|
|
|
|
const proxy_key_press = event => listener_key(EventType.KEY_PRESS, event);
|
|
|
|
const proxy_key_release = event => listener_key(EventType.KEY_RELEASE, event);
|
|
|
|
const proxy_key_typed = event => listener_key(EventType.KEY_TYPED, event);
|
2018-11-17 11:28:16 +00:00
|
|
|
|
|
|
|
export function initialize() : Promise<void> {
|
2018-11-17 15:25:44 +00:00
|
|
|
document.addEventListener('keypress', proxy_key_typed);
|
|
|
|
document.addEventListener('keydown', proxy_key_press);
|
|
|
|
document.addEventListener('keyup', proxy_key_release);
|
|
|
|
|
|
|
|
register_key_listener(listener_hook);
|
2018-11-17 11:28:16 +00:00
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
2018-11-17 15:25:44 +00:00
|
|
|
export function finalize() {
|
|
|
|
document.removeEventListener("keypress", proxy_key_typed);
|
|
|
|
document.removeEventListener("keydown", proxy_key_press);
|
|
|
|
document.removeEventListener("keyup", proxy_key_release);
|
|
|
|
|
|
|
|
unregister_key_listener(listener_hook);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function register_key_listener(listener: (_: KeyEvent) => any) {
|
|
|
|
key_listener.push(listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function unregister_key_listener(listener: (_: KeyEvent) => any) {
|
|
|
|
key_listener.remove(listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let key_hooks: KeyHook[] = [];
|
2018-11-17 11:28:16 +00:00
|
|
|
|
2018-11-17 15:25:44 +00:00
|
|
|
interface CurrentState {
|
|
|
|
event: KeyEvent;
|
|
|
|
code: string;
|
|
|
|
|
|
|
|
special: { [key:number]:boolean };
|
|
|
|
}
|
|
|
|
let current_state: CurrentState = {
|
|
|
|
special: []
|
|
|
|
} as any;
|
|
|
|
|
|
|
|
let key_hooks_active: KeyHook[] = [];
|
|
|
|
|
|
|
|
function listener_hook(event: KeyEvent) {
|
|
|
|
if(event.type == EventType.KEY_TYPED)
|
|
|
|
return;
|
|
|
|
|
|
|
|
let old_hooks = [...key_hooks_active];
|
|
|
|
let new_hooks = [];
|
|
|
|
|
|
|
|
current_state.special[SpecialKey.ALT] = event.key_alt;
|
|
|
|
current_state.special[SpecialKey.CTRL] = event.key_ctrl;
|
|
|
|
current_state.special[SpecialKey.SHIFT] = event.key_shift;
|
|
|
|
current_state.special[SpecialKey.WINDOWS] = event.key_windows;
|
|
|
|
|
|
|
|
current_state.code = undefined;
|
|
|
|
current_state.event = undefined;
|
|
|
|
|
|
|
|
if(event.type == EventType.KEY_PRESS) {
|
|
|
|
current_state.event = event;
|
|
|
|
current_state.code = event.key_code;
|
|
|
|
|
|
|
|
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();
|
|
|
|
console.debug("Trigger key press for %o!", hook);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//We have a new situation
|
|
|
|
for(const hook of old_hooks)
|
|
|
|
if(hook.callback_release) {
|
|
|
|
hook.callback_release();
|
|
|
|
console.debug("Trigger key release for %o!", hook);
|
|
|
|
}
|
|
|
|
key_hooks_active = new_hooks;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function register_key_hook(hook: KeyHook) {
|
|
|
|
key_hooks.push(hook);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function unregister_key_hook(hook: KeyHook) {
|
|
|
|
key_hooks.remove(hook);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function key_pressed(code: string | SpecialKey) : boolean {
|
|
|
|
if(typeof(code) === 'string')
|
|
|
|
return current_state.code == code;
|
|
|
|
return current_state.special[code];
|
|
|
|
}
|
2018-11-17 11:28:16 +00:00
|
|
|
}
|