ENH: Add CommonKey.IsPressed and CommonKey.GetModifiers

Co-authored-by: Jean-Baptiste Emmanuel Zorg <zorgjeanbe@proton.me>
This commit is contained in:
bananarama92 2024-11-14 18:53:43 +01:00
parent c8ccc6fe42
commit 3ce0118d07
No known key found for this signature in database
GPG key ID: ECBC951D6255A50F
22 changed files with 115 additions and 82 deletions
BondageClub
Screens
Character
BackgroundSelection
FriendList
Login
Relog
MiniGame
ChestLockpick
ClubCard
DojoStruggle
Online
Room
Pandora
Platform
PlatformDialog
Poker
Stable
Scripts

View file

@ -192,7 +192,7 @@ function BackgroundSelectionClick() {
* @type {KeyboardEventListener}
*/
function BackgroundSelectionKeyDown(event) {
if (event.key === "Enter" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Enter")) {
BackgroundSelectionExit(true);
return true;
}

View file

@ -317,16 +317,15 @@ function FriendListClick() {
function FriendListKeyDown(event) {
const beepTextArea = /** @type {HTMLTextAreaElement} */(document.getElementById(FriendListIDs.beepTextArea));
const beepTextAreaHasFocus = beepTextArea && document.activeElement === beepTextArea;
const modifiers = CommonGetKeyModifiers(event);
if (FriendListBeepTarget !== -1 || beepTextArea) {
if (event.key === 'Escape' && !modifiers) {
if (CommonKey.IsPressed(event, "Escape")) {
FriendListBeepMenuClose();
return true;
}
}
if (beepTextAreaHasFocus) {
if (event.key === 'Enter' && CommonArraysEqual(modifiers, ["Control"])) {
if (event.key === 'Enter' && CommonKey.IsPressed(event, "Enter", CommonKey.CTRL)) {
FriendListBeepMenuSend();
return true;
}

View file

@ -101,7 +101,7 @@ var LoginEventListeners = {
* @type {(this: HTMLInputElement, ev: KeyboardEvent) => void}
*/
_KeyDownInputName: function _KeyDownInputName(ev) {
if (!CommonGetKeyModifiers(ev) && ev.key === "Enter") {
if (CommonKey.IsPressed(ev, "Enter")) {
document.getElementById("InputPassword")?.focus();
ev.stopPropagation();
}
@ -112,7 +112,7 @@ var LoginEventListeners = {
* @type {(this: HTMLInputElement, ev: KeyboardEvent) => void}
*/
_KeyDownInputPassword: function _KeyDownInputPassword(ev) {
if (!CommonGetKeyModifiers(ev) && ev.key === "Enter") {
if (CommonKey.IsPressed(ev, "Enter")) {
LoginDoLogin();
ev.stopPropagation();
}
@ -1036,7 +1036,7 @@ function LoginClick() {
* @type {KeyboardEventListener}
*/
function LoginKeyDown(ev) {
if (!CommonGetKeyModifiers(ev) && ev.key === "Enter") {
if (CommonKey.IsPressed(ev, "Enter")) {
LoginDoLogin();
return true;
}

View file

@ -75,7 +75,7 @@ function RelogClick() {
* @type {KeyboardEventListener}
*/
function RelogKeyDown(event) {
if (event.key === "Enter" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Enter")) {
// On an "enter" key press, try to relog the player
RelogSend();
return true;

View file

@ -109,7 +109,7 @@ function ChestLockpickKeyDown(event) {
}
// The Space bar is like a click
if (event.code === "Space" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Space")) {
ChestLockpickMouseDown();
return true;
}

View file

@ -4126,7 +4126,7 @@ function ClubCardClick() {
function ClubCardKeyDown(event) {
if (document.activeElement.id !== "CCChat") return false;
if (event.key === "Enter" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Enter")) {
let Value = ElementValue("CCChat").trim();
if (Value != "") {
const Msg = CharacterNickname(Player) + ": " + Value;

View file

@ -134,7 +134,7 @@ function DojoStruggleMouseDown() {
function DojoStruggleKeyDown(event) {
if (event.repeat) return false;
if (!MiniGameEnded && event.code === "Space" && !CommonGetKeyModifiers(event)) {
if (!MiniGameEnded && CommonKey.IsPressed(event, "Space")) {
if (!MiniGameStarted)
MiniGameStarted = true;
else

View file

@ -222,7 +222,7 @@ function ChatCreateClick() {
function ChatCreateKeyDown(event) {
if (event.repeat) return false;
if (event.key === "Enter" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Enter")) {
ChatCreateRoom();
return true;
}

View file

@ -2702,22 +2702,21 @@ function ChatRoomLeave(clearCharacters = false) {
* @type {KeyboardEventListener}
*/
function ChatRoomCommonKeyDown(event) {
const modifiers = CommonGetKeyModifiers(event);
if (event.key === "Escape" && !modifiers) {
if (CommonKey.IsPressed(event, "Escape")) {
// Escape toggles between main view and chat
ElementScrollToEnd("TextAreaChatLog");
ElementFocus("InputChat");
return true;
} else if (event.key === "k" && CommonArraysEqual(modifiers, ["Alt"])) {
} else if (CommonKey.IsPressed(event, "k", CommonKey.Alt)) {
if (!event.repeat) ChatRoomToggleKneel();
return true;
} else if (event.key === "i" && CommonArraysEqual(modifiers, ["Alt"])) {
} else if (CommonKey.IsPressed(event, "i", CommonKey.Alt)) {
ChatRoomOpenInformationScreen();
return true;
} else if (event.key === "b" && CommonArraysEqual(modifiers, ["Alt"])) {
} else if (CommonKey.IsPressed(event, "b", CommonKey.Alt)) {
ChatRoomOpenWardrobeScreen();
return true;
} else if (event.key === "h" && CommonArraysEqual(modifiers, ["Alt"])) {
} else if (CommonKey.IsPressed(event, "h", CommonKey.Alt)) {
ChatRoomOpenAdminScreen();
return true;
}
@ -2731,7 +2730,7 @@ function ChatRoomCommonKeyDown(event) {
function ChatRoomKeyDown(event) {
const inputChat = /** @type {HTMLTextAreaElement} */(document.getElementById("InputChat"));
const chatHasFocus = inputChat && document.activeElement === inputChat;
const modifiers = CommonGetKeyModifiers(event);
const modifiers = CommonKey.GetModifiers(event);
if (chatHasFocus) {
// Why are these room-level event listeners!?
@ -2765,7 +2764,7 @@ function ChatRoomKeyDown(event) {
return true;
}
if (event.key === "Escape" && CommonArraysEqual(modifiers, ["Shift"])) {
if (CommonKey.IsPressed(event, "Escape", CommonKey.Shift)) {
// Try to leave the room on Shift-Escape
ChatRoomAttemptLeave();
}
@ -2809,11 +2808,10 @@ function ChatRoomKeyDown(event) {
}
}
// Move focus to the chat
if (
(event.key.length === 1 || event.key === "Enter")
&& !(event.altKey || event.metaKey || (event.ctrlKey && event.key !== "v"))
) {
if (CommonKey.IsPressed(event, "v", CommonKey.CTRL)) {
return false;
} else if ((event.key.length === 1 || event.key === "Enter") && !modifiers) {
// Move focus to the chat
ElementFocus("InputChat");
// We have to lie here so that the first keystroke without
// focus still goes through, but we want to eat Enter so

View file

@ -1527,36 +1527,43 @@ function ChatRoomMapViewKeyDown(event) {
// Nothing to do if a character dialog is open
if (CurrentCharacter != null) return false;
// ENTER to go back to the chat box
const modifiers = CommonGetKeyModifiers(event);
if (event.key === "z" && CommonArraysEqual(modifiers, ["Control"])) {
if (ChatRoomPlayerIsAdmin()) ChatRoomMapViewUndo();
return true;
} else if (modifiers) {
return false;
} else if (event.key === "Enter") {
ElementFocus("InputChat");
return true;
} else if ((event.key === "-") || (event.key === "_")) {
if (ChatRoomMapViewPerceptionRange > ChatRoomMapViewPerceptionRangeMin) ChatRoomMapViewPerceptionRange--;
return true;
} else if ((event.key === "+") || (event.key === "=")) {
if (ChatRoomMapViewPerceptionRange < ChatRoomMapViewPerceptionRangeMax) ChatRoomMapViewPerceptionRange++;
return true;
} else if (CommonKeyMove(event) === "u") {
ChatRoomMapViewMove("North");
return true;
} else if (CommonKeyMove(event) === "l") {
ChatRoomMapViewMove("West");
return true;
} else if (CommonKeyMove(event) === "d") {
ChatRoomMapViewMove("South");
return true;
} else if (CommonKeyMove(event) === "r") {
ChatRoomMapViewMove("East");
return true;
const modifiers = CommonKey.GetModifiers(event);
switch (event.key) {
case "Enter":
ElementFocus("InputChat");
return true;
case "-":
case "_":
if (ChatRoomMapViewPerceptionRange > ChatRoomMapViewPerceptionRangeMin) ChatRoomMapViewPerceptionRange--;
return true;
case "+":
case "=":
if (ChatRoomMapViewPerceptionRange < ChatRoomMapViewPerceptionRangeMax) ChatRoomMapViewPerceptionRange++;
return true;
case "z":
if (modifiers === CommonKey.CTRL) {
if (ChatRoomPlayerIsAdmin()) ChatRoomMapViewUndo();
return true;
}
return false;
}
switch (CommonKeyMove(event)) {
case "u":
ChatRoomMapViewMove("North");
return true;
case "l":
ChatRoomMapViewMove("West");
return true;
case "d":
ChatRoomMapViewMove("South");
return true;
case "r":
ChatRoomMapViewMove("East");
return true;
default:
return false;
}
return false;
}
/**

View file

@ -406,7 +406,7 @@ function ChatSearchLoadLanguageAndFilterTerms() {
function ChatSearchKeyDown(event) {
if (event.repeat) return false;
if (event.key === "Enter" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Enter")) {
if (ChatSearchMode == "") {
ChatSearchQuery();
} else {

View file

@ -317,7 +317,7 @@ function PandoraKeyDown (event) {
/** @type {"North" | "South" | "East" | "West" | undefined} */
let dir;
const movingAllowed = PandoraCurrentRoom.Character.every (i => i.AllowMove == null || i.AllowMove);
if (movingAllowed && PandoraMode == "" && !CommonGetKeyModifiers(event)) {
if (movingAllowed && PandoraMode == "" && !CommonKey.GetModifiers(event)) {
switch (CommonKeyMove (event, true)) {
case 'u':
dir = "North";

View file

@ -3591,7 +3591,7 @@ function PlatformEventKeyDown(Code) {
* @returns {boolean} - TRUE if we handled the key pressed
*/
function PlatformKeyDown(e) {
if (CommonGetKeyModifiers(e)) {
if (CommonKey.GetModifiers(e)) {
return false;
}
PlatformEventKeyDown(e.code);

View file

@ -5446,7 +5446,7 @@ function PlatformDialogProcess() {
* @type {KeyboardEventListener}
*/
function PlatformDialogKeyDown(event) {
if (CommonGetKeyModifiers(event)) {
if (CommonKey.GetModifiers(event)) {
return false;
} else if (event.code === "Space" || event.code === "Enter" || event.code === "KeyJ" || event.code === "KeyK" || event.code === "KeyL") {
PlatformDialogProcess();

View file

@ -607,7 +607,7 @@ function PokerClick() {
* @type {KeyboardEventListener}
*/
function PokerKeyDown(event) {
if (event.repeat || CommonGetKeyModifiers(event)) return false;
if (event.repeat || CommonKey.GetModifiers(event)) return false;
let modeCheck = ["DEAL", "FLOP", "TURN", "RIVER"].includes(PokerMode);
let handSize = PokerPlayer[0].Hand.length;

View file

@ -1063,7 +1063,7 @@ function StableGenericProgressEnd() {
/** @type {KeyboardEventListener} */
function StableKeyDown(event) {
if (event.repeat || CommonGetKeyModifiers(event)) return false;
if (event.repeat || CommonKey.GetModifiers(event)) return false;
if (StableProgress >= 0 && (CommonKeyMove(event) === "l" || CommonKeyMove(event) === "r")) {
StableGenericRun((StableProgressLastKeyPress == event.code));

View file

@ -1436,7 +1436,9 @@ function CommonJSONParse(data) {
* @returns {"u"|"d"|"l"|"r"|undefined}
*/
function CommonKeyMove(event, allowArrowKeys = true) {
if (event.code === "KeyW" || allowArrowKeys && event.code === "ArrowUp") {
if (CommonKey.GetModifiers(event)) {
return undefined;
} else if (event.code === "KeyW" || allowArrowKeys && event.code === "ArrowUp") {
return "u";
} else if (event.code === "KeyA" || allowArrowKeys && event.code === "ArrowLeft") {
return "l";
@ -1566,20 +1568,47 @@ function CommonVariableContainer(defaults, extraVars=null, resetCallbacks=null)
}
/**
* Return a list of all active key modifiers, or `null` if none are active
* @param {KeyboardEvent} event - The keyboard event to-be examined for modifiers
* @returns {null | ("Alt" | "Control" | "Meta" | "Shift")[]} - A (length >=1) list of keyboard modifiers or `null` if none are present
* Namespace with helper functions for validating key presses.
* @namespace
*/
function CommonGetKeyModifiers(event) {
if (!event) {
return null;
}
var CommonKey = /** @type {const} */({
/** Bitmask component for the {@link KeyboardEvent.altKey} modifier */
ALT: 1,
/** Bitmask component for the {@link KeyboardEvent.ctrlKey} modifier */
CTRL: 2,
/** Bitmask component for the {@link KeyboardEvent.metaKey} modifier */
META: 4,
/** Bitmask component for the {@link KeyboardEvent.shiftKey} modifier */
SHIFT: 8,
const ret = /** @type {const} */([
event.altKey ? "Alt" : undefined,
event.ctrlKey ? "Control" : undefined,
event.metaKey ? "Meta" : undefined,
event.shiftKey ? "Shift" : undefined,
]).filter(Boolean);
return ret.length > 0 ? ret : null;
}
/**
* Check whether the expected key and all its modifiers were pressed
* @example
* // `Enter` without modifiers
* CommonKey(event, "Enter");
* // `Enter` with the `Ctrl` and `Shift` modifiers
* CommonKey(event, "Enter", CommonKey.SHIFT | CommonKey.CTRL);
* @param {KeyboardEvent} event - The keyboard event in question
* @param {string} key - The expected key (see {@link KeyboardEvent.key})
* @param {null | number} modifiers - An optional bit mask of all expected modifiers (see examples)
* @returns {boolean} - Whether the expected key and all its modifiers were pressed
*/
IsPressed: function IsPressed(event, key, modifiers=null) {
modifiers ??= 0;
return event.key === key && modifiers === CommonKey.GetModifiers(event);
},
/**
* Return a bit mask with all modifiers in the passed keyboard event
* @param {KeyboardEvent} event - The keyboard event in question
* @returns {number} - The bitmask of keyboard modifiers
*/
GetModifiers: function GetModifiers(event) {
return [
event.altKey ? CommonKey.ALT : undefined,
event.ctrlKey ? CommonKey.CTRL : undefined,
event.metaKey ? CommonKey.META : undefined,
event.shiftKey ? CommonKey.SHIFT : undefined,
].filter(Boolean).reduce((sum, bit) => sum | bit, 0);
},
});

View file

@ -3673,7 +3673,7 @@ function DialogKeyDown(event) {
if (CurrentCharacter) {
if (StruggleKeyDown(event)) {
return true;
} else if (event.key === "Escape" && !CommonGetKeyModifiers(event)) {
} else if (CommonKey.IsPressed(event, "Escape")) {
DialogMenuBack();
return true;
}

View file

@ -834,7 +834,7 @@ var ElementButton = {
* @type {(this: HTMLButtonElement, ev: KeyboardEvent) => Promise<void>}
*/
_KeyDown: async function _KeyDown(ev) {
if (CommonGetKeyModifiers(ev)) {
if (CommonKey.GetModifiers(ev)) {
return;
}
switch (ev.key) {
@ -1004,7 +1004,7 @@ var ElementButton = {
* @param {KeyboardEvent} ev
*/
_KeyDownRadio: function _KeyDownRadio(ev) {
if (CommonGetKeyModifiers(ev)) {
if (CommonKey.GetModifiers(ev)) {
return;
}

View file

@ -181,7 +181,7 @@ function GameKeyDown(event) {
break handleKeyDown;
}
if (event.key == "Escape" && !CommonGetKeyModifiers(event)) {
if (CommonKey.IsPressed(event, "Escape")) {
if (document.activeElement instanceof HTMLElement && !(document.activeElement === document.body || document.activeElement.id === "MainCanvas")) {
document.activeElement.blur();
handled = true;

View file

@ -66,7 +66,7 @@ function MiniGameRunning() {
* @returns {boolean} - TRUE if C and cheats are allowed
*/
function MiniGameCheatKeyDown(event) {
if (event.repeat || CommonGetKeyModifiers(event)) return false;
if (event.repeat || CommonKey.GetModifiers(event)) return false;
if (MiniGameCheatAvailable && (event.key === "c" || event.key === "C")) {
MiniGameCheatAvailable = false;

View file

@ -243,7 +243,7 @@ function StruggleAllowLoosen() {
* @type {KeyboardEventListener}
*/
function StruggleKeyDown(event) {
if (event.repeat || CommonGetKeyModifiers(event)) return false;
if (event.repeat || CommonKey.GetModifiers(event)) return false;
if (!StruggleMinigameIsRunning()) return false;