Improve list box behaviour, make it more consistent

Make keys work after searching in vote menu

Unify some duplicated code
This commit is contained in:
def 2020-11-12 14:20:38 +01:00
parent 11d5e87047
commit 81bb7e661c
5 changed files with 106 additions and 204 deletions

View file

@ -2642,3 +2642,76 @@ void CMenus::SetMenuPage(int NewPage)
if(NewPage >= PAGE_INTERNET && NewPage <= PAGE_KOG)
g_Config.m_UiPage = NewPage;
}
bool CMenus::HandleListInputs(const CUIRect &View, float &ScrollValue, const float ScrollAmount, int *pScrollOffset, const float ElemHeight, int &SelectedIndex, const int NumElems)
{
int NewIndex = -1;
int Num = (int)(View.h / ElemHeight) + 1;
int ScrollNum = NumElems - Num + 1;
if(ScrollNum > 0)
{
if(pScrollOffset && *pScrollOffset >= 0)
{
ScrollValue = (float)(*pScrollOffset) / ScrollNum;
*pScrollOffset = -1;
}
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&View))
ScrollValue -= 3.0f / ScrollNum;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&View))
ScrollValue += 3.0f / ScrollNum;
}
else
ScrollNum = 0;
if(ScrollValue < 0)
ScrollValue = 0;
if(ScrollValue > 1)
ScrollValue = 1;
if(SelectedIndex < 0)
SelectedIndex = 0;
if(SelectedIndex >= NumElems)
SelectedIndex = NumElems;
for(int i = 0; i < m_NumInputEvents; i++)
{
if(m_aInputEvents[i].m_Flags & IInput::FLAG_PRESS)
{
if(m_aInputEvents[i].m_Key == KEY_DOWN)
NewIndex = minimum(SelectedIndex + 1, NumElems - 1);
else if(m_aInputEvents[i].m_Key == KEY_UP)
NewIndex = maximum(SelectedIndex - 1, 0);
else if(m_aInputEvents[i].m_Key == KEY_PAGEUP)
NewIndex = maximum(SelectedIndex - 25, 0);
else if(m_aInputEvents[i].m_Key == KEY_PAGEDOWN)
NewIndex = minimum(SelectedIndex + 25, NumElems - 1);
else if(m_aInputEvents[i].m_Key == KEY_HOME)
NewIndex = 0;
else if(m_aInputEvents[i].m_Key == KEY_END)
NewIndex = NumElems - 1;
}
if(NewIndex > -1 && NewIndex < NumElems)
{
//scroll
float IndexY = View.y - ScrollValue * ScrollNum * ElemHeight + NewIndex * ElemHeight;
int Scroll = View.y > IndexY ? -1 : View.y + View.h < IndexY + ElemHeight ? 1 : 0;
if(Scroll)
{
if(Scroll < 0)
{
int NumScrolls = (View.y - IndexY + ElemHeight - 1.0f) / ElemHeight;
ScrollValue -= (1.0f / ScrollNum) * NumScrolls;
}
else
{
int NumScrolls = (IndexY + ElemHeight - (View.y + View.h) + ElemHeight - 1.0f) / ElemHeight;
ScrollValue += (1.0f / ScrollNum) * NumScrolls;
}
}
SelectedIndex = NewIndex;
}
}
return NewIndex != -1;
}

View file

@ -627,6 +627,7 @@ public:
private:
static int GhostlistFetchCallback(const char *pName, int IsDir, int StorageType, void *pUser);
void SetMenuPage(int NewPage);
bool HandleListInputs(const CUIRect &View, float &ScrollValue, float ScrollAmount, int *pScrollOffset, float ElemHeight, int &SelectedIndex, int NumElems);
// found in menus_ingame.cpp
void RenderInGameNetwork(CUIRect MainView);

View file

