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

@ -2260,33 +2260,29 @@ static qboolean UI_OwnerDrawVisible(int flags) {
}
static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int h;
h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
if (key == K_MOUSE2) {
h -= 5;
} else {
h += 5;
}
h += 5 * select;
if (h > 100) {
h = 5;
} else if (h < 5) {
h = 100;
}
trap_Cvar_Set( "handicap", va( "%i", h) );
trap_Cvar_SetValue( "handicap", h );
return qtrue;
}
return qfalse;
}
static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
uiInfo.effectsColor--;
} else {
uiInfo.effectsColor++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
uiInfo.effectsColor += select;
if( uiInfo.effectsColor > 6 ) {
uiInfo.effectsColor = 0;
@ -2301,23 +2297,25 @@ static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int i;
i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
if (uiInfo.teamList[i].cinematic >= 0) {
trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
uiInfo.teamList[i].cinematic = -1;
}
if (key == K_MOUSE2) {
i--;
} else {
i++;
}
i += select;
if (i >= uiInfo.teamCount) {
i = 0;
} else if (i < 0) {
i = uiInfo.teamCount - 1;
}
trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName);
UI_HeadCountByTeam();
UI_FeederSelection(FEEDER_HEADS, 0);
@ -2328,11 +2326,12 @@ static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int oldCount = UI_MapCountByGameType(qtrue);
// hard coded mess here
if (key == K_MOUSE2) {
if (select < 0) {
ui_gameType.integer--;
if (ui_gameType.integer == 2) {
ui_gameType.integer = 1;
@ -2348,17 +2347,17 @@ static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboole
}
}
if (uiInfo.gameTypes[ui_gameType.integer].gtEnum == GT_TOURNAMENT) {
trap_Cvar_Set("ui_Q3Model", "1");
if (uiInfo.gameTypes[ui_gameType.integer].gtEnum < GT_TEAM) {
trap_Cvar_SetValue( "ui_Q3Model", 1 );
} else {
trap_Cvar_Set("ui_Q3Model", "0");
trap_Cvar_SetValue( "ui_Q3Model", 0 );
}
trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer));
trap_Cvar_SetValue("ui_gameType", ui_gameType.integer);
UI_SetCapFragLimits(qtrue);
UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
trap_Cvar_Set( "ui_currentMap", "0");
trap_Cvar_SetValue( "ui_currentMap", 0);
Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
}
return qtrue;
@ -2367,13 +2366,9 @@ static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboole
}
static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
ui_netGameType.integer--;
} else {
ui_netGameType.integer++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
ui_netGameType.integer += select;
if (ui_netGameType.integer < 0) {
ui_netGameType.integer = uiInfo.numGameTypes - 1;
@ -2381,9 +2376,9 @@ static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
ui_netGameType.integer = 0;
}
trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer));
trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum));
trap_Cvar_Set( "ui_currentNetMap", "0");
trap_Cvar_SetValue( "ui_netGameType", ui_netGameType.integer);
trap_Cvar_SetValue( "ui_actualnetGameType", uiInfo.gameTypes[ui_netGameType.integer].gtEnum);
trap_Cvar_SetValue( "ui_currentNetMap", 0);
UI_MapCountByGameType(qfalse);
Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
return qtrue;
@ -2392,13 +2387,9 @@ static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
ui_joinGameType.integer--;
} else {
ui_joinGameType.integer++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
ui_joinGameType.integer += select;
if (ui_joinGameType.integer < 0) {
ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
@ -2406,7 +2397,7 @@ static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
ui_joinGameType.integer = 0;
}
trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer));
trap_Cvar_SetValue( "ui_joinGameType", ui_joinGameType.integer);
UI_BuildServerDisplayList(qtrue);
return qtrue;
}
@ -2416,14 +2407,11 @@ static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int i = trap_Cvar_VariableValue( "g_spSkill" );
if (key == K_MOUSE2) {
i--;
} else {
i++;
}
i += select;
if (i < 1) {
i = numSkillLevels;
@ -2431,22 +2419,19 @@ static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
i = 1;
}
trap_Cvar_Set("g_spSkill", va("%i", i));
trap_Cvar_SetValue("g_spSkill", i);
return qtrue;
}
return qfalse;
}
static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int i;
i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
if (key == K_MOUSE2) {
i--;
} else {
i++;
}
i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
i += select;
if (i >= uiInfo.teamCount) {
i = 0;
@ -2455,25 +2440,21 @@ static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboole
}
trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
return qtrue;
}
return qfalse;
}
static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
// 0 - None
// 1 - Human
// 2..NumCharacters - Bot
char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
int value = trap_Cvar_VariableValue(cvar);
if (key == K_MOUSE2) {
value--;
} else {
value++;
}
value += select;
if (ui_actualNetGameType.integer >= GT_TEAM) {
if (value >= uiInfo.characterCount + 2) {
@ -2489,20 +2470,16 @@ static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboo
}
}
trap_Cvar_Set(cvar, va("%i", value));
trap_Cvar_SetValue(cvar, value);
return qtrue;
}
return qfalse;
}
static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
ui_netSource.integer--;
} else {
ui_netSource.integer++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
ui_netSource.integer += select;
if(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)
{
@ -2515,11 +2492,7 @@ static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
if(*masterstr)
break;
if (key == K_MOUSE2) {
ui_netSource.integer--;
} else {
ui_netSource.integer++;
}
ui_netSource.integer += select;
}
}
@ -2533,20 +2506,16 @@ static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
if (!(ui_netSource.integer >= UIAS_GLOBAL1 && ui_netSource.integer <= UIAS_GLOBAL5)) {
UI_StartServerRefresh(qtrue);
}
trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer));
trap_Cvar_SetValue( "ui_netSource", ui_netSource.integer);
return qtrue;
}
return qfalse;
}
static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
ui_serverFilterType.integer--;
} else {
ui_serverFilterType.integer++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
ui_serverFilterType.integer += select;
if (ui_serverFilterType.integer >= numServerFilters) {
ui_serverFilterType.integer = 0;
@ -2560,8 +2529,9 @@ static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
int select = UI_SelectForKey(key);
if (select != 0) {
if (select < 0) {
UI_PriorOpponent();
} else {
UI_NextOpponent();
@ -2572,15 +2542,12 @@ static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int game = trap_Cvar_VariableValue("g_gametype");
int value = uiInfo.botIndex;
if (key == K_MOUSE2) {
value--;
} else {
value++;
}
value += select;
if (game >= GT_TEAM) {
if (value >= uiInfo.characterCount + 2) {
@ -2602,12 +2569,10 @@ static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
uiInfo.skillIndex--;
} else {
uiInfo.skillIndex++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
uiInfo.skillIndex += select;
if (uiInfo.skillIndex >= numSkillLevels) {
uiInfo.skillIndex = 0;
} else if (uiInfo.skillIndex < 0) {
@ -2619,7 +2584,8 @@ static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
uiInfo.redBlue ^= 1;
return qtrue;
}
@ -2627,19 +2593,16 @@ static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
}
static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
if (key == K_MOUSE2) {
uiInfo.currentCrosshair--;
} else {
uiInfo.currentCrosshair++;
}
int select = UI_SelectForKey(key);
if (select != 0) {
uiInfo.currentCrosshair += select;
if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
uiInfo.currentCrosshair = 0;
} else if (uiInfo.currentCrosshair < 0) {
uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
}
trap_Cvar_Set("cg_drawCrosshair", va("%d", uiInfo.currentCrosshair));
trap_Cvar_SetValue("cg_drawCrosshair", uiInfo.currentCrosshair);
return qtrue;
}
return qfalse;
@ -2648,7 +2611,8 @@ static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
int select = UI_SelectForKey(key);
if (select != 0) {
int selected;
UI_BuildPlayerList();
@ -2657,11 +2621,7 @@ static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key)
}
selected = trap_Cvar_VariableValue("cg_selectedPlayer");
if (key == K_MOUSE2) {
selected--;
} else {
selected++;
}
selected += select;
if (selected > uiInfo.myTeamCount) {
selected = 0;
@ -2674,7 +2634,7 @@ static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key)
} else {
trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
}
trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected));
trap_Cvar_SetValue( "cg_selectedPlayer", selected);
}
return qfalse;
}

View file

@ -1932,8 +1932,16 @@ 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) {
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;
}
@ -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;
}

View file

@ -417,6 +417,7 @@ void Menu_Reset( void );
qboolean Menus_AnyFullScreenVisible( void );
void Menus_Activate(menuDef_t *menu);
int UI_SelectForKey(int key);
displayContextDef_t *Display_GetContext( void );
void *Display_CaptureItem(int x, int y);
qboolean Display_MouseMove(void *p, int x, int y);