From d3f0c2a1566afaee16ad870451dca63b9966d2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Mon, 9 Sep 2024 22:37:40 +0200 Subject: [PATCH] Extract `CUi::DoEditBox_Search` function for quick search Reduce duplicate and inconsistent code for rendering quick search for the demo browser, ingame vote list, player flag, skin, skin 0.7 and asset search. The quick search and exclude in the server browser are not refactored, as they have additional labels and different alignment, which would make a general function complicated. --- src/game/client/components/menus_demo.cpp | 16 +----- src/game/client/components/menus_ingame.cpp | 19 ++----- src/game/client/components/menus_settings.cpp | 56 ++++--------------- .../client/components/menus_settings7.cpp | 20 +------ .../components/menus_settings_assets.cpp | 30 +++------- src/game/client/ui.cpp | 19 +++++++ src/game/client/ui.h | 18 ++++++ 7 files changed, 64 insertions(+), 114 deletions(-) diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 2b816a6df..9da978a1f 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -1397,22 +1397,10 @@ void CMenus::RenderDemoBrowserButtons(CUIRect ButtonsView, bool WasListboxItemAc // quick search { - SetIconMode(true); - CUIRect DemoSearch, SearchIcon; + CUIRect DemoSearch; ButtonBarTop.VSplitLeft(ButtonBarBottom.h * 21.0f, &DemoSearch, &ButtonBarTop); ButtonBarTop.VSplitLeft(ButtonBarTop.h / 2.0f, nullptr, &ButtonBarTop); - DemoSearch.VSplitLeft(TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS), &SearchIcon, &DemoSearch); - DemoSearch.VSplitLeft(5.0f, nullptr, &DemoSearch); - Ui()->DoLabel(&SearchIcon, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - SetIconMode(false); - m_DemoSearchInput.SetEmptyText(Localize("Search")); - - if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()) - { - Ui()->SetActiveItem(&m_DemoSearchInput); - m_DemoSearchInput.SelectAll(); - } - if(Ui()->DoClearableEditBox(&m_DemoSearchInput, &DemoSearch, 12.0f)) + if(Ui()->DoEditBox_Search(&m_DemoSearchInput, &DemoSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed())) { RefreshFilteredDemos(); DemolistOnUpdate(false); diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index e1f3e2b53..ab511e768 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -683,26 +683,15 @@ void CMenus::RenderServerControl(CUIRect MainView) // render quick search CUIRect QuickSearch; - Bottom.VSplitLeft(5.0f, 0, &Bottom); + Bottom.VSplitLeft(5.0f, nullptr, &Bottom); Bottom.VSplitLeft(250.0f, &QuickSearch, &Bottom); - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); - TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); - - Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - QuickSearch.VSplitLeft(SearchWidth, 0, &QuickSearch); - QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch); - - if(m_ControlPageOpening || (Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed())) + if(m_ControlPageOpening) { - Ui()->SetActiveItem(&m_FilterInput); m_ControlPageOpening = false; + Ui()->SetActiveItem(&m_FilterInput); m_FilterInput.SelectAll(); } - m_FilterInput.SetEmptyText(Localize("Search")); - Ui()->DoClearableEditBox(&m_FilterInput, &QuickSearch, 14.0f); + Ui()->DoEditBox_Search(&m_FilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()); // call vote Bottom.VSplitRight(10.0f, &Bottom, 0); diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 53ab36fed..d7143ab39 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -257,7 +257,7 @@ void CMenus::SetNeedSendInfo() void CMenus::RenderSettingsPlayer(CUIRect MainView) { - CUIRect TabBar, PlayerTab, DummyTab, ChangeInfo, QuickSearch, QuickSearchClearButton; + CUIRect TabBar, PlayerTab, DummyTab, ChangeInfo, QuickSearch; MainView.HSplitTop(20.0f, &TabBar, &MainView); TabBar.VSplitMid(&TabBar, &ChangeInfo, 20.f); TabBar.VSplitMid(&PlayerTab, &DummyTab); @@ -340,7 +340,10 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView) } MainView.HSplitTop(10.0f, nullptr, &MainView); - MainView.HSplitBottom(25.0f, &MainView, &QuickSearch); + MainView.HSplitBottom(20.0f, &MainView, &QuickSearch); + MainView.HSplitBottom(5.0f, &MainView, nullptr); + QuickSearch.VSplitLeft(220.0f, &QuickSearch, nullptr); + int OldSelected = -1; static CListBox s_ListBox; s_ListBox.DoStart(48.0f, vpFilteredFlags.size(), 10, 3, OldSelected, &MainView); @@ -378,30 +381,7 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView) SetNeedSendInfo(); } - // render quick search - QuickSearch.VSplitLeft(240.0f, &QuickSearch, nullptr); - QuickSearch.HSplitTop(5.0f, nullptr, &QuickSearch); - - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); - TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); - Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - - float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - QuickSearch.VSplitLeft(SearchWidth - 1.5f, nullptr, &QuickSearch); - QuickSearch.VSplitLeft(5.0f, nullptr, &QuickSearch); - QuickSearch.VSplitLeft(QuickSearch.w - 10.0f, &QuickSearch, &QuickSearchClearButton); - - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()) - { - Ui()->SetActiveItem(&s_FlagFilterInput); - s_FlagFilterInput.SelectAll(); - } - s_FlagFilterInput.SetEmptyText(Localize("Search")); - Ui()->DoClearableEditBox(&s_FlagFilterInput, &QuickSearch, 14.0f); + Ui()->DoEditBox_Search(&s_FlagFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed()); } struct CUISkin @@ -770,8 +750,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView) CUIRect QuickSearch, DatabaseButton, DirectoryButton, RefreshButton; MainView.HSplitBottom(20.0f, &MainView, &QuickSearch); MainView.HSplitBottom(5.0f, &MainView, nullptr); - QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DatabaseButton); - QuickSearch.VSplitRight(10.0f, &QuickSearch, nullptr); + QuickSearch.VSplitLeft(220.0f, &QuickSearch, &DatabaseButton); + DatabaseButton.VSplitLeft(10.0f, nullptr, &DatabaseButton); DatabaseButton.VSplitLeft(150.0f, &DatabaseButton, &DirectoryButton); DirectoryButton.VSplitRight(175.0f, nullptr, &DirectoryButton); DirectoryButton.VSplitRight(25.0f, &DirectoryButton, &RefreshButton); @@ -904,24 +884,10 @@ void CMenus::RenderSettingsTee(CUIRect MainView) SetNeedSendInfo(); } - // Quick search + static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString)); + if(Ui()->DoEditBox_Search(&s_SkinFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed())) { - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); - TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); - Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch); - static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString)); - if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()) - { - Ui()->SetActiveItem(&s_SkinFilterInput); - s_SkinFilterInput.SelectAll(); - } - s_SkinFilterInput.SetEmptyText(Localize("Search")); - if(Ui()->DoClearableEditBox(&s_SkinFilterInput, &QuickSearch, 14.0f)) - m_SkinListNeedsUpdate = true; + m_SkinListNeedsUpdate = true; } static CButtonContainer s_SkinDatabaseButton; diff --git a/src/game/client/components/menus_settings7.cpp b/src/game/client/components/menus_settings7.cpp index 5d73efdc8..a560c5be3 100644 --- a/src/game/client/components/menus_settings7.cpp +++ b/src/game/client/components/menus_settings7.cpp @@ -282,24 +282,10 @@ void CMenus::RenderSettingsTee7(CUIRect MainView) } } - // Quick search + static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString)); + if(Ui()->DoEditBox_Search(&s_SkinFilterInput, &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed())) { - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); - TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); - Ui()->DoLabel(&QuickSearch, FontIcons::FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - float SearchWidth = TextRender()->TextWidth(14.0f, FontIcons::FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch); - static CLineInput s_SkinFilterInput(g_Config.m_ClSkinFilterString, sizeof(g_Config.m_ClSkinFilterString)); - if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()) - { - Ui()->SetActiveItem(&s_SkinFilterInput); - s_SkinFilterInput.SelectAll(); - } - s_SkinFilterInput.SetEmptyText(Localize("Search")); - if(Ui()->DoClearableEditBox(&s_SkinFilterInput, &QuickSearch, 14.0f)) - m_SkinListNeedsUpdate = true; + m_SkinListNeedsUpdate = true; } static CButtonContainer s_DirectoryButton; diff --git a/src/game/client/components/menus_settings_assets.cpp b/src/game/client/components/menus_settings_assets.cpp index a8a0e807e..9d022bb84 100644 --- a/src/game/client/components/menus_settings_assets.cpp +++ b/src/game/client/components/menus_settings_assets.cpp @@ -352,7 +352,7 @@ int InitSearchList(std::vector &vpSearchList, std::vector void CMenus::RenderSettingsCustom(CUIRect MainView) { - CUIRect TabBar, CustomList, QuickSearch, QuickSearchClearButton, DirectoryButton, ReloadButton; + CUIRect TabBar, CustomList, QuickSearch, DirectoryButton, ReloadButton; MainView.HSplitTop(20.0f, &TabBar, &MainView); const float TabWidth = TabBar.w / NUMBER_OF_ASSETS_TABS; @@ -599,29 +599,13 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) } } - // render quick search + // Quick search + MainView.HSplitBottom(ms_ButtonHeight, &MainView, &QuickSearch); + QuickSearch.VSplitLeft(220.0f, &QuickSearch, &DirectoryButton); + QuickSearch.HSplitTop(5.0f, nullptr, &QuickSearch); + if(Ui()->DoEditBox_Search(&s_aFilterInputs[s_CurCustomTab], &QuickSearch, 14.0f, !Ui()->IsPopupOpen() && m_pClient->m_GameConsole.IsClosed())) { - MainView.HSplitBottom(ms_ButtonHeight, &MainView, &QuickSearch); - QuickSearch.VSplitLeft(240.0f, &QuickSearch, &DirectoryButton); - QuickSearch.HSplitTop(5.0f, 0, &QuickSearch); - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); - TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); - - Ui()->DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, 14.0f, TEXTALIGN_ML); - float SearchWidth = TextRender()->TextWidth(14.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - TextRender()->SetRenderFlags(0); - TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - QuickSearch.VSplitLeft(SearchWidth, 0, &QuickSearch); - QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch); - QuickSearch.VSplitLeft(QuickSearch.w - 10.0f, &QuickSearch, &QuickSearchClearButton); - if(Input()->KeyPress(KEY_F) && Input()->ModifierIsPressed()) - { - Ui()->SetActiveItem(&s_aFilterInputs[s_CurCustomTab]); - s_aFilterInputs[s_CurCustomTab].SelectAll(); - } - s_aFilterInputs[s_CurCustomTab].SetEmptyText(Localize("Search")); - if(Ui()->DoClearableEditBox(&s_aFilterInputs[s_CurCustomTab], &QuickSearch, 14.0f)) - gs_aInitCustomList[s_CurCustomTab] = true; + gs_aInitCustomList[s_CurCustomTab] = true; } DirectoryButton.HSplitTop(5.0f, 0, &DirectoryButton); diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index 3a0a611cd..e0c859ac0 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -1004,6 +1004,25 @@ bool CUi::DoClearableEditBox(CLineInput *pLineInput, const CUIRect *pRect, float return ReturnValue; } +bool CUi::DoEditBox_Search(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, bool HotkeyEnabled) +{ + CUIRect QuickSearch = *pRect; + TextRender()->SetFontPreset(EFontPreset::ICON_FONT); + TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); + DoLabel(&QuickSearch, FONT_ICON_MAGNIFYING_GLASS, FontSize, TEXTALIGN_ML); + const float SearchWidth = TextRender()->TextWidth(FontSize, FONT_ICON_MAGNIFYING_GLASS); + TextRender()->SetRenderFlags(0); + TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); + QuickSearch.VSplitLeft(SearchWidth + 5.0f, nullptr, &QuickSearch); + if(HotkeyEnabled && Input()->ModifierIsPressed() && Input()->KeyPress(KEY_F)) + { + SetActiveItem(pLineInput); + pLineInput->SelectAll(); + } + pLineInput->SetEmptyText(Localize("Search")); + return DoClearableEditBox(pLineInput, &QuickSearch, FontSize); +} + int CUi::DoButton_Menu(CUIElement &UIElement, const CButtonContainer *pId, const std::function &GetTextLambda, const CUIRect *pRect, const SMenuButtonProperties &Props) { CUIRect Text = *pRect, DropDownIcon; diff --git a/src/game/client/ui.h b/src/game/client/ui.h index 6cc7129f2..8cf21bd30 100644 --- a/src/game/client/ui.h +++ b/src/game/client/ui.h @@ -603,6 +603,24 @@ public: */ bool DoClearableEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, int Corners = IGraphics::CORNER_ALL, const std::vector &vColorSplits = {}); + /** + * Creates an input field with a search icon and a clear [x] button attached to it. + * The input will have default text "Search" and the hotkey Ctrl+F can be used to activate the input. + * + * @see DoEditBox + * + * @param pLineInput This pointer will be stored and written to on next user input. + * So you can not pass in a pointer that goes out of scope such as a local variable. + * Pass in either a member variable of the current class or a static variable. + * For example ```static CLineInputBuffered s_MyInput;``` + * @param pRect the UI rect it will attach to + * @param FontSize Size of the font (`10.0f`, `12.0f` and `14.0f` are commonly used here) + * @param HotkeyEnabled Whether the hotkey to enable this editbox is currently enabled. + * + * @return true if the value of the input field changed since the last call. + */ + bool DoEditBox_Search(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, bool HotkeyEnabled); + int DoButton_Menu(CUIElement &UIElement, const CButtonContainer *pId, const std::function &GetTextLambda, const CUIRect *pRect, const SMenuButtonProperties &Props = {}); // only used for popup menus int DoButton_PopupMenu(CButtonContainer *pButtonContainer, const char *pText, const CUIRect *pRect, float Size, int Align, float Padding = 0.0f, bool TransparentInactive = false, bool Enabled = true);