@witchcraft/spellcraft 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +579 -0
- package/dist/core/EmulatedEvent.d.ts +10 -0
- package/dist/core/EmulatedEvent.js +19 -0
- package/dist/core/Emulator.d.ts +74 -0
- package/dist/core/Emulator.js +153 -0
- package/dist/core/ShortcutManagerManager.d.ts +103 -0
- package/dist/core/ShortcutManagerManager.js +267 -0
- package/dist/core/addCommand.d.ts +7 -0
- package/dist/core/addCommand.js +7 -0
- package/dist/core/addKey.d.ts +7 -0
- package/dist/core/addKey.js +7 -0
- package/dist/core/addShortcut.d.ts +7 -0
- package/dist/core/addShortcut.js +7 -0
- package/dist/core/attach.d.ts +10 -0
- package/dist/core/attach.js +13 -0
- package/dist/core/createCommand.d.ts +4 -0
- package/dist/core/createCommand.js +11 -0
- package/dist/core/createCommands.d.ts +11 -0
- package/dist/core/createCommands.js +20 -0
- package/dist/core/createCondition.d.ts +7 -0
- package/dist/core/createCondition.js +11 -0
- package/dist/core/createContext.d.ts +2 -0
- package/dist/core/createContext.js +8 -0
- package/dist/core/createKey.d.ts +10 -0
- package/dist/core/createKey.js +35 -0
- package/dist/core/createKeys.d.ts +5 -0
- package/dist/core/createKeys.js +36 -0
- package/dist/core/createManager.d.ts +81 -0
- package/dist/core/createManager.js +83 -0
- package/dist/core/createManagerEventListeners.d.ts +4 -0
- package/dist/core/createManagerEventListeners.js +130 -0
- package/dist/core/createManagerOptions.d.ts +8 -0
- package/dist/core/createManagerOptions.js +17 -0
- package/dist/core/createShortcut.d.ts +8 -0
- package/dist/core/createShortcut.js +24 -0
- package/dist/core/createShortcuts.d.ts +13 -0
- package/dist/core/createShortcuts.js +20 -0
- package/dist/core/detach.d.ts +10 -0
- package/dist/core/detach.js +6 -0
- package/dist/core/index.d.ts +32 -0
- package/dist/core/index.js +32 -0
- package/dist/core/removeCommand.d.ts +7 -0
- package/dist/core/removeCommand.js +7 -0
- package/dist/core/removeKey.d.ts +7 -0
- package/dist/core/removeKey.js +7 -0
- package/dist/core/removeShortcut.d.ts +7 -0
- package/dist/core/removeShortcut.js +7 -0
- package/dist/core/setCommandProp.d.ts +17 -0
- package/dist/core/setCommandProp.js +96 -0
- package/dist/core/setCommandsProp.d.ts +15 -0
- package/dist/core/setCommandsProp.js +94 -0
- package/dist/core/setKeyProp.d.ts +16 -0
- package/dist/core/setKeyProp.js +47 -0
- package/dist/core/setKeysProp.d.ts +10 -0
- package/dist/core/setKeysProp.js +166 -0
- package/dist/core/setManagerProp.d.ts +34 -0
- package/dist/core/setManagerProp.js +54 -0
- package/dist/core/setShortcutProp.d.ts +9 -0
- package/dist/core/setShortcutProp.js +50 -0
- package/dist/core/setShortcutsProp.d.ts +12 -0
- package/dist/core/setShortcutsProp.js +93 -0
- package/dist/defaults/KeysSorter.d.ts +35 -0
- package/dist/defaults/KeysSorter.js +20 -0
- package/dist/defaults/Stringifier.d.ts +66 -0
- package/dist/defaults/Stringifier.js +119 -0
- package/dist/defaults/defaultConditionEquals.d.ts +19 -0
- package/dist/defaults/defaultConditionEquals.js +5 -0
- package/dist/defaults/defaultManagerCallback.d.ts +7 -0
- package/dist/defaults/defaultManagerCallback.js +5 -0
- package/dist/helpers/KnownError.d.ts +8 -0
- package/dist/helpers/KnownError.js +3 -0
- package/dist/helpers/calculateAndSetPositionAndWidth.d.ts +13 -0
- package/dist/helpers/calculateAndSetPositionAndWidth.js +18 -0
- package/dist/helpers/calculateLayoutSize.d.ts +9 -0
- package/dist/helpers/calculateLayoutSize.js +13 -0
- package/dist/helpers/doesShortcutConflict.d.ts +18 -0
- package/dist/helpers/doesShortcutConflict.js +42 -0
- package/dist/helpers/equalsCommand.d.ts +7 -0
- package/dist/helpers/equalsCommand.js +4 -0
- package/dist/helpers/equalsContext.d.ts +7 -0
- package/dist/helpers/equalsContext.js +19 -0
- package/dist/helpers/equalsShortcut.d.ts +9 -0
- package/dist/helpers/equalsShortcut.js +7 -0
- package/dist/helpers/forceClear.d.ts +12 -0
- package/dist/helpers/forceClear.js +16 -0
- package/dist/helpers/forceUpdateNativeKeysState.d.ts +5 -0
- package/dist/helpers/forceUpdateNativeKeysState.js +4 -0
- package/dist/helpers/generateKeyShortcutMap.d.ts +23 -0
- package/dist/helpers/generateKeyShortcutMap.js +64 -0
- package/dist/helpers/getKeyFromEventCode.d.ts +15 -0
- package/dist/helpers/getKeyFromEventCode.js +36 -0
- package/dist/helpers/getKeyFromIdOrVariant.d.ts +4 -0
- package/dist/helpers/getKeyFromIdOrVariant.js +26 -0
- package/dist/helpers/getKeyboardLayoutMap.d.ts +5 -0
- package/dist/helpers/getKeyboardLayoutMap.js +7 -0
- package/dist/helpers/getLabel.d.ts +9 -0
- package/dist/helpers/getLabel.js +6 -0
- package/dist/helpers/getTriggerableShortcut.d.ts +6 -0
- package/dist/helpers/getTriggerableShortcut.js +25 -0
- package/dist/helpers/index.d.ts +28 -0
- package/dist/helpers/index.js +28 -0
- package/dist/helpers/isValidManager.d.ts +3 -0
- package/dist/helpers/isValidManager.js +20 -0
- package/dist/helpers/isValidShortcut.d.ts +3 -0
- package/dist/helpers/isValidShortcut.js +10 -0
- package/dist/helpers/labelWithEvent.d.ts +13 -0
- package/dist/helpers/labelWithEvent.js +20 -0
- package/dist/helpers/labelWithKeyboardMap.d.ts +15 -0
- package/dist/helpers/labelWithKeyboardMap.js +17 -0
- package/dist/helpers/managerToStorableClone.d.ts +12 -0
- package/dist/helpers/managerToStorableClone.js +13 -0
- package/dist/helpers/onKeyboardLayoutChange.d.ts +10 -0
- package/dist/helpers/onKeyboardLayoutChange.js +7 -0
- package/dist/helpers/safeSetManagerChain.d.ts +20 -0
- package/dist/helpers/safeSetManagerChain.js +37 -0
- package/dist/helpers/shortcutCanExecuteIn.d.ts +4 -0
- package/dist/helpers/shortcutCanExecuteIn.js +9 -0
- package/dist/helpers/shortcutIsTriggerableBy.d.ts +2 -0
- package/dist/helpers/shortcutIsTriggerableBy.js +5 -0
- package/dist/helpers/shortcutSwapChords.d.ts +75 -0
- package/dist/helpers/shortcutSwapChords.js +118 -0
- package/dist/helpers/virtualPress.d.ts +13 -0
- package/dist/helpers/virtualPress.js +15 -0
- package/dist/helpers/virtualRelease.d.ts +5 -0
- package/dist/helpers/virtualRelease.js +15 -0
- package/dist/helpers/virtualToggle.d.ts +7 -0
- package/dist/helpers/virtualToggle.js +16 -0
- package/dist/internal/addToChain.d.ts +3 -0
- package/dist/internal/addToChain.js +27 -0
- package/dist/internal/areValidKeys.d.ts +7 -0
- package/dist/internal/areValidKeys.js +28 -0
- package/dist/internal/areValidVariants.d.ts +4 -0
- package/dist/internal/areValidVariants.js +45 -0
- package/dist/internal/checkTrigger.d.ts +2 -0
- package/dist/internal/checkTrigger.js +47 -0
- package/dist/internal/checkUntrigger.d.ts +2 -0
- package/dist/internal/checkUntrigger.js +18 -0
- package/dist/internal/cloneLastChord.d.ts +4 -0
- package/dist/internal/cloneLastChord.js +5 -0
- package/dist/internal/containsPossibleToggleChords.d.ts +13 -0
- package/dist/internal/containsPossibleToggleChords.js +65 -0
- package/dist/internal/errorTextAdd.d.ts +1 -0
- package/dist/internal/errorTextAdd.js +11 -0
- package/dist/internal/errorTextInUse.d.ts +1 -0
- package/dist/internal/errorTextInUse.js +8 -0
- package/dist/internal/errorTextRemove.d.ts +1 -0
- package/dist/internal/errorTextRemove.js +8 -0
- package/dist/internal/getModifierState.d.ts +2 -0
- package/dist/internal/getModifierState.js +7 -0
- package/dist/internal/getPressedKeys.d.ts +7 -0
- package/dist/internal/getPressedKeys.js +18 -0
- package/dist/internal/getPressedModifierKeys.d.ts +2 -0
- package/dist/internal/getPressedModifierKeys.js +10 -0
- package/dist/internal/getPressedNonModifierKeys.d.ts +7 -0
- package/dist/internal/getPressedNonModifierKeys.js +11 -0
- package/dist/internal/inChain.d.ts +5 -0
- package/dist/internal/inChain.js +14 -0
- package/dist/internal/isValidChain.d.ts +10 -0
- package/dist/internal/isValidChain.js +22 -0
- package/dist/internal/isValidChord.d.ts +11 -0
- package/dist/internal/isValidChord.js +59 -0
- package/dist/internal/isValidCommand.d.ts +12 -0
- package/dist/internal/isValidCommand.js +20 -0
- package/dist/internal/keyOrder.d.ts +6 -0
- package/dist/internal/keyOrder.js +14 -0
- package/dist/internal/removeFromChain.d.ts +3 -0
- package/dist/internal/removeFromChain.js +32 -0
- package/dist/internal/safeSetEmulatedToggleState.d.ts +4 -0
- package/dist/internal/safeSetEmulatedToggleState.js +13 -0
- package/dist/internal/setKeysState.d.ts +8 -0
- package/dist/internal/setKeysState.js +42 -0
- package/dist/internal/updateNativeKeysState.d.ts +14 -0
- package/dist/internal/updateNativeKeysState.js +58 -0
- package/dist/layouts/createLayout.d.ts +25 -0
- package/dist/layouts/createLayout.js +221 -0
- package/dist/module.d.mts +13 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +40 -0
- package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.d.ts +9 -0
- package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.js +19 -0
- package/dist/runtime/composables/usePointerCoords.d.ts +32 -0
- package/dist/runtime/composables/usePointerCoords.js +17 -0
- package/dist/runtime/composables/useShortcutManagerContextCount.d.ts +14 -0
- package/dist/runtime/composables/useShortcutManagerContextCount.js +61 -0
- package/dist/runtime/composables/useShortcutManagerKeysLayout.d.ts +18 -0
- package/dist/runtime/composables/useShortcutManagerKeysLayout.js +22 -0
- package/dist/runtime/composables/useShortcutManagerVirtualPress.d.ts +6 -0
- package/dist/runtime/composables/useShortcutManagerVirtualPress.js +24 -0
- package/dist/runtime/types.d.ts +10 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/utils/shortcutToId.d.ts +5 -0
- package/dist/runtime/utils/shortcutToId.js +6 -0
- package/dist/types/commands.d.ts +113 -0
- package/dist/types/commands.js +0 -0
- package/dist/types/condition.d.ts +29 -0
- package/dist/types/condition.js +0 -0
- package/dist/types/context.d.ts +18 -0
- package/dist/types/context.js +0 -0
- package/dist/types/enums.d.ts +186 -0
- package/dist/types/enums.js +70 -0
- package/dist/types/general.d.ts +92 -0
- package/dist/types/general.js +0 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +8 -0
- package/dist/types/keys.d.ts +332 -0
- package/dist/types/keys.js +0 -0
- package/dist/types/manager.d.ts +249 -0
- package/dist/types/manager.js +0 -0
- package/dist/types/plugins.d.ts +1 -0
- package/dist/types/plugins.js +0 -0
- package/dist/types/shortcuts.d.ts +144 -0
- package/dist/types/shortcuts.js +0 -0
- package/dist/types/utils.d.ts +1 -0
- package/dist/types/utils.js +0 -0
- package/dist/types.d.mts +3 -0
- package/dist/utils/chainContainsSubset.d.ts +27 -0
- package/dist/utils/chainContainsSubset.js +45 -0
- package/dist/utils/cloneChain.d.ts +2 -0
- package/dist/utils/cloneChain.js +11 -0
- package/dist/utils/cloneKey.d.ts +3 -0
- package/dist/utils/cloneKey.js +26 -0
- package/dist/utils/containsKey.d.ts +7 -0
- package/dist/utils/containsKey.js +4 -0
- package/dist/utils/dedupeKeys.d.ts +9 -0
- package/dist/utils/dedupeKeys.js +9 -0
- package/dist/utils/equalsKey.d.ts +12 -0
- package/dist/utils/equalsKey.js +13 -0
- package/dist/utils/equalsKeys.d.ts +24 -0
- package/dist/utils/equalsKeys.js +15 -0
- package/dist/utils/index.d.ts +14 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/isAnyKey.d.ts +5 -0
- package/dist/utils/isAnyKey.js +5 -0
- package/dist/utils/isMouseKey.d.ts +5 -0
- package/dist/utils/isMouseKey.js +20 -0
- package/dist/utils/isNormalKey.d.ts +5 -0
- package/dist/utils/isNormalKey.js +5 -0
- package/dist/utils/isTriggerKey.d.ts +5 -0
- package/dist/utils/isTriggerKey.js +3 -0
- package/dist/utils/isWheelKey.d.ts +5 -0
- package/dist/utils/isWheelKey.js +11 -0
- package/dist/utils/mapKeys.d.ts +8 -0
- package/dist/utils/mapKeys.js +5 -0
- package/dist/utils/removeKeys.d.ts +7 -0
- package/dist/utils/removeKeys.js +4 -0
- package/package.json +156 -0
- package/src/core/EmulatedEvent.ts +29 -0
- package/src/core/Emulator.ts +185 -0
- package/src/core/ShortcutManagerManager.ts +380 -0
- package/src/core/addCommand.ts +24 -0
- package/src/core/addKey.ts +25 -0
- package/src/core/addShortcut.ts +24 -0
- package/src/core/attach.ts +27 -0
- package/src/core/createCommand.ts +24 -0
- package/src/core/createCommands.ts +45 -0
- package/src/core/createCondition.ts +21 -0
- package/src/core/createContext.ts +14 -0
- package/src/core/createKey.ts +59 -0
- package/src/core/createKeys.ts +68 -0
- package/src/core/createManager.ts +209 -0
- package/src/core/createManagerEventListeners.ts +139 -0
- package/src/core/createManagerOptions.ts +29 -0
- package/src/core/createShortcut.ts +49 -0
- package/src/core/createShortcuts.ts +51 -0
- package/src/core/detach.ts +21 -0
- package/src/core/index.ts +35 -0
- package/src/core/removeCommand.ts +25 -0
- package/src/core/removeKey.ts +25 -0
- package/src/core/removeShortcut.ts +24 -0
- package/src/core/setCommandProp.ts +140 -0
- package/src/core/setCommandsProp.ts +128 -0
- package/src/core/setKeyProp.ts +80 -0
- package/src/core/setKeysProp.ts +205 -0
- package/src/core/setManagerProp.ts +111 -0
- package/src/core/setShortcutProp.ts +89 -0
- package/src/core/setShortcutsProp.ts +124 -0
- package/src/defaults/KeysSorter.ts +55 -0
- package/src/defaults/Stringifier.ts +234 -0
- package/src/defaults/defaultConditionEquals.ts +29 -0
- package/src/defaults/defaultManagerCallback.ts +14 -0
- package/src/helpers/KnownError.ts +13 -0
- package/src/helpers/calculateAndSetPositionAndWidth.ts +30 -0
- package/src/helpers/calculateLayoutSize.ts +22 -0
- package/src/helpers/doesShortcutConflict.ts +72 -0
- package/src/helpers/equalsCommand.ts +18 -0
- package/src/helpers/equalsContext.ts +29 -0
- package/src/helpers/equalsShortcut.ts +34 -0
- package/src/helpers/forceClear.ts +31 -0
- package/src/helpers/forceUpdateNativeKeysState.ts +9 -0
- package/src/helpers/generateKeyShortcutMap.ts +113 -0
- package/src/helpers/getKeyFromEventCode.ts +67 -0
- package/src/helpers/getKeyFromIdOrVariant.ts +33 -0
- package/src/helpers/getKeyboardLayoutMap.ts +13 -0
- package/src/helpers/getLabel.ts +15 -0
- package/src/helpers/getTriggerableShortcut.ts +37 -0
- package/src/helpers/index.ts +30 -0
- package/src/helpers/isValidManager.ts +29 -0
- package/src/helpers/isValidShortcut.ts +20 -0
- package/src/helpers/labelWithEvent.ts +41 -0
- package/src/helpers/labelWithKeyboardMap.ts +37 -0
- package/src/helpers/managerToStorableClone.ts +26 -0
- package/src/helpers/onKeyboardLayoutChange.ts +17 -0
- package/src/helpers/safeSetManagerChain.ts +66 -0
- package/src/helpers/shortcutCanExecuteIn.ts +24 -0
- package/src/helpers/shortcutIsTriggerableBy.ts +15 -0
- package/src/helpers/shortcutSwapChords.ts +240 -0
- package/src/helpers/virtualPress.ts +34 -0
- package/src/helpers/virtualRelease.ts +25 -0
- package/src/helpers/virtualToggle.ts +28 -0
- package/src/internal/addToChain.ts +40 -0
- package/src/internal/areValidKeys.ts +40 -0
- package/src/internal/areValidVariants.ts +59 -0
- package/src/internal/checkTrigger.ts +55 -0
- package/src/internal/checkUntrigger.ts +26 -0
- package/src/internal/cloneLastChord.ts +10 -0
- package/src/internal/containsPossibleToggleChords.ts +91 -0
- package/src/internal/errorTextAdd.ts +18 -0
- package/src/internal/errorTextInUse.ts +10 -0
- package/src/internal/errorTextRemove.ts +10 -0
- package/src/internal/getModifierState.ts +15 -0
- package/src/internal/getPressedKeys.ts +26 -0
- package/src/internal/getPressedModifierKeys.ts +14 -0
- package/src/internal/getPressedNonModifierKeys.ts +19 -0
- package/src/internal/inChain.ts +25 -0
- package/src/internal/isValidChain.ts +42 -0
- package/src/internal/isValidChord.ts +87 -0
- package/src/internal/isValidCommand.ts +35 -0
- package/src/internal/keyOrder.ts +24 -0
- package/src/internal/removeFromChain.ts +46 -0
- package/src/internal/safeSetEmulatedToggleState.ts +23 -0
- package/src/internal/setKeysState.ts +71 -0
- package/src/internal/updateNativeKeysState.ts +84 -0
- package/src/layouts/createLayout.ts +328 -0
- package/src/module.ts +62 -0
- package/src/runtime/composables/useLabeledByKeyboardLayoutMap.ts +28 -0
- package/src/runtime/composables/usePointerCoords.ts +40 -0
- package/src/runtime/composables/useShortcutManagerContextCount.ts +81 -0
- package/src/runtime/composables/useShortcutManagerKeysLayout.ts +42 -0
- package/src/runtime/composables/useShortcutManagerVirtualPress.ts +30 -0
- package/src/runtime/types.ts +10 -0
- package/src/runtime/utils/shortcutToId.ts +14 -0
- package/src/types/commands.ts +148 -0
- package/src/types/condition.ts +35 -0
- package/src/types/context.ts +19 -0
- package/src/types/enums.ts +236 -0
- package/src/types/general.ts +117 -0
- package/src/types/index.ts +10 -0
- package/src/types/keys.ts +385 -0
- package/src/types/manager.ts +374 -0
- package/src/types/plugins.ts +32 -0
- package/src/types/shortcuts.ts +204 -0
- package/src/types/utils.ts +40 -0
- package/src/utils/chainContainsSubset.ts +97 -0
- package/src/utils/cloneChain.ts +13 -0
- package/src/utils/cloneKey.ts +33 -0
- package/src/utils/containsKey.ts +17 -0
- package/src/utils/dedupeKeys.ts +23 -0
- package/src/utils/equalsKey.ts +32 -0
- package/src/utils/equalsKeys.ts +50 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/isAnyKey.ts +12 -0
- package/src/utils/isMouseKey.ts +27 -0
- package/src/utils/isNormalKey.ts +15 -0
- package/src/utils/isTriggerKey.ts +7 -0
- package/src/utils/isWheelKey.ts +18 -0
- package/src/utils/mapKeys.ts +21 -0
- package/src/utils/removeKeys.ts +16 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { multisplice } from "@alanscodelog/utils/multisplice"
|
|
2
|
+
|
|
3
|
+
import { addToChain } from "./addToChain.js"
|
|
4
|
+
import { getModifierState } from "./getModifierState.js"
|
|
5
|
+
import { removeFromChain } from "./removeFromChain.js"
|
|
6
|
+
import { safeSetEmulatedToggleState } from "./safeSetEmulatedToggleState.js"
|
|
7
|
+
|
|
8
|
+
import { setKeyProp } from "../core/setKeyProp.js"
|
|
9
|
+
import { KnownError } from "../helpers/KnownError.js"
|
|
10
|
+
import type { AnyInputEvent, Manager } from "../types/index.js"
|
|
11
|
+
import { SHORTCUT_ERROR } from "../types/index.js"
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Should be used after we attempt to process the event and set key states.
|
|
15
|
+
*
|
|
16
|
+
* This should cause it to only actually change the state if it was changed off-focus.
|
|
17
|
+
*
|
|
18
|
+
* Technically not neccesary with wheel/mouse events, but ordered similarly for consistency.
|
|
19
|
+
*
|
|
20
|
+
* Modifiers need to be added/removed from the chain on changes, but not toggles.
|
|
21
|
+
*
|
|
22
|
+
* Mutates the passed keys array to remove processed keys.
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
export function updateNativeKeysState(
|
|
26
|
+
manager: Manager,
|
|
27
|
+
e: AnyInputEvent,
|
|
28
|
+
keyIds: string[] = []
|
|
29
|
+
): void {
|
|
30
|
+
const s = manager.options.stringifier
|
|
31
|
+
for (const id of manager.keys.nativeToggleKeys) {
|
|
32
|
+
const key = manager.keys.entries[id]
|
|
33
|
+
if (key.toggleOnPressed && key.toggleOffPressed) {
|
|
34
|
+
throw new KnownError(SHORTCUT_ERROR.INCORRECT_TOGGLE_STATE, `Key ${s.stringify(key, manager)} is a toggle key whose on and off versions are both pressed, which is not a valid state.`, { key })
|
|
35
|
+
}
|
|
36
|
+
// this does not guarantee the key code is valid
|
|
37
|
+
// it just returns false even for made up keys
|
|
38
|
+
const modifierState = getModifierState(key, e, manager)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if (modifierState === null) continue
|
|
42
|
+
if (modifierState) {
|
|
43
|
+
if (!key.toggleOnPressed) {
|
|
44
|
+
safeSetEmulatedToggleState(key, true, manager)
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
if (key.toggleOnPressed) {
|
|
48
|
+
safeSetEmulatedToggleState(key, false, manager)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const added: string[] = []
|
|
53
|
+
const removed: string[] = []
|
|
54
|
+
for (const id of manager.keys.nativeModifierKeys) {
|
|
55
|
+
const key = manager.keys.entries[id]
|
|
56
|
+
const modifierState = getModifierState(key, e, manager)
|
|
57
|
+
if (modifierState === null) continue
|
|
58
|
+
if (modifierState) {
|
|
59
|
+
if (!key.pressed) {
|
|
60
|
+
if (setKeyProp(key, "pressed", true, manager).isOk) {
|
|
61
|
+
added.push(id)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
if (key.pressed) {
|
|
66
|
+
if (setKeyProp(key, "pressed", false, manager).isOk) {
|
|
67
|
+
removed.push(id)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (added.length > 0) {
|
|
74
|
+
addToChain(manager, added, e)
|
|
75
|
+
const indexes = keyIds.map(key => added.indexOf(key)).filter(i => i > -1)
|
|
76
|
+
multisplice(keyIds, indexes)
|
|
77
|
+
}
|
|
78
|
+
if (removed.length > 0) {
|
|
79
|
+
removeFromChain(manager, removed, e)
|
|
80
|
+
const indexes = keyIds.map(key => added.indexOf(key)).filter(i => i > -1)
|
|
81
|
+
multisplice(keyIds, indexes)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { calculateAndSetPositionAndSize } from "../helpers/calculateAndSetPositionAndWidth.js"
|
|
2
|
+
import type { RawKey } from "../types/keys.js"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const start = 0
|
|
6
|
+
const mediaKey = { height: 0.5, width: 4 / 3 }
|
|
7
|
+
const setY = <T extends Record<"id", string>>(yVal: number) => (val: T): (T & { y: number }) => {
|
|
8
|
+
(val as any).y = yVal
|
|
9
|
+
return val as any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates the given keyboard layout, assiging the correct sizes and positions to keys.
|
|
14
|
+
*
|
|
15
|
+
* It returns an array of raw keys so that if you're extending {@link Key} you can create them with your extended class (you should override {@link Key.create}).
|
|
16
|
+
*
|
|
17
|
+
* Labels are assigned for most keys in english as a fallback, see {@link labelWithEvent}/{@link labelWithKeyboardMap} for proper labeling during runtime.
|
|
18
|
+
*
|
|
19
|
+
* Currently only supports generating the following layouts: `ansi`, `iso`. Technically the layout returned is a variation of these that includes half height 1.3333u (4u / 3 keys) media keys over the numpad.
|
|
20
|
+
*
|
|
21
|
+
* Pull requests for [standard layouts]([https://www.w3.org/TR/uievents-code) welcomed.
|
|
22
|
+
*
|
|
23
|
+
* You can remove sections using the options. Note that this just removes them and does not do any repositioning. If you only remove the numpad, for example, the media keys will still be placed above it. The idea is to easily allow reducing the size of the created layout to then adjust only a few keys to your liking.
|
|
24
|
+
*
|
|
25
|
+
* Also note the `navigation` section is split into two sections with `navigation` only refering to the 6 `Insert`, `Home`, etc. keys, and `arrowKeys` refering to the arrow keys.
|
|
26
|
+
*
|
|
27
|
+
* This also adds the following classes to some keys: `center-label` for media and arrow keys, and `iso-enter` for the iso enter which requires a different approach to styling (see the demo, it's painful).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export function createLayout<
|
|
31
|
+
TNumpad extends boolean = true,
|
|
32
|
+
TMediaKeys extends boolean = true,
|
|
33
|
+
TFn extends boolean = true,
|
|
34
|
+
TNavigation extends boolean = true,
|
|
35
|
+
TArrowKeys extends boolean = true,
|
|
36
|
+
TNames extends string = "Escape"
|
|
37
|
+
| (
|
|
38
|
+
TFn extends true
|
|
39
|
+
? "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12"
|
|
40
|
+
: never
|
|
41
|
+
)
|
|
42
|
+
| "Backquote" | "Digit1" | "Digit2" | "Digit3" | "Digit4" | "Digit5" | "Digit6" | "Digit7" | "Digit8" | "Digit9" | "Digit0" | "Minus" | "Equal" | "Backspace"
|
|
43
|
+
| "Tab" | "KeyQ" | "KeyW" | "KeyE" | "KeyR" | "KeyT" | "KeyY" | "KeyU" | "KeyI" | "KeyO" | "KeyP" | "BracketLeft" | "BracketRight" | "Backslash"
|
|
44
|
+
| "CapsLock" | "KeyA" | "KeyS" | "KeyD" | "KeyF" | "KeyG" | "KeyH" | "KeyJ" | "KeyK" | "KeyL" | "Semicolon" | "Quote" | "Enter"
|
|
45
|
+
| "VirtualShiftLeft" | "IntlBackslash" | "KeyZ" | "KeyX" | "KeyC" | "KeyV" | "KeyB" | "KeyN" | "KeyM" | "Comma" | "Period" | "Slash" | "VirtualShiftRight"
|
|
46
|
+
| "VirtualControlLeft" | "VirtualMetaLeft" | "VirtualAltLeft" | "Space" | "VirtualAltRight" | "VirtualMetaRight" | "ContextMenu" | "VirtualControlRight"
|
|
47
|
+
|
|
48
|
+
| "PrintScreen"
|
|
49
|
+
| "ScrollLock"
|
|
50
|
+
| "Pause"
|
|
51
|
+
|
|
52
|
+
| (
|
|
53
|
+
TNavigation extends true
|
|
54
|
+
? "Insert" | "Home" | "PageUp"
|
|
55
|
+
: never
|
|
56
|
+
)
|
|
57
|
+
| (
|
|
58
|
+
TArrowKeys extends true
|
|
59
|
+
? "ArrowUp" | "ArrowLeft" | "ArrowDown" | "ArrowRight"
|
|
60
|
+
: never
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
| (
|
|
64
|
+
TMediaKeys extends true
|
|
65
|
+
? "AudioVolumeMute" | "AudioVolumeDown" | "AudioVolumeUp" | "MediaTrackPrevious" | "MediaTrackPause" | "MediaTrackNext"
|
|
66
|
+
: never
|
|
67
|
+
)
|
|
68
|
+
| (
|
|
69
|
+
TNumpad extends true
|
|
70
|
+
? ("NumLock" | "NumpadDivide" | "NumpadMultiply" | "NumpadSubtract"
|
|
71
|
+
| "Numpad7" | "Numpad8" | "Numpad9" | "NumpadAdd"
|
|
72
|
+
| "Numpad4" | "Numpad5" | "Numpad6"
|
|
73
|
+
| "Numpad1" | "Numpad2" | "Numpad3" | "NumpadEnter"
|
|
74
|
+
| "Numpad0" | "NumpadDecimal")
|
|
75
|
+
: never
|
|
76
|
+
)
|
|
77
|
+
>(
|
|
78
|
+
type: "ansi" | "iso" | "" = "ansi",
|
|
79
|
+
{
|
|
80
|
+
numpad = true as any,
|
|
81
|
+
mediaKeys = true as any,
|
|
82
|
+
fn = true as any,
|
|
83
|
+
navigation = true as any,
|
|
84
|
+
arrowKeys = true as any
|
|
85
|
+
}:
|
|
86
|
+
Partial<{
|
|
87
|
+
numpad: TNumpad
|
|
88
|
+
mediaKeys: TMediaKeys
|
|
89
|
+
fn: TFn
|
|
90
|
+
navigation: TNavigation
|
|
91
|
+
arrowKeys: TArrowKeys
|
|
92
|
+
}> = {}
|
|
93
|
+
): RawKey<TNames>[] {
|
|
94
|
+
const keys = [
|
|
95
|
+
...calculateAndSetPositionAndSize([
|
|
96
|
+
{ id: "Escape" as const, label: "Esc" },
|
|
97
|
+
...(fn
|
|
98
|
+
? [
|
|
99
|
+
{ id: "F1" as const, x: 2 },
|
|
100
|
+
{ id: "F2" as const },
|
|
101
|
+
{ id: "F3" as const },
|
|
102
|
+
{ id: "F4" as const },
|
|
103
|
+
{ id: "F5" as const, x: 6.5 },
|
|
104
|
+
{ id: "F6" as const },
|
|
105
|
+
{ id: "F7" as const },
|
|
106
|
+
{ id: "F8" as const },
|
|
107
|
+
{ id: "F9" as const, x: 11 },
|
|
108
|
+
{ id: "F10" as const },
|
|
109
|
+
{ id: "F11" as const },
|
|
110
|
+
{ id: "F12" as const }
|
|
111
|
+
] as const
|
|
112
|
+
: []
|
|
113
|
+
)
|
|
114
|
+
]).map(setY(start + 0)),
|
|
115
|
+
...calculateAndSetPositionAndSize([
|
|
116
|
+
{ id: "Backquote" as const, label: "`" },
|
|
117
|
+
{ id: "Digit1" as const, label: "1" },
|
|
118
|
+
{ id: "Digit2" as const, label: "2" },
|
|
119
|
+
{ id: "Digit3" as const, label: "3" },
|
|
120
|
+
{ id: "Digit4" as const, label: "4" },
|
|
121
|
+
{ id: "Digit5" as const, label: "5" },
|
|
122
|
+
{ id: "Digit6" as const, label: "6" },
|
|
123
|
+
{ id: "Digit7" as const, label: "7" },
|
|
124
|
+
{ id: "Digit8" as const, label: "8" },
|
|
125
|
+
{ id: "Digit9" as const, label: "9" },
|
|
126
|
+
{ id: "Digit0" as const, label: "0" },
|
|
127
|
+
{ id: "Minus" as const, label: "-" },
|
|
128
|
+
{ id: "Equal" as const, label: "=" },
|
|
129
|
+
{ id: "Backspace" as const, width: 2 }
|
|
130
|
+
] as const).map(setY(start + 2)),
|
|
131
|
+
...calculateAndSetPositionAndSize([
|
|
132
|
+
{ id: "Tab" as const, width: 1.5 },
|
|
133
|
+
{ id: "KeyQ" as const, label: "q" },
|
|
134
|
+
{ id: "KeyW" as const, label: "w" },
|
|
135
|
+
{ id: "KeyE" as const, label: "e" },
|
|
136
|
+
{ id: "KeyR" as const, label: "r" },
|
|
137
|
+
{ id: "KeyT" as const, label: "t" },
|
|
138
|
+
{ id: "KeyY" as const, label: "y" },
|
|
139
|
+
{ id: "KeyU" as const, label: "u" },
|
|
140
|
+
{ id: "KeyI" as const, label: "i" },
|
|
141
|
+
{ id: "KeyO" as const, label: "o" },
|
|
142
|
+
{ id: "KeyP" as const, label: "p" },
|
|
143
|
+
{ id: "BracketLeft" as const, label: "[" },
|
|
144
|
+
{ id: "BracketRight" as const, label: "]" },
|
|
145
|
+
type === "ansi"
|
|
146
|
+
? { id: "Backslash" as const, label: "\\", width: 1.5 }
|
|
147
|
+
: type === "iso"
|
|
148
|
+
? { id: "Enter" as const, width: 1.5, height: 2, classes: ["iso-enter"] }
|
|
149
|
+
: {} as never
|
|
150
|
+
] as const).map(setY(start + 3)),
|
|
151
|
+
...calculateAndSetPositionAndSize([
|
|
152
|
+
{ id: "CapsLock" as const, width: 1.75, isToggle: "native" as const },
|
|
153
|
+
{ id: "KeyA" as const, label: "a" },
|
|
154
|
+
{ id: "KeyS" as const, label: "s" },
|
|
155
|
+
{ id: "KeyD" as const, label: "d" },
|
|
156
|
+
{ id: "KeyF" as const, label: "f" },
|
|
157
|
+
{ id: "KeyG" as const, label: "g" },
|
|
158
|
+
{ id: "KeyH" as const, label: "h" },
|
|
159
|
+
{ id: "KeyJ" as const, label: "j" },
|
|
160
|
+
{ id: "KeyK" as const, label: "k" },
|
|
161
|
+
{ id: "KeyL" as const, label: "l" },
|
|
162
|
+
{ id: "Semicolon" as const, label: ";" },
|
|
163
|
+
{ id: "Quote" as const, label: "'" },
|
|
164
|
+
type === "ansi"
|
|
165
|
+
? { id: "Enter" as const, width: 2.25 }
|
|
166
|
+
: type === "iso"
|
|
167
|
+
? { id: "Backslash" as const, label: "#", width: 1 }
|
|
168
|
+
: {} as never
|
|
169
|
+
] as const).map(setY(start + 4)),
|
|
170
|
+
...calculateAndSetPositionAndSize([
|
|
171
|
+
...(type === "ansi"
|
|
172
|
+
? [
|
|
173
|
+
{ id: "VirtualShiftLeft" as const, isModifier: "native" as const, label: "Shift", variants: ["ShiftLeft", "ShiftRight", "Shift"], width: 2.25 }
|
|
174
|
+
]
|
|
175
|
+
: type === "iso"
|
|
176
|
+
? [
|
|
177
|
+
{ id: "VirtualShiftLeft" as const, isModifier: "native" as const, label: "Shift", variants: ["ShiftLeft", "ShiftRight", "Shift"], width: 1.25 },
|
|
178
|
+
{ id: "IntlBackslash" as const, label: "\\", width: 1 }
|
|
179
|
+
]
|
|
180
|
+
: []),
|
|
181
|
+
{ id: "KeyZ" as const, label: "z" },
|
|
182
|
+
{ id: "KeyX" as const, label: "x" },
|
|
183
|
+
{ id: "KeyC" as const, label: "c" },
|
|
184
|
+
{ id: "KeyV" as const, label: "v" },
|
|
185
|
+
{ id: "KeyB" as const, label: "b" },
|
|
186
|
+
{ id: "KeyN" as const, label: "n" },
|
|
187
|
+
{ id: "KeyM" as const, label: "m" },
|
|
188
|
+
{ id: "Comma" as const, label: "," },
|
|
189
|
+
{ id: "Period" as const, label: "." },
|
|
190
|
+
{ id: "Slash" as const, label: "/" },
|
|
191
|
+
{
|
|
192
|
+
id: "VirtualShiftRight" as const,
|
|
193
|
+
isModifier: "native" as const,
|
|
194
|
+
label: "Shift",
|
|
195
|
+
variants: ["ShiftLeft", "ShiftRight", "Shift"],
|
|
196
|
+
width: 2.75
|
|
197
|
+
}
|
|
198
|
+
] as const).map(setY(start + 5)),
|
|
199
|
+
...calculateAndSetPositionAndSize([
|
|
200
|
+
{
|
|
201
|
+
id: "VirtualControlLeft" as const,
|
|
202
|
+
isModifier: "native" as const,
|
|
203
|
+
label: "Ctrl",
|
|
204
|
+
variants: ["ControlLeft", "ControlRight", "Control", "Ctrl"],
|
|
205
|
+
width: 1.25
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "VirtualMetaLeft" as const,
|
|
209
|
+
isModifier: "native" as const,
|
|
210
|
+
label: "Meta",
|
|
211
|
+
variants: ["MetaLeft", "MetaRight", "Meta"],
|
|
212
|
+
width: 1.25
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: "VirtualAltLeft" as const,
|
|
216
|
+
isModifier: "native" as const,
|
|
217
|
+
label: "Alt",
|
|
218
|
+
variants: ["AltLeft", "AltRight", "Alt"],
|
|
219
|
+
width: 1.25
|
|
220
|
+
},
|
|
221
|
+
{ id: "Space" as const, label: "", width: 6.25 },
|
|
222
|
+
{
|
|
223
|
+
id: "VirtualAltRight" as const,
|
|
224
|
+
isModifier: "native" as const,
|
|
225
|
+
label: "Alt",
|
|
226
|
+
variants: ["AltLeft", "AltRight", "Alt"],
|
|
227
|
+
width: 1.25
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
id: "VirtualMetaRight" as const,
|
|
231
|
+
isModifier: "native" as const,
|
|
232
|
+
label: "Meta",
|
|
233
|
+
variants: ["MetaLeft", "MetaRight", "Meta"],
|
|
234
|
+
width: 1.25
|
|
235
|
+
},
|
|
236
|
+
{ id: "ContextMenu" as const, label: "Menu", width: 1.25 },
|
|
237
|
+
{
|
|
238
|
+
id: "VirtualControlRight" as const,
|
|
239
|
+
isModifier: "native" as const,
|
|
240
|
+
label: "Ctrl",
|
|
241
|
+
variants: ["ControlLeft", "ControlRight", "Control", "Ctrl"],
|
|
242
|
+
width: 1.25
|
|
243
|
+
}
|
|
244
|
+
] as const).map(setY(start + 6)),
|
|
245
|
+
...calculateAndSetPositionAndSize([
|
|
246
|
+
{ id: "PrintScreen" as const, label: "PrtScn", x: 15.5 },
|
|
247
|
+
{ id: "ScrollLock" as const, label: "Scroll\nLock", isToggle: "native" as const },
|
|
248
|
+
{ id: "Pause" as const, label: "Pause\nBreak" }
|
|
249
|
+
] as const).map(setY(start)),
|
|
250
|
+
...(navigation
|
|
251
|
+
? [
|
|
252
|
+
...calculateAndSetPositionAndSize([
|
|
253
|
+
{ id: "Insert" as const, x: 15.5 },
|
|
254
|
+
{ id: "Home" as const },
|
|
255
|
+
{ id: "PageUp" as const, label: "Pg\nUp" }
|
|
256
|
+
] as const).map(setY(start + 2)),
|
|
257
|
+
...calculateAndSetPositionAndSize([
|
|
258
|
+
{ id: "Delete" as const, x: 15.5 },
|
|
259
|
+
{ id: "End" as const },
|
|
260
|
+
{ id: "PageDown" as const, label: "Pg\nDown" }
|
|
261
|
+
] as const).map(setY(start + 3))
|
|
262
|
+
]
|
|
263
|
+
: []
|
|
264
|
+
),
|
|
265
|
+
...(arrowKeys
|
|
266
|
+
? [
|
|
267
|
+
...calculateAndSetPositionAndSize([
|
|
268
|
+
{ id: "ArrowUp" as const, label: "▲", x: 16.5, y: start + 5, classes: ["center-label"] }
|
|
269
|
+
]),
|
|
270
|
+
...calculateAndSetPositionAndSize([
|
|
271
|
+
{ id: "ArrowLeft" as const, label: "◄", x: 15.5, classes: ["center-label"] },
|
|
272
|
+
{ id: "ArrowDown" as const, label: "▼", classes: ["center-label"] },
|
|
273
|
+
{ id: "ArrowRight" as const, label: "►", classes: ["center-label"] }
|
|
274
|
+
] as const).map(setY(start + 6))
|
|
275
|
+
]
|
|
276
|
+
: []
|
|
277
|
+
),
|
|
278
|
+
...(
|
|
279
|
+
mediaKeys
|
|
280
|
+
? [
|
|
281
|
+
...calculateAndSetPositionAndSize([
|
|
282
|
+
{ id: "AudioVolumeMute" as const, label: "🔇", x: 19, ...mediaKey, classes: ["center-label"] },
|
|
283
|
+
{ id: "AudioVolumeDown" as const, label: "🔉", ...mediaKey, classes: ["center-label"] },
|
|
284
|
+
{ id: "AudioVolumeUp" as const, label: "🔊", ...mediaKey, classes: ["center-label"] }
|
|
285
|
+
]).map(setY(start)),
|
|
286
|
+
...calculateAndSetPositionAndSize([
|
|
287
|
+
{ id: "MediaTrackPrevious" as const, label: "⏮️", x: 19, ...mediaKey, classes: ["center-label"] },
|
|
288
|
+
{ id: "MediaTrackPause" as const, label: "⏯️", ...mediaKey, classes: ["center-label"] },
|
|
289
|
+
{ id: "MediaTrackNext" as const, label: "⏭️", ...mediaKey, classes: ["center-label"] }
|
|
290
|
+
]).map(setY(start + 0.5))
|
|
291
|
+
]
|
|
292
|
+
: []
|
|
293
|
+
),
|
|
294
|
+
...(numpad
|
|
295
|
+
? [
|
|
296
|
+
...calculateAndSetPositionAndSize([
|
|
297
|
+
{ id: "NumLock" as const, label: "Num\nLock", x: 19, isToggle: "native" as const },
|
|
298
|
+
{ id: "NumpadDivide" as const, label: "/" },
|
|
299
|
+
{ id: "NumpadMultiply" as const, label: "*" },
|
|
300
|
+
{ id: "NumpadSubtract" as const, label: "-" }
|
|
301
|
+
]).map(setY(start + 2)),
|
|
302
|
+
...calculateAndSetPositionAndSize([
|
|
303
|
+
{ id: "Numpad7" as const, label: "7", x: 19 },
|
|
304
|
+
{ id: "Numpad8" as const, label: "8" },
|
|
305
|
+
{ id: "Numpad9" as const, label: "9" },
|
|
306
|
+
{ id: "NumpadAdd" as const, label: "+", height: 2 }
|
|
307
|
+
]).map(setY(start + 3)),
|
|
308
|
+
...calculateAndSetPositionAndSize([
|
|
309
|
+
{ id: "Numpad4" as const, label: "4", x: 19 },
|
|
310
|
+
{ id: "Numpad5" as const, label: "5" },
|
|
311
|
+
{ id: "Numpad6" as const, label: "6" }
|
|
312
|
+
]).map(setY(start + 4)),
|
|
313
|
+
...calculateAndSetPositionAndSize([
|
|
314
|
+
{ id: "Numpad1" as const, label: "1", x: 19 },
|
|
315
|
+
{ id: "Numpad2" as const, label: "2" },
|
|
316
|
+
{ id: "Numpad3" as const, label: "3" },
|
|
317
|
+
{ id: "NumpadEnter" as const, label: "+", height: 2 }
|
|
318
|
+
]).map(setY(start + 5)),
|
|
319
|
+
...calculateAndSetPositionAndSize([
|
|
320
|
+
{ id: "Numpad0" as const, label: "0", x: 19, width: 2 },
|
|
321
|
+
{ id: "NumpadDecimal" as const, label: "." }
|
|
322
|
+
]).map(setY(start + 6))
|
|
323
|
+
]
|
|
324
|
+
: []
|
|
325
|
+
)
|
|
326
|
+
] satisfies RawKey[]
|
|
327
|
+
return keys as any
|
|
328
|
+
}
|
package/src/module.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addImportsDir,
|
|
3
|
+
addTypeTemplate,
|
|
4
|
+
createResolver,
|
|
5
|
+
defineNuxtModule
|
|
6
|
+
} from "@nuxt/kit"
|
|
7
|
+
|
|
8
|
+
import pkg from "../package.json" with { type: "json" }
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const { resolve } = createResolver(import.meta.url)
|
|
12
|
+
|
|
13
|
+
declare module "@nuxt/schema" {
|
|
14
|
+
interface PublicRuntimeConfig {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
16
|
+
witchcraftSpellcraft: {}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ModuleOptions {
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default defineNuxtModule<ModuleOptions>({
|
|
25
|
+
meta: {
|
|
26
|
+
name: "witchcraftSpellcraft",
|
|
27
|
+
configKey: "witchcraftSpellcraft"
|
|
28
|
+
},
|
|
29
|
+
defaults: {
|
|
30
|
+
},
|
|
31
|
+
moduleDependencies: {
|
|
32
|
+
"@witchcraft/ui/nuxt": {
|
|
33
|
+
version: pkg.dependencies["@witchcraft/ui"]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
async setup(_options, nuxt) {
|
|
37
|
+
// nuxt.options.runtimeConfig.public.witchcraftSpellcraft = defu(
|
|
38
|
+
// nuxt.options.runtimeConfig.public.witchcraftSpellcraft,
|
|
39
|
+
// {
|
|
40
|
+
// }
|
|
41
|
+
// )
|
|
42
|
+
addTypeTemplate({
|
|
43
|
+
filename: "types/witchcraft-spellcraft.d.ts",
|
|
44
|
+
|
|
45
|
+
getContents: () => `
|
|
46
|
+
import { type NavigatorWKeyboard } from "./src/types/general.ts"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
declare global {
|
|
50
|
+
interface Navigator {
|
|
51
|
+
keyboard: NavigatorWKeyboard["keyboard"]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
addImportsDir(resolve("runtime/composables"))
|
|
58
|
+
addImportsDir(resolve("runtime/utils"))
|
|
59
|
+
|
|
60
|
+
nuxt.options.alias["#witchcraft-spellcraft"] = resolve("runtime")
|
|
61
|
+
}
|
|
62
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Ref, ref } from "vue"
|
|
2
|
+
|
|
3
|
+
import { getKeyboardLayoutMap } from "../../helpers/getKeyboardLayoutMap.js"
|
|
4
|
+
import { labelWithKeyboardMap } from "../../helpers/labelWithKeyboardMap.js"
|
|
5
|
+
import { onKeyboardLayoutChange } from "../../helpers/onKeyboardLayoutChange.js"
|
|
6
|
+
import type { Manager } from "../../types/manager.js"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sets up {@link getKeyboardLayoutMap} and {@link onKeyboardLayoutChange} to use {@link labelWithKeyboardMap}.
|
|
10
|
+
*
|
|
11
|
+
* Returns a ref of the latest key labels to have been set.
|
|
12
|
+
*/
|
|
13
|
+
export function useLabeledByKeyboardLayoutMap(manager: Manager): Ref<ReturnType<typeof labelWithKeyboardMap> | undefined> {
|
|
14
|
+
const labeledByMap = ref<ReturnType<typeof labelWithKeyboardMap>>()
|
|
15
|
+
|
|
16
|
+
void getKeyboardLayoutMap().then(map => {
|
|
17
|
+
if (map) {
|
|
18
|
+
labeledByMap.value = labelWithKeyboardMap(manager, { map })
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
void onKeyboardLayoutChange(async () => {
|
|
22
|
+
const map = await getKeyboardLayoutMap()
|
|
23
|
+
if (map) {
|
|
24
|
+
labeledByMap.value = labelWithKeyboardMap(manager, { map })
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
return labeledByMap
|
|
28
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { computed, type ComputedRef, reactive } from "vue"
|
|
2
|
+
/**
|
|
3
|
+
* Returns a set of coordinates that includes an initial offset.
|
|
4
|
+
*
|
|
5
|
+
* For use with drag or similar events.
|
|
6
|
+
*
|
|
7
|
+
* `setInitialOffset` should be called at drag start.
|
|
8
|
+
*
|
|
9
|
+
* `setPointerCoords` can then be called on drag move.
|
|
10
|
+
*
|
|
11
|
+
* And `coords` will reflect the coordinates of the event + the initial offset.
|
|
12
|
+
*
|
|
13
|
+
* This can then be used to position an element and it won't jump, it will stay grabbed from where the user initially grabbed it.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export const usePointerCoords = (): {
|
|
18
|
+
pointerCoords: { x: number, y: number }
|
|
19
|
+
coords: ComputedRef<{ x: number, y: number }>
|
|
20
|
+
setPointerCoords: (e: { clientX: number, clientY: number }) => void
|
|
21
|
+
setInitialPointerOffset: (e: { clientX: number, clientY: number }, el: HTMLElement) => void
|
|
22
|
+
} => {
|
|
23
|
+
const pointerCoords = reactive<{ x: number, y: number }>({ x: 0, y: 0 })
|
|
24
|
+
const offsetCoords = reactive<{ x: number, y: number }>({ x: 0, y: 0 })
|
|
25
|
+
const coords = computed(() => ({ x: pointerCoords.x - offsetCoords.x, y: pointerCoords.y - offsetCoords.y }))
|
|
26
|
+
|
|
27
|
+
const setPointerCoords = (e: { clientX: number, clientY: number }): void => {
|
|
28
|
+
pointerCoords.x = e.clientX
|
|
29
|
+
pointerCoords.y = e.clientY
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const setInitialPointerOffset = (e: { clientX: number, clientY: number }, el: HTMLElement): void => {
|
|
33
|
+
setPointerCoords(e)
|
|
34
|
+
const clientRect = el.getBoundingClientRect()
|
|
35
|
+
offsetCoords.x = pointerCoords.x - clientRect.x
|
|
36
|
+
offsetCoords.y = pointerCoords.y - clientRect.y
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return { pointerCoords, coords, setPointerCoords, setInitialPointerOffset }
|
|
40
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { keys } from "@alanscodelog/utils/keys"
|
|
2
|
+
import { unreachable } from "@alanscodelog/utils/unreachable"
|
|
3
|
+
import { extractTokens } from "@witchcraft/expressit/utils/extractTokens"
|
|
4
|
+
import { type ComputedRef, type Ref, watch } from "vue"
|
|
5
|
+
|
|
6
|
+
import type { Manager } from "../../types/manager.js"
|
|
7
|
+
import type { ContextInfo } from "../types.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Updates the count of the ctx variables depending on how many shortcuts are using the variable. Requires shortcuts use the expressit library to set the ast property of conditions.
|
|
11
|
+
*
|
|
12
|
+
* Useful to know if we can delete a ctx.
|
|
13
|
+
*/
|
|
14
|
+
export function useShortcutManagerContextCount(manager: Ref<Manager> | ComputedRef<Manager>, context: Ref<ContextInfo>): {
|
|
15
|
+
addContext(ctx: string): void
|
|
16
|
+
removeContext(ctx: string): void
|
|
17
|
+
activateContext(ctx: string): void
|
|
18
|
+
deactivateContext(ctx: string): void
|
|
19
|
+
} {
|
|
20
|
+
watch(() => manager.value.shortcuts.entries, newShortcuts => {
|
|
21
|
+
const rc: Record<string, number> = {}
|
|
22
|
+
for (const shortcut of newShortcuts) {
|
|
23
|
+
if (!("ast" in shortcut.condition)) continue
|
|
24
|
+
const c = shortcut.condition.ast
|
|
25
|
+
if (c) {
|
|
26
|
+
const tokens = extractTokens(c as any) // todo
|
|
27
|
+
const seen: string[] = []
|
|
28
|
+
for (const token of tokens) {
|
|
29
|
+
if (token.type === "VALUE") {
|
|
30
|
+
if (seen.includes(token.value)) continue
|
|
31
|
+
seen.push(token.value)
|
|
32
|
+
rc[token.value] = rc[token.value] ? rc[token.value] + 1 : 1
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const ctx of keys(context.value)) {
|
|
38
|
+
context.value.count[ctx] = rc[ctx] ?? 0
|
|
39
|
+
}
|
|
40
|
+
for (const ctx of keys(rc)) {
|
|
41
|
+
if (!context.value.isActive[ctx]) {
|
|
42
|
+
context.value.isActive[ctx] = false
|
|
43
|
+
context.value.count[ctx] = rc[ctx]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}, { deep: true, immediate: true })
|
|
47
|
+
// we're using unreachable, because the checks should already be in the ui
|
|
48
|
+
|
|
49
|
+
function addContext(ctx: string): void {
|
|
50
|
+
if (!context.value.isActive[ctx]) {
|
|
51
|
+
context.value.isActive[ctx] = true
|
|
52
|
+
context.value.count[ctx] = 0
|
|
53
|
+
} else {
|
|
54
|
+
unreachable()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function removeContext(ctx: string): void {
|
|
59
|
+
if (context.value.count[ctx] === 0) {
|
|
60
|
+
delete context.value.isActive[ctx]
|
|
61
|
+
delete context.value.count[ctx]
|
|
62
|
+
} else {
|
|
63
|
+
unreachable()
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function activateContext(ctx: string): void {
|
|
68
|
+
context.value.isActive[ctx] ||= true
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function deactivateContext(ctx: string): void {
|
|
72
|
+
context.value.isActive[ctx] &&= false
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
addContext,
|
|
77
|
+
removeContext,
|
|
78
|
+
activateContext,
|
|
79
|
+
deactivateContext
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useGlobalResizeObserver } from "@witchcraft/ui/composables/useGlobalResizeObserver"
|
|
2
|
+
import { computed, reactive, type Ref, ref, watch } from "vue"
|
|
3
|
+
|
|
4
|
+
import type { Keys } from "../../types/keys.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Watches Keys.layout.x/y and listens to resize changes on the element containing the keys to update what the pixel height of the element should be and what the pixel keyWidth.
|
|
8
|
+
*
|
|
9
|
+
* While it also returns the width and the ratio, you should not set the element to them.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export const useShortcutManagerKeysLayout = (keys: Keys, keyboardEl: Ref<HTMLElement | null>): {
|
|
13
|
+
width: Ref<number>
|
|
14
|
+
height: Ref<number>
|
|
15
|
+
ratio: Ref<number>
|
|
16
|
+
keyWidth: Ref<number>
|
|
17
|
+
layout: {
|
|
18
|
+
x: number
|
|
19
|
+
y: number
|
|
20
|
+
}
|
|
21
|
+
} => {
|
|
22
|
+
const layout = reactive({ x: keys.layout.x, y: keys.layout.y })
|
|
23
|
+
watch([() => keys.layout.x, () => keys.layout.y], ([x, y]) => {
|
|
24
|
+
layout.x = x
|
|
25
|
+
layout.y = y
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const width = ref(0)
|
|
29
|
+
const keyWidth = computed(() => {
|
|
30
|
+
const val = width.value / layout.x
|
|
31
|
+
return Number.isNaN(val) ? 1 : val
|
|
32
|
+
})
|
|
33
|
+
const ratio = computed(() => layout.x / layout.y)
|
|
34
|
+
const height = computed(() => width.value / ratio.value)
|
|
35
|
+
useGlobalResizeObserver(keyboardEl, function updateSize() {
|
|
36
|
+
if (keyboardEl.value) {
|
|
37
|
+
width.value = Math.max(keyboardEl.value.offsetWidth, 1000)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
return { width, height, ratio, keyWidth, layout }
|
|
41
|
+
}
|
|
42
|
+
|