@ -165,29 +165,12 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
UI()->DoLabelScaled(&MsgBox, Localize("No servers match your filter criteria"), 16.0f, 0);
}
int Num = (int)(View.h / s_aCols[0].m_Rect.h) + 1;
static int s_ScrollBar = 0;
static float s_ScrollValue = 0;
Scroll.HMargin(5.0f, &Scroll);
s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue);
int ScrollNum = NumServers - Num + 1;
if(ScrollNum > 0)
{
if(m_ScrollOffset >= 0)
{
s_ScrollValue = (float)(m_ScrollOffset) / ScrollNum;
m_ScrollOffset = -1;
}
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&View))
s_ScrollValue -= 3.0f / ScrollNum;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&View))
s_ScrollValue += 3.0f / ScrollNum;
}
else
ScrollNum = 0;
if(Input()->KeyPress(KEY_TAB) && m_pClient->m_pGameConsole->IsClosed())
{
if(Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT))
@ -195,62 +178,19 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
else
g_Config.m_UiToolboxPage = (g_Config.m_UiToolboxPage + 3 + 1) % 3;
}
if(m_SelectedIndex < 0)
m_SelectedIndex = 0;
for(int i = 0; i < m_NumInputEvents; i++)
if(HandleListInputs(View, s_ScrollValue, 3.0f, &m_ScrollOffset, s_aCols[0].m_Rect.h, m_SelectedIndex, NumServers))
{
int NewIndex = -1;
if(m_aInputEvents[i].m_Flags & IInput::FLAG_PRESS)
{
if(m_aInputEvents[i].m_Key == KEY_DOWN)
NewIndex = minimum(m_SelectedIndex + 1, NumServers - 1);
else if(m_aInputEvents[i].m_Key == KEY_UP)
NewIndex = maximum(m_SelectedIndex - 1, 0);
else if(m_aInputEvents[i].m_Key == KEY_PAGEUP)
NewIndex = maximum(m_SelectedIndex - 25, 0);
else if(m_aInputEvents[i].m_Key == KEY_PAGEDOWN)
NewIndex = minimum(m_SelectedIndex + 25, NumServers - 1);
else if(m_aInputEvents[i].m_Key == KEY_HOME)
NewIndex = 0;
else if(m_aInputEvents[i].m_Key == KEY_END)
NewIndex = NumServers - 1;
}
if(NewIndex > -1 && NewIndex < NumServers)
{
//scroll
float IndexY = View.y - s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h + NewIndex * s_aCols[0].m_Rect.h;
int Scroll = View.y > IndexY ? -1 : View.y + View.h < IndexY + s_aCols[0].m_Rect.h ? 1 : 0;
if(Scroll)
{
if(Scroll < 0)
{
int NumScrolls = (View.y - IndexY + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue -= (1.0f / ScrollNum) * NumScrolls;
}
else
{
int NumScrolls = (IndexY + s_aCols[0].m_Rect.h - (View.y + View.h) + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue += (1.0f / ScrollNum) * NumScrolls;
}
}
m_SelectedIndex = NewIndex;
const CServerInfo *pItem = ServerBrowser()->SortedGet(m_SelectedIndex);
str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress));
}
const CServerInfo *pItem = ServerBrowser()->SortedGet(m_SelectedIndex);
str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress));
}
if(s_ScrollValue < 0)
s_ScrollValue = 0;
if(s_ScrollValue > 1)
s_ScrollValue = 1;
// set clipping
UI()->ClipEnable(&View);
CUIRect OriginalView = View;
int Num = (int)(View.h / s_aCols[0].m_Rect.h) + 1;
int ScrollNum = NumServers - Num + 1;
View.y -= s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h;
int NewSelected = -1;

View file

