Menus/Virtual Keyboard: cache cvar string for duration of typing

This avoids calling cvar callbacks after every key press.
This commit is contained in:
James R 2023-12-28 05:53:59 -08:00
parent 172951410b
commit 0ef1abcf3a
4 changed files with 36 additions and 37 deletions

View file

@ -542,6 +542,8 @@ extern struct menutyping_s
boolean keyboardcapslock;
boolean keyboardshift;
char cache[MAXSTRINGLENGTH]; // cached string
} menutyping;
// While typing, we'll have a fade strongly darken the screen to overlay the typing menu instead
@ -666,6 +668,7 @@ void M_Init(void);
void M_PlayMenuJam(void);
void M_OpenVirtualKeyboard(boolean gamepad);
void M_MenuTypingInput(INT32 key);
void M_QuitResponse(INT32 ch);

View file

@ -430,8 +430,6 @@ static void M_DrawMenuTyping(void)
INT32 x, y;
consvar_t *cv = currentMenu->menuitems[itemOn].itemaction.cvar;
char buf[8]; // We write there to use drawstring for convenience.
V_DrawFadeScreen(31, (menutyping.menutypingfade+1)/2);
@ -462,12 +460,12 @@ static void M_DrawMenuTyping(void)
V_DrawFill(x + 4, y + 4 + 5, 1, 8+6, 121);
V_DrawFill(x + 5 + boxwidth - 8, y + 4 + 5, 1, 8+6, 121);
V_DrawString(x + 8, y + 12, 0, cv->string);
V_DrawString(x + 8, y + 12, 0, menutyping.cache);
if (skullAnimCounter < 4
&& menutyping.menutypingclose == false
&& menutyping.menutypingfade == (menutyping.keyboardtyping ? 9 : 18))
{
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12 + 1, '_', false);
V_DrawCharacter(x + 8 + V_StringWidth(menutyping.cache, 0), y + 12 + 1, '_', false);
}
const INT32 buttonwidth = ((boxwidth + 1)/NUMVIRTUALKEYSINROW);

View file

@ -972,9 +972,7 @@ static void M_HandleMenuInput(void)
// If we're hovering over a IT_CV_STRING option, pressing A/X opens the typing submenu
if (M_MenuConfirmPressed(pid))
{
menutyping.keyboardtyping = thisMenuKey != -1 ? true : false; // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller.
menutyping.active = true;
menutyping.menutypingclose = false;
M_OpenVirtualKeyboard(thisMenuKey == -1); // If we entered this menu by pressing a menu Key, default to keyboard typing, otherwise use controller.
return;
}

View file

@ -38,8 +38,6 @@ typedef enum
boolean M_ChangeStringCvar(INT32 choice)
{
consvar_t *cv = currentMenu->menuitems[itemOn].itemaction.cvar;
char buf[MAXSTRINGLENGTH];
size_t len;
cvarcopypastemode_t copypastemode = CVCPM_NONE;
@ -86,7 +84,7 @@ boolean M_ChangeStringCvar(INT32 choice)
if (copypastemode != CVCPM_NONE)
{
len = strlen(cv->string);
len = strlen(menutyping.cache);
if (copypastemode == CVCPM_PASTE)
{
@ -95,12 +93,7 @@ boolean M_ChangeStringCvar(INT32 choice)
;
else if (len < MAXSTRINGLENGTH - 1)
{
M_Memcpy(buf, cv->string, len);
buf[len] = 0;
strncat(buf, paste, (MAXSTRINGLENGTH - 1) - len);
CV_Set(cv, buf);
strlcat(menutyping.cache, paste, MAXSTRINGLENGTH);
S_StartSound(NULL, sfx_s3k5b); // Tails
}
@ -109,12 +102,12 @@ boolean M_ChangeStringCvar(INT32 choice)
|| copypastemode == CVCPM_CUT)*/
)
{
I_ClipboardCopy(cv->string, len);
I_ClipboardCopy(menutyping.cache, len);
if (copypastemode == CVCPM_CUT)
{
// A cut should wipe.
CV_Set(cv, "");
strcpy(menutyping.cache, "");
}
S_StartSound(NULL, sfx_s3k5b); // Tails
@ -130,22 +123,18 @@ boolean M_ChangeStringCvar(INT32 choice)
switch (choice)
{
case KEY_BACKSPACE:
if (cv->string[0])
if (menutyping.cache[0])
{
len = strlen(cv->string);
M_Memcpy(buf, cv->string, len);
buf[len-1] = 0;
CV_Set(cv, buf);
len = strlen(menutyping.cache);
menutyping.cache[len - 1] = 0;
S_StartSound(NULL, sfx_s3k5b); // Tails
}
return true;
case KEY_DEL:
if (cv->string[0])
if (menutyping.cache[0])
{
CV_Set(cv, "");
strcpy(menutyping.cache, "");
S_StartSound(NULL, sfx_s3k5b); // Tails
}
@ -153,15 +142,11 @@ boolean M_ChangeStringCvar(INT32 choice)
default:
if (choice >= 32 && choice <= 127)
{
len = strlen(cv->string);
len = strlen(menutyping.cache);
if (len < MAXSTRINGLENGTH - 1)
{
M_Memcpy(buf, cv->string, len);
buf[len++] = (char)choice;
buf[len] = 0;
CV_Set(cv, buf);
menutyping.cache[len++] = (char)choice;
menutyping.cache[len] = 0;
S_StartSound(NULL, sfx_s3k5b); // Tails
}
@ -189,6 +174,12 @@ static void M_ToggleVirtualShift(void)
}
}
static void M_CloseVirtualKeyboard(void)
{
menutyping.menutypingclose = true; // close menu.
CV_Set(currentMenu->menuitems[itemOn].itemaction.cvar, menutyping.cache);
}
static boolean M_IsTypingKey(INT32 key)
{
return key == KEY_BACKSPACE || key == KEY_ENTER
@ -286,7 +277,7 @@ void M_MenuTypingInput(INT32 key)
// OTHERWISE, process keyboard inputs for typing!
if (key == KEY_ENTER || key == KEY_ESCAPE)
{
menutyping.menutypingclose = true; // close menu.
M_CloseVirtualKeyboard();
M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k5b);
@ -355,7 +346,7 @@ void M_MenuTypingInput(INT32 key)
else if (M_MenuButtonPressed(pid, MBT_START))
{
// Shortcut for close menu.
menutyping.menutypingclose = true;
M_CloseVirtualKeyboard();
M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k5b);
@ -396,7 +387,7 @@ void M_MenuTypingInput(INT32 key)
}
else if (c == KEY_ENTER)
{
menutyping.menutypingclose = true; // close menu.
M_CloseVirtualKeyboard();
}
else
{
@ -410,3 +401,12 @@ void M_MenuTypingInput(INT32 key)
}
}
}
void M_OpenVirtualKeyboard(boolean gamepad)
{
menutyping.keyboardtyping = !gamepad;
menutyping.active = true;
menutyping.menutypingclose = false;
strlcpy(menutyping.cache, currentMenu->menuitems[itemOn].itemaction.cvar->string, MAXSTRINGLENGTH);
}