2022-03-03 02:34:39 +00:00
|
|
|
import { hasWon } from "@/data/projEntry";
|
2022-01-14 04:25:47 +00:00
|
|
|
import { globalBus } from "@/game/events";
|
|
|
|
import player from "@/game/player";
|
|
|
|
import {
|
|
|
|
Computable,
|
|
|
|
GetComputableTypeWithDefault,
|
|
|
|
GetComputableType,
|
|
|
|
ProcessedComputable,
|
|
|
|
processComputable
|
|
|
|
} from "@/util/computed";
|
2022-02-27 19:49:34 +00:00
|
|
|
import { createLazyProxy } from "@/util/proxies";
|
2022-01-14 04:25:47 +00:00
|
|
|
import { unref } from "vue";
|
|
|
|
import { findFeatures, Replace, setDefault } from "./feature";
|
|
|
|
|
2022-01-25 04:23:30 +00:00
|
|
|
export const hotkeys: Record<string, GenericHotkey | undefined> = {};
|
2022-01-14 04:25:47 +00:00
|
|
|
export const HotkeyType = Symbol("Hotkey");
|
|
|
|
|
|
|
|
export interface HotkeyOptions {
|
|
|
|
enabled?: Computable<boolean>;
|
|
|
|
key: string;
|
|
|
|
description: Computable<string>;
|
|
|
|
onPress: VoidFunction;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface BaseHotkey {
|
|
|
|
type: typeof HotkeyType;
|
|
|
|
}
|
|
|
|
|
|
|
|
export type Hotkey<T extends HotkeyOptions> = Replace<
|
|
|
|
T & BaseHotkey,
|
|
|
|
{
|
|
|
|
enabled: GetComputableTypeWithDefault<T["enabled"], true>;
|
|
|
|
description: GetComputableType<T["description"]>;
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
|
|
|
|
export type GenericHotkey = Replace<
|
|
|
|
Hotkey<HotkeyOptions>,
|
|
|
|
{
|
|
|
|
enabled: ProcessedComputable<boolean>;
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
|
2022-02-27 19:49:34 +00:00
|
|
|
export function createHotkey<T extends HotkeyOptions>(
|
|
|
|
optionsFunc: () => T & ThisType<Hotkey<T>>
|
|
|
|
): Hotkey<T> {
|
|
|
|
return createLazyProxy(() => {
|
|
|
|
const hotkey: T & Partial<BaseHotkey> = optionsFunc();
|
|
|
|
hotkey.type = HotkeyType;
|
2022-01-14 04:25:47 +00:00
|
|
|
|
2022-02-27 19:49:34 +00:00
|
|
|
processComputable(hotkey as T, "enabled");
|
|
|
|
setDefault(hotkey, "enabled", true);
|
|
|
|
processComputable(hotkey as T, "description");
|
2022-01-14 04:25:47 +00:00
|
|
|
|
2022-02-27 19:49:34 +00:00
|
|
|
return hotkey as unknown as Hotkey<T>;
|
|
|
|
});
|
2022-01-14 04:25:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
globalBus.on("addLayer", layer => {
|
|
|
|
(findFeatures(layer, HotkeyType) as GenericHotkey[]).forEach(hotkey => {
|
|
|
|
hotkeys[hotkey.key] = hotkey;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
globalBus.on("removeLayer", layer => {
|
|
|
|
(findFeatures(layer, HotkeyType) as GenericHotkey[]).forEach(hotkey => {
|
2022-01-25 04:23:30 +00:00
|
|
|
hotkeys[hotkey.key] = undefined;
|
2022-01-14 04:25:47 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-01-25 04:23:30 +00:00
|
|
|
document.onkeydown = function (e) {
|
2022-01-14 04:25:47 +00:00
|
|
|
if ((e.target as HTMLElement | null)?.tagName === "INPUT") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (hasWon.value && !player.keepGoing) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let key = e.key;
|
|
|
|
if (e.shiftKey) {
|
|
|
|
key = "shift+" + key;
|
|
|
|
}
|
|
|
|
if (e.ctrlKey) {
|
|
|
|
key = "ctrl+" + key;
|
|
|
|
}
|
|
|
|
const hotkey = hotkeys[key];
|
|
|
|
if (hotkey && unref(hotkey.enabled)) {
|
|
|
|
e.preventDefault();
|
|
|
|
hotkey.onPress();
|
|
|
|
}
|
|
|
|
};
|