@ -561,29 +561,29 @@ void CMenus::UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHe
{
Num = 0;
}
else if(Num == 1)
{
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&View))
gs_ListBoxScrollValue -= 0.1f;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&View))
gs_ListBoxScrollValue += 0.1f;
if(gs_ListBoxScrollValue < 0.0f)
gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f)
gs_ListBoxScrollValue = 1.0f;
}
else
{
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&View))
gs_ListBoxScrollValue -= 3.0f / Num;
gs_ListBoxScrollValue -= Num == 1 ? 0.1f : 3.0f / Num;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&View))
gs_ListBoxScrollValue += 3.0f / Num;
gs_ListBoxScrollValue += Num == 1 ? 0.1f : 3.0f / Num;
}
if(gs_ListBoxScrollValue < 0.0f)
gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f)
gs_ListBoxScrollValue = 1.0f;
// TODO: Still have to press twice after updating search, why?
if(gs_ListBoxScrollValue < 0.0f)
gs_ListBoxScrollValue = 0.0f;
if(gs_ListBoxScrollValue > 1.0f)
gs_ListBoxScrollValue = 1.0f;
if(gs_ListBoxSelectedIndex < 0)
{
gs_ListBoxSelectedIndex = 0;
gs_ListBoxNewSelected = 0;
}
if(gs_ListBoxSelectedIndex >= NumItems)
{
gs_ListBoxSelectedIndex = NumItems - 1;
gs_ListBoxNewSelected = NumItems - 1;
}
Scroll.HMargin(5.0f, &Scroll);
@ -1077,85 +1077,20 @@ void CMenus::RenderDemoList(CUIRect MainView)
CUIRect Scroll;
ListBox.VSplitRight(15, &ListBox, &Scroll);
int Num = (int)(ListBox.h / s_aCols[0].m_Rect.h) + 1;
static int s_ScrollBar = 0;
static float s_ScrollValue = 0;
Scroll.HMargin(5.0f, &Scroll);
s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue);
int ScrollNum = m_lDemos.size() - Num + 1;
if(ScrollNum > 0)
{
if(m_ScrollOffset)
{
s_ScrollValue = (float)(m_ScrollOffset) / ScrollNum;
m_ScrollOffset = 0;
}
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&ListBox))
s_ScrollValue -= 3.0f / ScrollNum;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&ListBox))
s_ScrollValue += 3.0f / ScrollNum;
}
else
ScrollNum = 0;
if(m_DemolistSelectedIndex > -1)
{
for(int i = 0; i < m_NumInputEvents; i++)
{
int NewIndex = -1;
if(m_aInputEvents[i].m_Flags & IInput::FLAG_PRESS)
{
if(m_aInputEvents[i].m_Key == KEY_DOWN)
NewIndex = m_DemolistSelectedIndex + 1;
else if(m_aInputEvents[i].m_Key == KEY_UP)
NewIndex = m_DemolistSelectedIndex - 1;
else if(m_aInputEvents[i].m_Key == KEY_PAGEUP)
NewIndex = maximum(m_DemolistSelectedIndex - 20, 0);
else if(m_aInputEvents[i].m_Key == KEY_PAGEDOWN)
NewIndex = minimum(m_DemolistSelectedIndex + 20, m_lDemos.size() - 1);
else if(m_aInputEvents[i].m_Key == KEY_HOME)
NewIndex = 0;
else if(m_aInputEvents[i].m_Key == KEY_END)
NewIndex = m_lDemos.size() - 1;
}
if(NewIndex > -1 && NewIndex < m_lDemos.size())
{
//scroll
float IndexY = ListBox.y - s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h + NewIndex * s_aCols[0].m_Rect.h;
int Scroll = ListBox.y > IndexY ? -1 : ListBox.y + ListBox.h < IndexY + s_aCols[0].m_Rect.h ? 1 : 0;
if(Scroll)
{
if(Scroll < 0)
{
int NumScrolls = (ListBox.y - IndexY + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue -= (1.0f / ScrollNum) * NumScrolls;
}
else
{
int NumScrolls = (IndexY + s_aCols[0].m_Rect.h - (ListBox.y + ListBox.h) + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue += (1.0f / ScrollNum) * NumScrolls;
}
}
m_DemolistSelectedIndex = NewIndex;
str_copy(g_Config.m_UiDemoSelected, m_lDemos[NewIndex].m_aName, sizeof(g_Config.m_UiDemoSelected));
DemolistOnUpdate(false);
}
}
}
if(s_ScrollValue < 0)
s_ScrollValue = 0;
if(s_ScrollValue > 1)
s_ScrollValue = 1;
HandleListInputs(ListBox, s_ScrollValue, 3.0f, &m_ScrollOffset, s_aCols[0].m_Rect.h, m_DemolistSelectedIndex, m_lDemos.size());
// set clipping
UI()->ClipEnable(&ListBox);
CUIRect OriginalView = ListBox;
int Num = (int)(ListBox.h / s_aCols[0].m_Rect.h) + 1;
int ScrollNum = m_lDemos.size() - Num + 1;
ListBox.y -= s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h;
int NewSelected = -1;

View file

@ -559,7 +559,7 @@ bool CMenus::RenderServerControlServer(CUIRect MainView)
bool CMenus::RenderServerControlKick(CUIRect MainView, bool FilterSpectators)
{
int NumOptions = 0;
int Selected = -1;
int Selected = 0;
static int aPlayerIDs[MAX_CLIENTS];
for(auto &pInfoByName : m_pClient->m_Snap.m_paInfoByName)
{
@ -1015,68 +1015,21 @@ void CMenus::RenderGhost(CUIRect MainView)
View.VSplitRight(15, &View, &Scroll);
int NumGhosts = m_lGhosts.size();
int Num = (int)(View.h / s_aCols[0].m_Rect.h) + 1;
static int s_ScrollBar = 0;
static float s_ScrollValue = 0;
static int s_SelectedIndex = 0;
Scroll.HMargin(5.0f, &Scroll);
s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue);
int ScrollNum = NumGhosts - Num + 1;
if(ScrollNum > 0)
{
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP))
s_ScrollValue -= 1.0f / ScrollNum;
if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN))
s_ScrollValue += 1.0f / ScrollNum;
}
else
ScrollNum = 0;
static int s_SelectedIndex = 0;
for(int i = 0; i < m_NumInputEvents; i++)
{
int NewIndex = -1;
if(m_aInputEvents[i].m_Flags & IInput::FLAG_PRESS)
{
if(m_aInputEvents[i].m_Key == KEY_DOWN)
NewIndex = s_SelectedIndex + 1;
if(m_aInputEvents[i].m_Key == KEY_UP)
NewIndex = s_SelectedIndex - 1;
}
if(NewIndex > -1 && NewIndex < NumGhosts)
{
//scroll
float IndexY = View.y - s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h + NewIndex * s_aCols[0].m_Rect.h;
int Scroll = View.y > IndexY ? -1 : View.y + View.h < IndexY + s_aCols[0].m_Rect.h ? 1 : 0;
if(Scroll)
{
if(Scroll < 0)
{
int NumScrolls = (View.y - IndexY + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue -= (1.0f / ScrollNum) * NumScrolls;
}
else
{
int NumScrolls = (IndexY + s_aCols[0].m_Rect.h - (View.y + View.h) + s_aCols[0].m_Rect.h - 1.0f) / s_aCols[0].m_Rect.h;
s_ScrollValue += (1.0f / ScrollNum) * NumScrolls;
}
}
s_SelectedIndex = NewIndex;
}
}
if(s_ScrollValue < 0)
s_ScrollValue = 0;
if(s_ScrollValue > 1)
s_ScrollValue = 1;
HandleListInputs(View, s_ScrollValue, 1.0f, nullptr, s_aCols[0].m_Rect.h, s_SelectedIndex, NumGhosts);
// set clipping
UI()->ClipEnable(&View);
CUIRect OriginalView = View;
int Num = (int)(View.h / s_aCols[0].m_Rect.h) + 1;
int ScrollNum = NumGhosts - Num + 1;
View.y -= s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h;
int NewSelected = -1;
@ -1180,7 +1133,7 @@ void CMenus::RenderGhost(CUIRect MainView)
Status.VSplitLeft(120.0f, &Button, &Status);
static int s_ReloadButton = 0;
if(DoButton_Menu(&s_ReloadButton, Localize("Reload"), 0, &Button))
if(DoButton_Menu(&s_ReloadButton, Localize("Reload"), 0, &Button) || Input()->KeyPress(KEY_F5))
{
m_pClient->m_pGhost->UnloadAll();
GhostlistPopulate();