Improve keyboard/joystick input in Team Arena UI

Make Yes/No, Multi, Slider, and Bind items allow enter key to change
value without mouse over item. Add support for left and right arrow keys
and joystick button 1-4 to Yes/No, Multi, and Slider and many item
specific 'ownerdraw' key handlers.

Listbox still requires mouse hover and Team Arena main menu requires
mouse hover to get anywhere...

Enabling K_JOY1-4 to select in default key handler also caused additional
mouse button (K_AUX1-16) to select, which is done in q3_ui as well. Both
handle K_AUX equally badly (not treated as a mouse button and not handled
by item specific key handlers), so it's probably fine.
This commit is contained in:
Zack Middleton 2016-05-23 09:06:34 -05:00
parent 6394180224
commit d875c1f03c
3 changed files with 229 additions and 207 deletions

View file

@ -1932,12 +1932,20 @@ qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolea
qboolean Item_YesNo_HandleKey(itemDef_t *item, int key) {
if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) {
if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
return qtrue;
if (item->cvar) {
qboolean action = qfalse;
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
action = qtrue;
}
} else if (UI_SelectForKey(key) != 0) {
action = qtrue;
}
}
if (action) {
DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
return qtrue;
}
}
return qfalse;
@ -2006,11 +2014,21 @@ const char *Item_Multi_Setting(itemDef_t *item) {
qboolean Item_Multi_HandleKey(itemDef_t *item, int key) {
multiDef_t *multiPtr = (multiDef_t*)item->typeData;
if (multiPtr) {
if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) {
if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
int current = Item_Multi_FindCvarByValue(item) + 1;
if (item->cvar) {
int select = 0;
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
select = (key == K_MOUSE2) ? -1 : 1;
}
} else {
select = UI_SelectForKey(key);
}
if (select != 0) {
int current = Item_Multi_FindCvarByValue(item) + select;
int max = Item_Multi_CountSettings(item);
if ( current < 0 || current >= max ) {
if ( current < 0 ) {
current = max-1;
} else if ( current >= max ) {
current = 0;
}
if (multiPtr->strDef) {
@ -2334,10 +2352,10 @@ qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) {
float x, value, width, work;
//DC->Print("slider handle key\n");
if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
if (item->cvar) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
editFieldDef_t *editDef = item->typeData;
if (editDef) {
if (editDef && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS) {
rectDef_t testRect;
width = SLIDER_WIDTH;
if (item->text) {
@ -2364,6 +2382,23 @@ qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) {
return qtrue;
}
}
} else {
int select = UI_SelectForKey(key);
if (select != 0) {
editFieldDef_t *editDef = item->typeData;
if (editDef) {
// 20 is number of steps
value = DC->getCVarValue(item->cvar) + (((editDef->maxVal - editDef->minVal)/20) * select);
if (value < editDef->minVal)
value = editDef->minVal;
else if (value > editDef->maxVal)
value = editDef->maxVal;
DC->setCVar(item->cvar, va("%f", value));
return qtrue;
}
}
}
}
DC->Print("slider handle key exit\n");
@ -2594,6 +2629,32 @@ static rectDef_t *Item_CorrectedTextRect(itemDef_t *item) {
return &rect;
}
// menu item key horizontal action: -1 = previous value, 1 = next value, 0 = no change
int UI_SelectForKey(int key)
{
switch (key) {
case K_MOUSE1:
case K_MOUSE3:
case K_ENTER:
case K_KP_ENTER:
case K_RIGHTARROW:
case K_KP_RIGHTARROW:
case K_JOY1:
case K_JOY2:
case K_JOY3:
case K_JOY4:
return 1; // next
case K_MOUSE2:
case K_LEFTARROW:
case K_KP_LEFTARROW:
return -1; // previous
}
// no change
return 0;
}
void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) {
int i;
itemDef_t *item = NULL;
@ -2723,7 +2784,6 @@ void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) {
case K_AUX14:
case K_AUX15:
case K_AUX16:
break;
case K_KP_ENTER:
case K_ENTER:
if (item) {
@ -3435,9 +3495,10 @@ qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) {
int id;
int i;
if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey)
if (!g_waitingForKey)
{
if (down && (key == K_MOUSE1 || key == K_ENTER)) {
if (down && ((key == K_MOUSE1 && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
|| key == K_ENTER || key == K_KP_ENTER || key == K_JOY1 || key == K_JOY2 || key == K_JOY3 || key == K_JOY4)) {
g_waitingForKey = qtrue;
g_bindItem = item;
}
@ -3445,7 +3506,7 @@ qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) {
}
else
{
if (!g_waitingForKey || g_bindItem == NULL) {
if (g_bindItem == NULL) {
return qtrue;
}