From 447cef95951ac950c8e27abca93120330198ccea Mon Sep 17 00:00:00 2001 From: Jordy Ruiz Date: Thu, 1 Nov 2018 13:38:58 +0100 Subject: [PATCH] Implemented independent dropdowns. Redesigned the controls menus, with a scrollbar. --- src/game/client/components/menus.cpp | 44 +++++++++++++++ src/game/client/components/menus.h | 3 +- src/game/client/components/menus_browser.cpp | 8 +-- src/game/client/components/menus_settings.cpp | 56 +++++++++++++++++-- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 1a6d66807..2378519b5 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -633,6 +633,50 @@ float CMenus::DoDropdownMenu(void *pID, const CUIRect *pRect, const char *pStr, return HeaderHeight; } +float CMenus::DoIndependentDropdownMenu(void *pID, const CUIRect *pRect, const char *pStr, float HeaderHeight, FDropdownCallback pfnCallback, bool* pActive) +{ + CUIRect View = *pRect; + CUIRect Header, Label; + + bool Active = *pActive; + int Corners = Active ? CUI::CORNER_T : CUI::CORNER_ALL; + + View.HSplitTop(HeaderHeight, &Header, &View); + + // background + RenderTools()->DrawUIRect(&Header, vec4(0.0f, 0.0f, 0.0f, 0.25f), Corners, 5.0f); + + // render icon + CUIRect Button; + Header.VSplitLeft(Header.h, &Button, 0); + Button.Margin(2.0f, &Button); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_MENUICONS].m_Id); + Graphics()->QuadsBegin(); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, UI()->HotItem() == pID ? 1.0f : 0.6f); + if(Active) + RenderTools()->SelectSprite(SPRITE_MENU_EXPANDED); + else + RenderTools()->SelectSprite(SPRITE_MENU_COLLAPSED); + IGraphics::CQuadItem QuadItem(Button.x, Button.y, Button.w, Button.h); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); + Graphics()->QuadsEnd(); + + // label + Label = Header; + Label.y += 2.0f; + UI()->DoLabel(&Label, pStr, Header.h*ms_FontmodHeight*0.8f, CUI::ALIGN_CENTER); + + if(UI()->DoButtonLogic(pID, 0, 0, &Header)) + *pActive ^= 1; + + // render content of expanded menu + if(Active) + return HeaderHeight + pfnCallback(View, this); + + return HeaderHeight; +} + void CMenus::DoInfoBox(const CUIRect *pRect, const char *pLabel, const char *pValue) { RenderTools()->DrawUIRect(pRect, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f); diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index fced438b4..6806edd8a 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -83,6 +83,7 @@ private: void DoEditBoxOption(void *pID, char *pOption, int OptionLength, const CUIRect *pRect, const char *pStr, float VSplitVal, float *pOffset, bool Hidden=false); void DoScrollbarOption(void *pID, int *pOption, const CUIRect *pRect, const char *pStr, float VSplitVal, int Min, int Max, bool infinite=false); float DoDropdownMenu(void *pID, const CUIRect *pRect, const char *pStr, float HeaderHeight, FDropdownCallback pfnCallback); + float DoIndependentDropdownMenu(void *pID, const CUIRect *pRect, const char *pStr, float HeaderHeight, FDropdownCallback pfnCallback, bool* pActive); void DoInfoBox(const CUIRect *pRect, const char *pLable, const char *pValue); //static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false); @@ -523,7 +524,7 @@ private: void RenderServerControlServer(CUIRect MainView); // found in menus_browser.cpp - int m_ScrollOffset; + // int m_ScrollOffset; void RenderServerbrowserServerList(CUIRect View); void RenderServerbrowserFriendList(CUIRect View); void RenderServerbrowserServerDetail(CUIRect View, const CServerInfo *pInfo); diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index c76bf9ec1..d0d8b63ec 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -1051,11 +1051,11 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) int ScrollNum = (int)((ListHeight-View.h)/ms_aBrowserCols[0].m_Rect.h)+1; if(ScrollNum > 0) { - if(m_ScrollOffset) + /*if(m_ScrollOffset) { s_ScrollValue = (float)(m_ScrollOffset)/ScrollNum; m_ScrollOffset = 0; - } + }*/ 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)) @@ -1772,11 +1772,11 @@ void CMenus::RenderServerbrowserFriendList(CUIRect View) int ScrollNum = (int)((ListHeight - View.h) / ms_aBrowserCols[0].m_Rect.h) + 1; if(ScrollNum > 0) { - if(m_ScrollOffset) + /*if(m_ScrollOffset) { s_ScrollValue = (float)(m_ScrollOffset) / ScrollNum; m_ScrollOffset = 0; - } + }*/ 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)) diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 68ceb512a..8153cab62 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1162,26 +1162,70 @@ void CMenus::RenderSettingsControls(CUIRect MainView) MainView.HSplitBottom(80.0f, &MainView, &BottomView); BottomView.HSplitTop(20.f, 0, &BottomView); - float HeaderHeight = 20.0f; + // split scrollbar from main view + CUIRect Scroll; + MainView.VSplitRight(20.0f, &MainView, &Scroll); + RenderTools()->DrawUIRect(&Scroll, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(&MainView, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 5.0f); + const float HeaderHeight = 20.0f; + const float ItemHeight = 20.0f+2.0f; + const float MainViewH = MainView.h; + + // make scrollbar + static int s_ScrollBar = 0; + static int s_ScrollNum = 0; + static float s_ScrollValue = 0.f; + static float TotalHeight = 0.f; + Scroll.HMargin(5.0f, &Scroll); + s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + + UI()->ClipEnable(&MainView); + if(TotalHeight - MainView.h > 0) + MainView.y -= s_ScrollValue*(TotalHeight - MainView.h); + + TotalHeight = 0.f; static int s_MovementDropdown = 0; - float Split = DoDropdownMenu(&s_MovementDropdown, &MainView, Localize("Movement"), HeaderHeight, RenderSettingsControlsMovement); + static bool s_MovementActive = true; + float Split = DoIndependentDropdownMenu(&s_MovementDropdown, &MainView, Localize("Movement"), HeaderHeight, RenderSettingsControlsMovement, &s_MovementActive); + TotalHeight += Split+10.0f; MainView.HSplitTop(Split+10.0f, 0, &MainView); static int s_WeaponDropdown = 0; - Split = DoDropdownMenu(&s_WeaponDropdown, &MainView, Localize("Weapon"), HeaderHeight, RenderSettingsControlsWeapon); + static bool s_WeaponActive = true; + Split = DoIndependentDropdownMenu(&s_WeaponDropdown, &MainView, Localize("Weapon"), HeaderHeight, RenderSettingsControlsWeapon, &s_WeaponActive); + TotalHeight += Split+10.0f; MainView.HSplitTop(Split+10.0f, 0, &MainView); static int s_VotingDropdown = 0; - Split = DoDropdownMenu(&s_VotingDropdown, &MainView, Localize("Voting"), HeaderHeight, RenderSettingsControlsVoting); + static bool s_VotingActive = true; + Split = DoIndependentDropdownMenu(&s_VotingDropdown, &MainView, Localize("Voting"), HeaderHeight, RenderSettingsControlsVoting, &s_VotingActive); + TotalHeight += Split+10.0f; MainView.HSplitTop(Split+10.0f, 0, &MainView); static int s_ChatDropdown = 0; - Split = DoDropdownMenu(&s_ChatDropdown, &MainView, Localize("Chat"), HeaderHeight, RenderSettingsControlsChat); + static bool s_ChatActive = true; + Split = DoIndependentDropdownMenu(&s_ChatDropdown, &MainView, Localize("Chat"), HeaderHeight, RenderSettingsControlsChat, &s_ChatActive); + TotalHeight += Split+10.0f; MainView.HSplitTop(Split+10.0f, 0, &MainView); static int s_MiscDropdown = 0; - Split = DoDropdownMenu(&s_MiscDropdown, &MainView, Localize("Misc"), HeaderHeight, RenderSettingsControlsMisc); + static bool s_MiscActive = true; + Split = DoIndependentDropdownMenu(&s_MiscDropdown, &MainView, Localize("Misc"), HeaderHeight, RenderSettingsControlsMisc, &s_MiscActive); + TotalHeight += Split; + UI()->ClipDisable(); + + // handle scrolling + float ProperHeight = (TotalHeight-5*HeaderHeight-40.0f); + s_ScrollNum = /*ceil*/((ProperHeight-MainViewH)/ItemHeight); + if(s_ScrollNum <= 0) + s_ScrollNum = 1; + // We could && UI()->MouseInside(&MainView)), but that does not work well because the controls settings menu got holes + if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP)) + s_ScrollValue -= 3.0f/s_ScrollNum; // will be set to 0 by clamp if scrollnum is too small + if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN)) + s_ScrollValue += 3.0f/s_ScrollNum; // will be set to 1 by clamp if scrollnum is too small + s_ScrollValue = clamp(s_ScrollValue, 0.f, 1.f); // reset button float Spacing = 3.0f;