mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
Simplify list box activation handling
Store the list box active state inside `CListBox` instead of tracking it separately with a pointer. Allow activating list boxes by clicking the scrollbar. Previously it was only possible to activate list boxes by selecting an item. Fix country selection list box in players settings not being deactivated properly when name/clan edit boxes are active, because wrong UI element IDs were being used.
This commit is contained in:
parent
161f8442b7
commit
55726e8da3
|
@ -1806,7 +1806,7 @@ void CMenus::RenderThemeSelection(CUIRect MainView)
|
|||
|
||||
static CListBox s_ListBox;
|
||||
s_ListBox.DoHeader(&MainView, Localize("Theme"), 20.0f);
|
||||
s_ListBox.DoStart(20.0f, vThemes.size(), 1, 3, SelectedTheme, nullptr, true);
|
||||
s_ListBox.DoStart(20.0f, vThemes.size(), 1, 3, SelectedTheme);
|
||||
|
||||
for(int i = 0; i < (int)vThemes.size(); i++)
|
||||
{
|
||||
|
|
|
@ -184,10 +184,9 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
g_Config.m_UiToolboxPage = (g_Config.m_UiToolboxPage + 3 + Direction) % 3;
|
||||
}
|
||||
|
||||
bool ListBoxUsed = !UI()->IsPopupOpen();
|
||||
|
||||
static CListBox s_ListBox;
|
||||
s_ListBox.DoStart(ms_ListheaderHeight, NumServers, 1, 3, -1, &View, false, &ListBoxUsed);
|
||||
s_ListBox.SetActive(!UI()->IsPopupOpen());
|
||||
s_ListBox.DoStart(ms_ListheaderHeight, NumServers, 1, 3, -1, &View, false);
|
||||
|
||||
int NumPlayers = 0;
|
||||
static int s_PrevSelectedIndex = -1;
|
||||
|
@ -224,7 +223,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
pItem->m_pUIElement = UI()->GetNewUIElement(UIRectCount);
|
||||
}
|
||||
|
||||
const CListboxItem ListItem = s_ListBox.DoNextItem(pItem, str_comp(pItem->m_aAddress, g_Config.m_UiServerAddress) == 0, &ListBoxUsed);
|
||||
const CListboxItem ListItem = s_ListBox.DoNextItem(pItem, str_comp(pItem->m_aAddress, g_Config.m_UiServerAddress) == 0);
|
||||
if(ListItem.m_Selected)
|
||||
m_SelectedIndex = i;
|
||||
|
||||
|
@ -984,11 +983,9 @@ CUI::EPopupMenuFunctionResult CMenus::PopupCountrySelection(void *pContext, CUIR
|
|||
SPopupCountrySelectionContext *pPopupContext = static_cast<SPopupCountrySelectionContext *>(pContext);
|
||||
CMenus *pMenus = pPopupContext->m_pMenus;
|
||||
|
||||
bool ListBoxUsed = Active;
|
||||
|
||||
static CListBox s_ListBox;
|
||||
int OldSelected = -1;
|
||||
s_ListBox.DoStart(50.0f, pMenus->m_pClient->m_CountryFlags.Num(), 8, 1, OldSelected, &View, false, &ListBoxUsed);
|
||||
s_ListBox.SetActive(Active);
|
||||
s_ListBox.DoStart(50.0f, pMenus->m_pClient->m_CountryFlags.Num(), 8, 1, -1, &View, false);
|
||||
|
||||
if(pPopupContext->m_New)
|
||||
{
|
||||
|
@ -999,10 +996,8 @@ CUI::EPopupMenuFunctionResult CMenus::PopupCountrySelection(void *pContext, CUIR
|
|||
for(size_t i = 0; i < pMenus->m_pClient->m_CountryFlags.Num(); ++i)
|
||||
{
|
||||
const CCountryFlags::CCountryFlag *pEntry = pMenus->m_pClient->m_CountryFlags.GetByIndex(i);
|
||||
if(pEntry->m_CountryCode == pPopupContext->m_Selection)
|
||||
OldSelected = i;
|
||||
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(pEntry, OldSelected >= 0 && (size_t)OldSelected == i, &ListBoxUsed);
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(pEntry, pEntry->m_CountryCode == pPopupContext->m_Selection);
|
||||
if(!Item.m_Visible)
|
||||
continue;
|
||||
|
||||
|
@ -1020,7 +1015,7 @@ CUI::EPopupMenuFunctionResult CMenus::PopupCountrySelection(void *pContext, CUIR
|
|||
}
|
||||
|
||||
const int NewSelected = s_ListBox.DoEnd();
|
||||
pPopupContext->m_Selection = pMenus->m_pClient->m_CountryFlags.GetByIndex(NewSelected)->m_CountryCode;
|
||||
pPopupContext->m_Selection = NewSelected >= 0 ? pMenus->m_pClient->m_CountryFlags.GetByIndex(NewSelected)->m_CountryCode : -1;
|
||||
if(s_ListBox.WasItemSelected() || s_ListBox.WasItemActivated())
|
||||
{
|
||||
g_Config.m_BrFilterCountry = 1;
|
||||
|
|
|
@ -363,15 +363,13 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView)
|
|||
m_Dummy ^= 1;
|
||||
}
|
||||
|
||||
static bool s_ListBoxUsed = false;
|
||||
if(UI()->CheckActiveItem(pClan) || UI()->CheckActiveItem(pName))
|
||||
s_ListBoxUsed = false;
|
||||
|
||||
// country flag selector
|
||||
MainView.HSplitTop(20.0f, 0, &MainView);
|
||||
int OldSelected = -1;
|
||||
static CListBox s_ListBox;
|
||||
s_ListBox.DoStart(50.0f, m_pClient->m_CountryFlags.Num(), 10, 3, OldSelected, &MainView, true, &s_ListBoxUsed);
|
||||
if(UI()->CheckActiveItem(&s_ClanInput) || UI()->CheckActiveItem(&s_NameInput))
|
||||
s_ListBox.SetActive(false);
|
||||
s_ListBox.DoStart(50.0f, m_pClient->m_CountryFlags.Num(), 10, 3, OldSelected, &MainView);
|
||||
|
||||
for(size_t i = 0; i < m_pClient->m_CountryFlags.Num(); ++i)
|
||||
{
|
||||
|
@ -379,7 +377,7 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView)
|
|||
if(pEntry->m_CountryCode == *pCountry)
|
||||
OldSelected = i;
|
||||
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(&pEntry->m_CountryCode, OldSelected >= 0 && (size_t)OldSelected == i, &s_ListBoxUsed);
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(&pEntry->m_CountryCode, OldSelected >= 0 && (size_t)OldSelected == i);
|
||||
if(!Item.m_Visible)
|
||||
continue;
|
||||
|
||||
|
@ -1565,15 +1563,16 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
|
|||
static const float sc_RowHeightResList = 22.0f;
|
||||
static const float sc_FontSizeResListHeader = 12.0f;
|
||||
static const float sc_FontSizeResList = 10.0f;
|
||||
bool ListBoxUsed = !UI()->IsPopupOpen();
|
||||
int OldSelected = -1;
|
||||
|
||||
{
|
||||
int G = std::gcd(g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight);
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %dx%d @%dhz %d bit (%d:%d)", Localize("Current"), (int)(g_Config.m_GfxScreenWidth * Graphics()->ScreenHiDPIScale()), (int)(g_Config.m_GfxScreenHeight * Graphics()->ScreenHiDPIScale()), g_Config.m_GfxScreenRefreshRate, g_Config.m_GfxColorDepth, g_Config.m_GfxScreenWidth / G, g_Config.m_GfxScreenHeight / G);
|
||||
UI()->DoLabel(&ModeLabel, aBuf, sc_FontSizeResListHeader, TEXTALIGN_MC);
|
||||
}
|
||||
|
||||
UI()->DoLabel(&ModeLabel, aBuf, sc_FontSizeResListHeader, TEXTALIGN_MC);
|
||||
s_ListBox.DoStart(sc_RowHeightResList, s_NumNodes, 1, 3, OldSelected, &ModeList, true, &ListBoxUsed);
|
||||
int OldSelected = -1;
|
||||
s_ListBox.SetActive(!UI()->IsPopupOpen());
|
||||
s_ListBox.DoStart(sc_RowHeightResList, s_NumNodes, 1, 3, OldSelected, &ModeList);
|
||||
|
||||
for(int i = 0; i < s_NumNodes; ++i)
|
||||
{
|
||||
|
@ -1586,7 +1585,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
|
|||
OldSelected = i;
|
||||
}
|
||||
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(&s_aModes[i], OldSelected == i, &ListBoxUsed);
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(&s_aModes[i], OldSelected == i);
|
||||
if(!Item.m_Visible)
|
||||
continue;
|
||||
|
||||
|
@ -2059,7 +2058,7 @@ bool CMenus::RenderLanguageSelection(CUIRect MainView)
|
|||
|
||||
const int OldSelected = s_SelectedLanguage;
|
||||
|
||||
s_ListBox.DoStart(24.0f, g_Localization.Languages().size(), 1, 3, s_SelectedLanguage, &MainView, true);
|
||||
s_ListBox.DoStart(24.0f, g_Localization.Languages().size(), 1, 3, s_SelectedLanguage, &MainView);
|
||||
|
||||
for(const auto &Language : g_Localization.Languages())
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@ CListBox::CListBox()
|
|||
m_HasHeader = false;
|
||||
m_AutoSpacing = 0.0f;
|
||||
m_ScrollbarIsShown = false;
|
||||
m_Active = true;
|
||||
}
|
||||
|
||||
void CListBox::DoBegin(const CUIRect *pRect)
|
||||
|
@ -59,7 +60,7 @@ void CListBox::DoFooter(const char *pBottomText, float FooterHeight)
|
|||
m_FooterHeight = FooterHeight;
|
||||
}
|
||||
|
||||
void CListBox::DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsPerScroll, int SelectedIndex, const CUIRect *pRect, bool Background, bool *pActive, int BackgroundCorners)
|
||||
void CListBox::DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsPerScroll, int SelectedIndex, const CUIRect *pRect, bool Background, int BackgroundCorners)
|
||||
{
|
||||
CUIRect View;
|
||||
if(pRect)
|
||||
|
@ -96,7 +97,7 @@ void CListBox::DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsP
|
|||
m_ListBoxItemSelected = false;
|
||||
|
||||
// handle input
|
||||
if(!pActive || *pActive)
|
||||
if(m_Active)
|
||||
{
|
||||
if(UI()->ConsumeHotkey(CUI::HOTKEY_DOWN))
|
||||
m_ListBoxNewSelOffset += 1;
|
||||
|
@ -115,7 +116,7 @@ void CListBox::DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsP
|
|||
// setup the scrollbar
|
||||
m_ScrollOffset = vec2(0.0f, 0.0f);
|
||||
CScrollRegionParams ScrollParams;
|
||||
ScrollParams.m_Active = !pActive || *pActive;
|
||||
ScrollParams.m_Active = m_Active;
|
||||
ScrollParams.m_ScrollbarWidth = ScrollbarWidthMax();
|
||||
ScrollParams.m_ScrollUnit = (m_ListBoxRowHeight + m_AutoSpacing) * RowsPerScroll;
|
||||
m_ScrollRegion.Begin(&m_ListBoxView, &m_ScrollOffset, &ScrollParams);
|
||||
|
@ -144,7 +145,7 @@ CListboxItem CListBox::DoNextRow()
|
|||
return Item;
|
||||
}
|
||||
|
||||
CListboxItem CListBox::DoNextItem(const void *pId, bool Selected, bool *pActive)
|
||||
CListboxItem CListBox::DoNextItem(const void *pId, bool Selected)
|
||||
{
|
||||
if(m_AutoSpacing > 0.0f && m_ListBoxItemIndex > 0)
|
||||
DoSpacing(m_AutoSpacing);
|
||||
|
@ -165,18 +166,15 @@ CListboxItem CListBox::DoNextItem(const void *pId, bool Selected, bool *pActive)
|
|||
ItemClicked = true;
|
||||
m_ListBoxNewSelected = ThisItemIndex;
|
||||
m_ListBoxItemSelected = true;
|
||||
if(pActive)
|
||||
*pActive = true;
|
||||
m_Active = true;
|
||||
}
|
||||
else
|
||||
ItemClicked = false;
|
||||
|
||||
const bool ProcessInput = !pActive || *pActive;
|
||||
|
||||
// process input, regard selected index
|
||||
if(m_ListBoxSelectedIndex == ThisItemIndex)
|
||||
{
|
||||
if(ProcessInput && !m_ListBoxDoneEvents)
|
||||
if(m_Active && !m_ListBoxDoneEvents)
|
||||
{
|
||||
m_ListBoxDoneEvents = true;
|
||||
|
||||
|
@ -187,7 +185,7 @@ CListboxItem CListBox::DoNextItem(const void *pId, bool Selected, bool *pActive)
|
|||
}
|
||||
}
|
||||
|
||||
Item.m_Rect.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, ProcessInput ? 0.5f : 0.33f), IGraphics::CORNER_ALL, 5.0f);
|
||||
Item.m_Rect.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, m_Active ? 0.5f : 0.33f), IGraphics::CORNER_ALL, 5.0f);
|
||||
}
|
||||
if(UI()->HotItem() == pId && !m_ScrollRegion.IsAnimating())
|
||||
{
|
||||
|
@ -207,6 +205,8 @@ CListboxItem CListBox::DoSubheader()
|
|||
int CListBox::DoEnd()
|
||||
{
|
||||
m_ScrollRegion.End();
|
||||
m_Active |= m_ScrollRegion.Params().m_Active;
|
||||
|
||||
m_ScrollbarIsShown = m_ScrollRegion.IsScrollbarShown();
|
||||
if(m_ListBoxNewSelOffset != 0 && m_ListBoxNumItems > 0 && m_ListBoxSelectedIndex == m_ListBoxNewSelected)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
float m_FilterOffset;
|
||||
int m_BackgroundCorners;
|
||||
bool m_HasHeader;
|
||||
bool m_Active;
|
||||
|
||||
protected:
|
||||
CListboxItem DoNextRow();
|
||||
|
@ -50,14 +51,19 @@ public:
|
|||
void DoAutoSpacing(float Spacing = 20.0f) { m_AutoSpacing = Spacing; }
|
||||
void DoSpacing(float Spacing = 20.0f);
|
||||
void DoFooter(const char *pBottomText, float FooterHeight = 20.0f); // call before DoStart to create a footer
|
||||
void DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsPerScroll, int SelectedIndex, const CUIRect *pRect = nullptr, bool Background = true, bool *pActive = nullptr, int BackgroundCorners = IGraphics::CORNER_ALL);
|
||||
void DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsPerScroll, int SelectedIndex, const CUIRect *pRect = nullptr, bool Background = true, int BackgroundCorners = IGraphics::CORNER_ALL);
|
||||
void ScrollToSelected() { m_ListBoxUpdateScroll = true; }
|
||||
CListboxItem DoNextItem(const void *pID, bool Selected = false, bool *pActive = nullptr);
|
||||
CListboxItem DoNextItem(const void *pID, bool Selected = false);
|
||||
CListboxItem DoSubheader();
|
||||
int DoEnd();
|
||||
bool FilterMatches(const char *pNeedle) const;
|
||||
|
||||
// Active state must be set before calling DoStart.
|
||||
bool Active() const { return m_Active; }
|
||||
void SetActive(bool Active) { m_Active = Active; }
|
||||
|
||||
bool WasItemSelected() const { return m_ListBoxItemSelected; }
|
||||
bool WasItemActivated() const { return m_ListBoxItemActivated; }
|
||||
|
||||
bool ScrollbarIsShown() const { return m_ScrollbarIsShown; }
|
||||
float ScrollbarWidth() const { return ScrollbarIsShown() ? ScrollbarWidthMax() : 0.0f; }
|
||||
float ScrollbarWidthMax() const { return 20.0f; }
|
||||
|
|
|
@ -157,6 +157,7 @@ void CScrollRegion::End()
|
|||
m_SliderGrabPos.y = UI()->MouseY() - Slider.y;
|
||||
m_AnimTargetScrollY = m_ScrollY;
|
||||
m_AnimTime = 0.0f;
|
||||
m_Params.m_Active = true;
|
||||
}
|
||||
}
|
||||
else if(InsideRail && UI()->MouseButtonClicked(0))
|
||||
|
@ -167,6 +168,7 @@ void CScrollRegion::End()
|
|||
m_SliderGrabPos.y = Slider.h / 2.0f;
|
||||
m_AnimTargetScrollY = m_ScrollY;
|
||||
m_AnimTime = 0.0f;
|
||||
m_Params.m_Active = true;
|
||||
}
|
||||
else if(UI()->CheckActiveItem(pID) && !UI()->MouseButton(0))
|
||||
{
|
||||
|
|
|
@ -134,6 +134,7 @@ public:
|
|||
bool IsRectClipped(const CUIRect &Rect) const;
|
||||
bool IsScrollbarShown() const;
|
||||
bool IsAnimating() const;
|
||||
const CScrollRegionParams &Params() const { return m_Params; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4664,8 +4664,7 @@ void CEditor::RenderFileDialog()
|
|||
|
||||
// filebox
|
||||
static CListBox s_ListBox;
|
||||
static bool s_ListBoxUsed = false;
|
||||
s_ListBoxUsed = !UI()->IsPopupOpen();
|
||||
s_ListBox.SetActive(!UI()->IsPopupOpen());
|
||||
|
||||
if(m_FileDialogStorageType == IStorage::TYPE_SAVE)
|
||||
{
|
||||
|
@ -4791,11 +4790,11 @@ void CEditor::RenderFileDialog()
|
|||
}
|
||||
}
|
||||
|
||||
s_ListBox.DoStart(15.0f, m_vpFilteredFileList.size(), 1, 5, m_FilesSelectedIndex, &View, false, &s_ListBoxUsed);
|
||||
s_ListBox.DoStart(15.0f, m_vpFilteredFileList.size(), 1, 5, m_FilesSelectedIndex, &View, false);
|
||||
|
||||
for(size_t i = 0; i < m_vpFilteredFileList.size(); i++)
|
||||
{
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(m_vpFilteredFileList[i], m_FilesSelectedIndex >= 0 && (size_t)m_FilesSelectedIndex == i, &s_ListBoxUsed);
|
||||
const CListboxItem Item = s_ListBox.DoNextItem(m_vpFilteredFileList[i], m_FilesSelectedIndex >= 0 && (size_t)m_FilesSelectedIndex == i);
|
||||
if(!Item.m_Visible)
|
||||
continue;
|
||||
|
||||
|
@ -4920,12 +4919,12 @@ void CEditor::RenderFileDialog()
|
|||
|
||||
ButtonBar.VSplitRight(ButtonSpacing, &ButtonBar, nullptr);
|
||||
ButtonBar.VSplitRight(50.0f, &ButtonBar, &Button);
|
||||
if(DoButton_Editor(&s_CancelButton, "Cancel", 0, &Button, 0, nullptr) || (s_ListBoxUsed && UI()->ConsumeHotkey(CUI::HOTKEY_ESCAPE)))
|
||||
if(DoButton_Editor(&s_CancelButton, "Cancel", 0, &Button, 0, nullptr) || (s_ListBox.Active() && UI()->ConsumeHotkey(CUI::HOTKEY_ESCAPE)))
|
||||
m_Dialog = DIALOG_NONE;
|
||||
|
||||
ButtonBar.VSplitRight(ButtonSpacing, &ButtonBar, nullptr);
|
||||
ButtonBar.VSplitRight(50.0f, &ButtonBar, &Button);
|
||||
if(DoButton_Editor(&s_RefreshButton, "Refresh", 0, &Button, 0, nullptr) || (s_ListBoxUsed && (Input()->KeyIsPressed(KEY_F5) || (Input()->ModifierIsPressed() && Input()->KeyIsPressed(KEY_R)))))
|
||||
if(DoButton_Editor(&s_RefreshButton, "Refresh", 0, &Button, 0, nullptr) || (s_ListBox.Active() && (Input()->KeyIsPressed(KEY_F5) || (Input()->ModifierIsPressed() && Input()->KeyIsPressed(KEY_R)))))
|
||||
FilelistPopulate(m_FileDialogLastPopulatedStorageType, true);
|
||||
|
||||
ButtonBar.VSplitRight(ButtonSpacing, &ButtonBar, nullptr);
|
||||
|
@ -4943,7 +4942,7 @@ void CEditor::RenderFileDialog()
|
|||
static CUI::SConfirmPopupContext s_ConfirmDeletePopupContext;
|
||||
if(m_FilesSelectedIndex >= 0 && m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType == IStorage::TYPE_SAVE && !m_vpFilteredFileList[m_FilesSelectedIndex]->m_IsLink && str_comp(m_vpFilteredFileList[m_FilesSelectedIndex]->m_aFilename, "..") != 0)
|
||||
{
|
||||
if(DoButton_Editor(&s_DeleteButton, "Delete", 0, &Button, 0, nullptr) || (s_ListBoxUsed && UI()->ConsumeHotkey(CUI::HOTKEY_DELETE)))
|
||||
if(DoButton_Editor(&s_DeleteButton, "Delete", 0, &Button, 0, nullptr) || (s_ListBox.Active() && UI()->ConsumeHotkey(CUI::HOTKEY_DELETE)))
|
||||
{
|
||||
s_ConfirmDeletePopupContext.Reset();
|
||||
s_ConfirmDeletePopupContext.YesNoButtons();
|
||||
|
|
Loading…
Reference in a new issue