import { hasWon } from "data/projEntry"; import { globalBus } from "game/events"; import player from "game/player"; import { registerInfoComponent } from "game/settings"; import { Computable, GetComputableTypeWithDefault, GetComputableType, ProcessedComputable, processComputable } from "util/computed"; import { createLazyProxy } from "util/proxies"; import { shallowReactive, unref } from "vue"; import { findFeatures, jsx, Replace, setDefault } from "./feature"; export const hotkeys: Record = shallowReactive({}); export const HotkeyType = Symbol("Hotkey"); export interface HotkeyOptions { enabled?: Computable; key: string; description: Computable; onPress: VoidFunction; } export interface BaseHotkey { type: typeof HotkeyType; } export type Hotkey = Replace< T & BaseHotkey, { enabled: GetComputableTypeWithDefault; description: GetComputableType; } >; export type GenericHotkey = Replace< Hotkey, { enabled: ProcessedComputable; } >; export function createHotkey( optionsFunc: () => T & ThisType> ): Hotkey { return createLazyProxy(() => { const hotkey: T & Partial = optionsFunc(); hotkey.type = HotkeyType; processComputable(hotkey as T, "enabled"); setDefault(hotkey, "enabled", true); processComputable(hotkey as T, "description"); return hotkey as unknown as Hotkey; }); } 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 => { hotkeys[hotkey.key] = undefined; }); }); document.onkeydown = function (e) { 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(); } }; registerInfoComponent( jsx(() => { const keys = Object.values(hotkeys).filter(hotkey => unref(hotkey?.enabled)); if (keys.length === 0) { return ""; } return (

Hotkeys

{keys.map(hotkey => (
{hotkey?.key}: {hotkey?.description}
))}
); }) );