mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-23 02:41:30 +00:00
[console] Untangle console and menu toggling
The recent changes to key handling broke using escape to get out of the console (escape would toggle between console and menu). Thus take care of the menu (escape) part of the coupling FIXME by implementing a callback for the escape key (and removing key_togglemenu) and sorting out the escape key handling in console. Seems to work nicely
This commit is contained in:
parent
30dc82f290
commit
3b586fc0a6
10 changed files with 167 additions and 114 deletions
|
@ -537,7 +537,6 @@ typedef struct {
|
|||
int state; // low bit is down state
|
||||
} kbutton_t;
|
||||
|
||||
extern knum_t key_togglemenu;
|
||||
extern knum_t key_toggleconsole;
|
||||
|
||||
typedef struct keybind_s {
|
||||
|
@ -571,8 +570,8 @@ extern int keydown[QFK_LAST];
|
|||
\param down True if a press event, false if a release event.
|
||||
\param data Callback specific data pointer as passed to Key_SetKeyDest
|
||||
*/
|
||||
typedef void (*key_event_t) (knum_t key, short unicode, qboolean down,
|
||||
void *data);
|
||||
typedef void key_event_t (knum_t key, short unicode, qboolean down,
|
||||
void *data);
|
||||
|
||||
/** Set the fallback key event handler callback for the specified keydest.
|
||||
|
||||
|
@ -585,9 +584,25 @@ typedef void (*key_event_t) (knum_t key, short unicode, qboolean down,
|
|||
|
||||
\param keydest The keydest for which the callback will be set.
|
||||
\param callback The function to be called when an event occurs.
|
||||
\param data Opaque data pointerer passed to the callback.
|
||||
\param data Opaque data pointer passed to the callback.
|
||||
*/
|
||||
void Key_SetKeyEvent (keydest_t keydest, key_event_t callback, void *data);
|
||||
void Key_SetKeyEvent (keydest_t keydest, key_event_t *callback, void *data);
|
||||
|
||||
/** Callback for handling the escape key.
|
||||
\param data Callback specific data pointer as passed to Key_PushEscape
|
||||
*/
|
||||
typedef void key_escape_t (void *data);
|
||||
|
||||
/** Push an escape key event handler callback.
|
||||
|
||||
\param callback The function to be called when the escape key is pressed.
|
||||
\param data Opaque data pointer passed to the callback.
|
||||
*/
|
||||
void Key_PushEscape (key_escape_t *callback, void *data);
|
||||
|
||||
/** Push an escape key event handler callback.
|
||||
*/
|
||||
void Key_PopEscape (void);
|
||||
|
||||
struct cbuf_s;
|
||||
|
||||
|
@ -687,14 +702,17 @@ keydest_t Key_GetKeyDest(void) __attribute__((pure));
|
|||
/** keydest callback signature.
|
||||
|
||||
\param kd The new current keydest target.
|
||||
\param data Callback specific data pointer as passed to
|
||||
Key_KeydestCallback
|
||||
*/
|
||||
typedef void keydest_callback_t (keydest_t kd);
|
||||
typedef void keydest_callback_t (keydest_t kd, void *data);
|
||||
|
||||
/** Add a callback for when the keydest target changes.
|
||||
|
||||
\param callback The callback to be added.
|
||||
\param data Opaque data pointer passed to the callback.
|
||||
*/
|
||||
void Key_KeydestCallback (keydest_callback_t *callback);
|
||||
void Key_KeydestCallback (keydest_callback_t *callback, void *data);
|
||||
|
||||
/** Get the string representation of a key.
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ static view_t *hud_view;
|
|||
|
||||
static qboolean con_initialized;
|
||||
|
||||
static keydest_t con_keydest;
|
||||
static keydest_t con_curr_keydest;
|
||||
static keydest_t con_prev_keydest;
|
||||
|
||||
static void
|
||||
ClearNotify (void)
|
||||
|
@ -123,9 +124,10 @@ ToggleConsole_f (void)
|
|||
{
|
||||
Con_ClearTyping (input_line, 0);
|
||||
|
||||
if (con_keydest == key_console && !con_data.force_commandline) {
|
||||
Key_SetKeyDest (key_game);
|
||||
if (con_curr_keydest == key_console && !con_data.force_commandline) {
|
||||
Key_SetKeyDest (con_prev_keydest);
|
||||
} else {
|
||||
con_prev_keydest = Key_GetKeyDest ();
|
||||
Key_SetKeyDest (key_console);
|
||||
}
|
||||
|
||||
|
@ -137,7 +139,7 @@ ToggleChat_f (void)
|
|||
{
|
||||
Con_ClearTyping (input_line, 0);
|
||||
|
||||
if (con_keydest == key_console && !con_data.force_commandline) {
|
||||
if (con_curr_keydest == key_console && !con_data.force_commandline) {
|
||||
Key_SetKeyDest (key_game);
|
||||
} else {
|
||||
Key_SetKeyDest (key_console);
|
||||
|
@ -453,49 +455,19 @@ C_KeyEvent (knum_t key, short unicode, qboolean down, void *data)
|
|||
if (!down)
|
||||
return;
|
||||
|
||||
if (con_keydest == key_menu) {
|
||||
if (con_curr_keydest == key_menu) {
|
||||
if (Menu_KeyEvent (key, unicode, down))
|
||||
return;
|
||||
}
|
||||
|
||||
if (down) {
|
||||
if (key == key_togglemenu) {
|
||||
switch (con_keydest) {
|
||||
case key_menu:
|
||||
Menu_Leave ();
|
||||
return;
|
||||
case key_message:
|
||||
if (chat_team) {
|
||||
Con_ClearTyping (say_team_line, 1);
|
||||
} else {
|
||||
Con_ClearTyping (say_line, 1);
|
||||
}
|
||||
Key_SetKeyDest (key_game);
|
||||
return;
|
||||
case key_console:
|
||||
if (!con_data.force_commandline) {
|
||||
Cbuf_AddText (con_data.cbuf, "toggleconsole\n");
|
||||
return;
|
||||
}
|
||||
case key_game:
|
||||
case key_demo:
|
||||
Menu_Enter ();
|
||||
return;
|
||||
case key_unfocused:
|
||||
return;
|
||||
case key_last:
|
||||
break; // should not happen, so hit error
|
||||
}
|
||||
Sys_Error ("Bad con_keydest");
|
||||
} else if (key == key_toggleconsole) {
|
||||
if (key == key_toggleconsole) {
|
||||
ToggleConsole_f ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (con_keydest == key_menu) {
|
||||
return;
|
||||
} else if (con_keydest == key_message) {
|
||||
if (con_curr_keydest == key_message) {
|
||||
if (chat_team) {
|
||||
il = say_team_line;
|
||||
} else {
|
||||
|
@ -579,7 +551,7 @@ C_DrawInputLine (inputline_t *il)
|
|||
static void
|
||||
draw_input (view_t *view)
|
||||
{
|
||||
if (con_keydest != key_console)// && !con_data.force_commandline)
|
||||
if (con_curr_keydest != key_console)// && !con_data.force_commandline)
|
||||
return; // don't draw anything (always draw if not active)
|
||||
|
||||
DrawInputLine (view->xabs + 8, view->yabs, 1, input_line);
|
||||
|
@ -734,7 +706,7 @@ setup_console (void)
|
|||
|
||||
if (con_data.force_commandline) {
|
||||
lines = con_data.lines = r_data->vid->conview->ylen;
|
||||
} else if (con_keydest == key_console) {
|
||||
} else if (con_curr_keydest == key_console) {
|
||||
lines = r_data->vid->conview->ylen * bound (0.2, con_size->value, 1);
|
||||
} else {
|
||||
lines = 0;
|
||||
|
@ -763,9 +735,9 @@ C_DrawConsole (void)
|
|||
if (console_view->ylen != con_data.lines)
|
||||
view_resize (console_view, console_view->xlen, con_data.lines);
|
||||
|
||||
say_view->visible = con_keydest == key_message;
|
||||
say_view->visible = con_curr_keydest == key_message;
|
||||
console_view->visible = con_data.lines != 0;
|
||||
menu_view->visible = con_keydest == key_menu;
|
||||
menu_view->visible = con_curr_keydest == key_menu;
|
||||
|
||||
con_data.view->draw (con_data.view);
|
||||
}
|
||||
|
@ -806,10 +778,50 @@ exec_line (inputline_t *il)
|
|||
}
|
||||
|
||||
static void
|
||||
con_keydest_callback (keydest_t kd)
|
||||
con_end_message (void *line)
|
||||
{
|
||||
// simply cache the value
|
||||
con_keydest = kd;
|
||||
Key_PopEscape ();
|
||||
Con_ClearTyping (line, 1);
|
||||
Key_SetKeyDest (key_game);
|
||||
}
|
||||
|
||||
static void
|
||||
con_leave_console (void *data)
|
||||
{
|
||||
ToggleConsole_f ();
|
||||
}
|
||||
|
||||
static void
|
||||
con_keydest_callback (keydest_t kd, void *data)
|
||||
{
|
||||
if (kd == key_unfocused || kd == con_curr_keydest) {
|
||||
return;
|
||||
}
|
||||
if (kd != key_console && con_curr_keydest == key_console) {
|
||||
Key_PopEscape ();
|
||||
}
|
||||
switch (kd) {
|
||||
case key_last:
|
||||
case key_game:
|
||||
case key_demo:
|
||||
case key_unfocused:
|
||||
case key_menu:
|
||||
break;
|
||||
case key_message:
|
||||
Key_PushEscape (con_end_message,
|
||||
chat_team ? say_team_line : say_line);
|
||||
break;
|
||||
case key_console:
|
||||
Key_PushEscape (con_leave_console, 0);
|
||||
break;
|
||||
}
|
||||
con_curr_keydest = kd;
|
||||
}
|
||||
|
||||
static void
|
||||
con_enter_menu (void *data)
|
||||
{
|
||||
Menu_Enter ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -821,7 +833,8 @@ C_Init (void)
|
|||
setlocale (LC_ALL, "C-TRADITIONAL");
|
||||
#endif
|
||||
|
||||
Key_KeydestCallback (con_keydest_callback);
|
||||
Key_PushEscape (con_enter_menu, 0);
|
||||
Key_KeydestCallback (con_keydest_callback, 0);
|
||||
Key_SetKeyEvent (key_message, C_KeyEvent, 0);
|
||||
Key_SetKeyEvent (key_menu, C_KeyEvent, 0);
|
||||
Key_SetKeyEvent (key_console, C_KeyEvent, 0);
|
||||
|
|
|
@ -779,6 +779,12 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_leave (void *data)
|
||||
{
|
||||
Menu_Leave ();
|
||||
}
|
||||
|
||||
void
|
||||
Menu_Enter ()
|
||||
{
|
||||
|
@ -789,6 +795,7 @@ Menu_Enter ()
|
|||
menu = Hash_Find (menu_hash, top_menu);
|
||||
if (menu) {
|
||||
menu_keydest = Key_GetKeyDest ();
|
||||
Key_PushEscape (menu_leave, 0);
|
||||
Key_SetKeyDest (key_menu);
|
||||
if (menu->enter_hook) {
|
||||
run_menu_pre ();
|
||||
|
@ -809,6 +816,7 @@ Menu_Leave ()
|
|||
}
|
||||
menu = menu->parent;
|
||||
if (!menu) {
|
||||
Key_PopEscape ();
|
||||
Key_SetKeyDest (menu_keydest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "QF/cbuf.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/darray.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/keys.h"
|
||||
#include "QF/sys.h"
|
||||
|
@ -53,13 +54,25 @@
|
|||
|
||||
static keydest_t key_dest = key_console;
|
||||
static keytarget_t key_targets[key_last];
|
||||
VISIBLE knum_t key_togglemenu = QFK_ESCAPE;
|
||||
VISIBLE knum_t key_toggleconsole = QFK_BACKQUOTE;
|
||||
|
||||
#define KEYDEST_CALLBACK_CHUNK 16
|
||||
static keydest_callback_t **keydest_callbacks;
|
||||
static int num_keydest_callbacks;
|
||||
static int max_keydest_callbacks;
|
||||
typedef struct {
|
||||
keydest_callback_t *func;
|
||||
void *data;
|
||||
} keydest_callback_item_t;
|
||||
|
||||
typedef struct {
|
||||
key_escape_t *func;
|
||||
void *data;
|
||||
} key_escape_item_t;
|
||||
|
||||
#define CALLBACK_CHUNK 16
|
||||
static struct DARRAY_TYPE(keydest_callback_item_t) keydest_callbacks = {
|
||||
.grow = CALLBACK_CHUNK
|
||||
};
|
||||
static struct DARRAY_TYPE(key_escape_item_t) key_escape_callbacks = {
|
||||
.grow = CALLBACK_CHUNK
|
||||
};
|
||||
|
||||
VISIBLE int keydown[QFK_LAST];
|
||||
|
||||
|
@ -614,10 +627,10 @@ Key_SetBinding (imt_t *imt, knum_t keynum, const char *binding)
|
|||
static void
|
||||
Key_CallDestCallbacks (keydest_t kd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_keydest_callbacks; i++)
|
||||
keydest_callbacks[i] (kd);
|
||||
for (size_t i = 0; i < keydest_callbacks.size; i++) {
|
||||
keydest_callback_item_t *cb = &keydest_callbacks.a[i];
|
||||
cb->func (kd, cb->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -934,23 +947,6 @@ Key_Bind_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
in_key_togglemenu_f (cvar_t *var)
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!*var->string) {
|
||||
key_togglemenu = QFK_ESCAPE;
|
||||
return;
|
||||
}
|
||||
if ((k = Key_StringToKeynum (var->string)) == -1) {
|
||||
k = QFK_ESCAPE;
|
||||
Sys_Printf ("\"%s\" is not a valid key. setting to \"K_ESCAPE\"\n",
|
||||
var->string);
|
||||
}
|
||||
key_togglemenu = k;
|
||||
}
|
||||
|
||||
static void
|
||||
in_key_toggleconsole_f (cvar_t *var)
|
||||
{
|
||||
|
@ -1116,11 +1112,11 @@ keyhelp_f (void)
|
|||
keyhelp = 1;
|
||||
}
|
||||
|
||||
static key_event_t key_event_handlers[key_last] = { };
|
||||
static key_event_t *key_event_handlers[key_last] = { };
|
||||
static void *key_event_data[key_last] = { };
|
||||
|
||||
VISIBLE void
|
||||
Key_SetKeyEvent (keydest_t keydest, key_event_t callback, void *data)
|
||||
Key_SetKeyEvent (keydest_t keydest, key_event_t *callback, void *data)
|
||||
{
|
||||
if (keydest < 0 || keydest >= key_last) {
|
||||
Sys_Error ("Key_SetKeyEvent: invalid keydest: %d", keydest);
|
||||
|
@ -1152,15 +1148,20 @@ Key_Event (knum_t key, short unicode, qboolean down)
|
|||
keydown[key] = 0;
|
||||
}
|
||||
|
||||
// handle menu and console toggle keys specially so the user can never
|
||||
// override or unbind them
|
||||
// handle the escape key specially so it can never be overridden or
|
||||
// unbound
|
||||
if (key == QFK_ESCAPE && keydown[key] == 1) {
|
||||
if (key_escape_callbacks.size) {
|
||||
int ind = key_escape_callbacks.size - 1;
|
||||
key_escape_item_t cb = key_escape_callbacks.a[ind];
|
||||
cb.func (cb.data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
//FIXME maybe still a tad over-coupled. Use callbacks for menu and console
|
||||
//toggles? Should keys know anything about menu and console?
|
||||
if (key_dest != key_menu && key == key_togglemenu && keydown[key] == 1) {
|
||||
Cbuf_AddText (cbuf, "togglemenu");
|
||||
return;
|
||||
} else if (key_dest != key_console && key == key_toggleconsole
|
||||
&& keydown[key] == 1) {
|
||||
if (key_dest != key_console && key == key_toggleconsole
|
||||
&& keydown[key] == 1) {
|
||||
Cbuf_AddText (cbuf, "toggleconsole");
|
||||
return;
|
||||
}
|
||||
|
@ -1310,8 +1311,6 @@ Key_Init (cbuf_t *cb)
|
|||
void
|
||||
Key_Init_Cvars (void)
|
||||
{
|
||||
Cvar_Get ("in_key_togglemenu", "", CVAR_NONE, in_key_togglemenu_f,
|
||||
"Key for toggling the menu.");
|
||||
Cvar_Get ("in_key_toggleconsole", "K_BACKQUOTE", CVAR_NONE,
|
||||
in_key_toggleconsole_f,
|
||||
"Key for toggling the console.");
|
||||
|
@ -1333,8 +1332,10 @@ Key_SetKeyDest(keydest_t kd)
|
|||
Sys_Error ("Bad key_dest: %d", kd);
|
||||
}
|
||||
Sys_MaskPrintf (SYS_input, "Key_SetKeyDest: %s\n", keydest_names[kd]);
|
||||
key_dest = kd;
|
||||
Key_CallDestCallbacks (key_dest);
|
||||
if (key_dest != kd) {
|
||||
key_dest = kd;
|
||||
Key_CallDestCallbacks (key_dest);
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE keydest_t
|
||||
|
@ -1344,19 +1345,32 @@ Key_GetKeyDest (void)
|
|||
}
|
||||
|
||||
VISIBLE void
|
||||
Key_KeydestCallback (keydest_callback_t *callback)
|
||||
Key_KeydestCallback (keydest_callback_t *callback, void *data)
|
||||
{
|
||||
if (num_keydest_callbacks == max_keydest_callbacks) {
|
||||
size_t size = (max_keydest_callbacks + KEYDEST_CALLBACK_CHUNK)
|
||||
* sizeof (keydest_callback_t *);
|
||||
keydest_callbacks = realloc (keydest_callbacks, size);
|
||||
if (!keydest_callbacks)
|
||||
Sys_Error ("Too many keydest callbacks!");
|
||||
max_keydest_callbacks += KEYDEST_CALLBACK_CHUNK;
|
||||
if (!callback) {
|
||||
Sys_Error ("null keydest callback");
|
||||
}
|
||||
|
||||
if (!callback)
|
||||
Sys_Error ("null keydest callback");
|
||||
|
||||
keydest_callbacks[num_keydest_callbacks++] = callback;
|
||||
keydest_callback_item_t cb = { callback, data };
|
||||
DARRAY_APPEND (&keydest_callbacks, cb);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Key_PushEscape (key_escape_t *callback, void *data)
|
||||
{
|
||||
if (!callback) {
|
||||
Sys_Error ("null escape callback");
|
||||
}
|
||||
|
||||
key_escape_item_t cb = { callback, data };
|
||||
DARRAY_APPEND (&key_escape_callbacks, cb);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Key_PopEscape (void)
|
||||
{
|
||||
if (!key_escape_callbacks.size) {
|
||||
Sys_Error ("no escape callback to pop");
|
||||
}
|
||||
DARRAY_REMOVE (&key_escape_callbacks);
|
||||
}
|
||||
|
|
|
@ -597,7 +597,7 @@ XLateKey (XKeyEvent * ev, int *k, int *u)
|
|||
}
|
||||
|
||||
static void
|
||||
x11_keydest_callback (keydest_t key_dest)
|
||||
x11_keydest_callback (keydest_t key_dest, void *data)
|
||||
{
|
||||
// if (key_dest == key_game) {
|
||||
// XAutoRepeatOff (x_disp);
|
||||
|
@ -842,7 +842,7 @@ IN_LL_Init (void)
|
|||
in_mouse_avail = 1;
|
||||
}
|
||||
|
||||
Key_KeydestCallback (x11_keydest_callback);
|
||||
Key_KeydestCallback (x11_keydest_callback, 0);
|
||||
|
||||
Cmd_AddCommand ("in_paste_buffer", in_paste_buffer_f,
|
||||
"Paste the contents of X's C&P buffer to the console");
|
||||
|
|
|
@ -849,7 +849,7 @@ Host_Init_Memory (void)
|
|||
}
|
||||
|
||||
static void
|
||||
host_keydest_callback (keydest_t kd)
|
||||
host_keydest_callback (keydest_t kd, void *data)
|
||||
{
|
||||
host_in_game = kd == key_game;
|
||||
}
|
||||
|
@ -888,7 +888,7 @@ Host_Init (void)
|
|||
|
||||
Mod_Init ();
|
||||
|
||||
Key_KeydestCallback (host_keydest_callback);
|
||||
Key_KeydestCallback (host_keydest_callback, 0);
|
||||
|
||||
SV_Init ();
|
||||
|
||||
|
|
|
@ -1644,7 +1644,7 @@ Sbar_GIB_Print_Center_f (void)
|
|||
}
|
||||
|
||||
static void
|
||||
sbar_keydest_callback (keydest_t kd)
|
||||
sbar_keydest_callback (keydest_t kd, void *data)
|
||||
{
|
||||
overlay_view->visible = kd == key_game;
|
||||
}
|
||||
|
@ -1656,7 +1656,7 @@ Sbar_Init (void)
|
|||
|
||||
init_views ();
|
||||
|
||||
Key_KeydestCallback (sbar_keydest_callback);
|
||||
Key_KeydestCallback (sbar_keydest_callback, 0);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
sb_nums[0][i] = r_funcs->Draw_PicFromWad (va (0, "num_%i", i));
|
||||
|
|
|
@ -59,7 +59,7 @@ GIB_Key_Init (void)
|
|||
}
|
||||
|
||||
void
|
||||
Key_KeydestCallback (keydest_callback_t *callback)
|
||||
Key_KeydestCallback (keydest_callback_t *callback, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ CL_ChatInfo (int val)
|
|||
}
|
||||
|
||||
static void
|
||||
cl_chat_keydest (keydest_t keydest)
|
||||
cl_chat_keydest (keydest_t keydest, void *data)
|
||||
{
|
||||
switch (keydest) {
|
||||
case key_game:
|
||||
|
@ -277,5 +277,5 @@ CL_Chat_Init (void)
|
|||
|
||||
Cmd_AddCommand ("ignore", CL_Ignore_f, "Ignores chat and name-change messages from a user.");
|
||||
Cmd_AddCommand ("unignore", CL_Unignore_f, "Removes a previously ignored user from the ignore list.");
|
||||
Key_KeydestCallback (cl_chat_keydest);
|
||||
Key_KeydestCallback (cl_chat_keydest, 0);
|
||||
}
|
||||
|
|
|
@ -1941,7 +1941,7 @@ Sbar_GIB_Print_Center_f (void)
|
|||
}
|
||||
|
||||
static void
|
||||
sbar_keydest_callback (keydest_t kd)
|
||||
sbar_keydest_callback (keydest_t kd, void *data)
|
||||
{
|
||||
overlay_view->visible = kd == key_game;
|
||||
}
|
||||
|
@ -1953,7 +1953,7 @@ Sbar_Init (void)
|
|||
|
||||
init_views ();
|
||||
|
||||
Key_KeydestCallback (sbar_keydest_callback);
|
||||
Key_KeydestCallback (sbar_keydest_callback, 0);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
sb_nums[0][i] = r_funcs->Draw_PicFromWad (va (0, "num_%i", i));
|
||||
|
|
Loading…
Reference in a new issue