diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 62996e481..9bc7a3f71 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -40,10 +42,13 @@ ColorRGBA CMenus::ms_GuiColor; ColorRGBA CMenus::ms_ColorTabbarInactiveOutgame; ColorRGBA CMenus::ms_ColorTabbarActiveOutgame; +ColorRGBA CMenus::ms_ColorTabbarHoverOutgame; ColorRGBA CMenus::ms_ColorTabbarInactive; -ColorRGBA CMenus::ms_ColorTabbarActive = ColorRGBA(0,0,0,0.5f); +ColorRGBA CMenus::ms_ColorTabbarActive = ColorRGBA(0, 0, 0, 0.5f); +ColorRGBA CMenus::ms_ColorTabbarHover; ColorRGBA CMenus::ms_ColorTabbarInactiveIngame; ColorRGBA CMenus::ms_ColorTabbarActiveIngame; +ColorRGBA CMenus::ms_ColorTabbarHoverIngame; float CMenus::ms_ButtonHeight = 25.0f; float CMenus::ms_ListheaderHeight = 17.0f; @@ -189,12 +194,32 @@ void CMenus::DoButton_KeySelect(const void *pID, const char *pText, int Checked, UI()->DoLabel(&Temp, pText, Temp.h*ms_FontmodHeight, 0); } -int CMenus::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners) +int CMenus::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners, const ColorRGBA *pDefaultColor, const ColorRGBA *pActiveColor, const ColorRGBA *pHoverColor, float EdgeRounding) { if(Checked) - RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, Corners, 10.0f); + { + ColorRGBA ColorMenuTab = ms_ColorTabbarActive; + if(pActiveColor) + ColorMenuTab = *pActiveColor; + RenderTools()->DrawUIRect(pRect, ColorMenuTab, Corners, EdgeRounding); + } else - RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, Corners, 10.0f); + { + if(UI()->MouseInside(pRect)) + { + ColorRGBA HoverColorMenuTab = ms_ColorTabbarHover; + if(pHoverColor) + HoverColorMenuTab = *pHoverColor; + RenderTools()->DrawUIRect(pRect, HoverColorMenuTab, Corners, EdgeRounding); + } + else + { + ColorRGBA ColorMenuTab = ms_ColorTabbarInactive; + if(pDefaultColor) + ColorMenuTab = *pDefaultColor; + RenderTools()->DrawUIRect(pRect, ColorMenuTab, Corners, EdgeRounding); + } + } CUIRect Temp; pRect->HMargin(2.0f, &Temp); UI()->DoLabel(&Temp, pText, Temp.h*ms_FontmodHeight, 0); @@ -500,7 +525,7 @@ int CMenus::DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, CUIRect EditBox; CUIRect ClearButton; pRect->VSplitRight(15.0f, &EditBox, &ClearButton); - if(DoEditBox(pID, &EditBox, pStr, StrSize, FontSize, Offset, Hidden, Corners&~CUI::CORNER_R, pEmptyText)) + if(DoEditBox(pID, &EditBox, pStr, StrSize, FontSize, Offset, Hidden, Corners & ~CUI::CORNER_R, pEmptyText)) { ReturnValue = true; } @@ -556,25 +581,26 @@ float CMenus::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) UI()->SetHotItem(pID); // render - CUIRect Rail; - pRect->VMargin(5.0f, &Rail); - RenderTools()->DrawUIRect(&Rail, ColorRGBA(1,1,1,0.25f), 0, 0.0f); + RenderTools()->DrawUIRect(pRect, ColorRGBA(0, 0, 0, 0.25f), CUI::CORNER_ALL, 2.5f); CUIRect Slider = Handle; - Slider.w = Rail.x-Slider.x; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1,1,1,0.25f), CUI::CORNER_L, 2.5f); - Slider.x = Rail.x+Rail.w; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1,1,1,0.25f), CUI::CORNER_R, 2.5f); + RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 2.5f); + Slider.Margin(2, &Slider); - Slider = Handle; - Slider.Margin(5.0f, &Slider); - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1,1,1,0.25f*ButtonColorMul(pID)), CUI::CORNER_ALL, 2.5f); + float ColorSlider = 0; + + if(UI()->ActiveItem() == pID) + ColorSlider = 1.0f; + else if(UI()->HotItem() == pID) + ColorSlider = 0.9f; + else + ColorSlider = 0.75f; + + RenderTools()->DrawUIRect(&Slider, ColorRGBA(ColorSlider, ColorSlider, ColorSlider, 0.75f), CUI::CORNER_ALL, 2.5f); return ReturnValue; } - - float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) { CUIRect Handle; @@ -732,7 +758,33 @@ int CMenus::RenderMenubar(CUIRect r) TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_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_OVERSIZE); - if(DoButton_MenuTab(&s_StartButton, "\xEE\xA2\x8A", false, &Button, CUI::CORNER_T)) + bool GotNewsOrUpdate = false; + +#if defined(CONF_AUTOUPDATE) + int State = Updater()->GetCurrentState(); + bool NeedUpdate = str_comp(Client()->LatestVersion(), "0"); + if(State == IUpdater::CLEAN && NeedUpdate) + { + GotNewsOrUpdate = true; + } +#endif + + GotNewsOrUpdate |= (bool)g_Config.m_UiUnreadNews; + + ColorRGBA HomeButtonColorAlert(0, 1, 0, 0.25f); + ColorRGBA HomeButtonColorAlertHover(0, 1, 0, 0.5f); + ColorRGBA *pHomeButtonColor = NULL; + ColorRGBA *pHomeButtonColorHover = NULL; + + const char *pHomeScreenButtonLabel = "\xEE\xA2\x8A"; + if(GotNewsOrUpdate) + { + pHomeScreenButtonLabel = "\xEE\x80\xB1"; + pHomeButtonColor = &HomeButtonColorAlert; + pHomeButtonColorHover = &HomeButtonColorAlertHover; + } + + if(DoButton_MenuTab(&s_StartButton, pHomeScreenButtonLabel, false, &Button, CUI::CORNER_T, pHomeButtonColor, pHomeButtonColor, pHomeButtonColorHover)) { m_ShowStart = true; m_DoubleClickIndex = -1; @@ -868,8 +920,9 @@ int CMenus::RenderMenubar(CUIRect r) 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_OVERSIZE); Box.VSplitRight(33.0f, &Box, &Button); - static int s_QuitButton=0; - if(DoButton_MenuTab(&s_QuitButton, "\xEE\x97\x8D", 0, &Button, CUI::CORNER_T)) + static int s_QuitButton = 0; + ColorRGBA QuitColor(1, 0, 0, 0.5f); + if(DoButton_MenuTab(&s_QuitButton, "\xEE\x97\x8D", 0, &Button, CUI::CORNER_T, NULL, NULL, &QuitColor)) { if(m_pClient->Editor()->HasUnsavedData() || (Client()->GetCurrentRaceTime() / 60 >= g_Config.m_ClConfirmQuitTime && g_Config.m_ClConfirmQuitTime >= 0)) { @@ -1106,12 +1159,14 @@ int CMenus::Render() { ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame; ms_ColorTabbarActive = ms_ColorTabbarActiveIngame; + ms_ColorTabbarHover = ms_ColorTabbarHoverIngame; } else { RenderBackground(); ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame; ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame; + ms_ColorTabbarHover = ms_ColorTabbarHoverOutgame; } CUIRect TabBar; @@ -2124,16 +2179,18 @@ void CMenus::OnRender() // update colors ms_GuiColor = color_cast(ColorHSLA(g_Config.m_UiColor, true)); - ms_ColorTabbarInactiveOutgame = ColorRGBA(0,0,0,0.25f); - ms_ColorTabbarActiveOutgame = ColorRGBA(0,0,0,0.5f); + ms_ColorTabbarInactiveOutgame = ColorRGBA(0, 0, 0, 0.25f); + ms_ColorTabbarActiveOutgame = ColorRGBA(0, 0, 0, 0.5f); + ms_ColorTabbarHoverOutgame = ColorRGBA(1, 1, 1, 0.25f); float ColorIngameScaleI = 0.5f; float ColorIngameAcaleA = 0.2f; + ms_ColorTabbarInactiveIngame = ColorRGBA( - ms_GuiColor.r*ColorIngameScaleI, - ms_GuiColor.g*ColorIngameScaleI, - ms_GuiColor.b*ColorIngameScaleI, - ms_GuiColor.a*0.8f); + ms_GuiColor.r * ColorIngameScaleI, + ms_GuiColor.g * ColorIngameScaleI, + ms_GuiColor.b * ColorIngameScaleI, + ms_GuiColor.a * 0.8f); ms_ColorTabbarActiveIngame = ColorRGBA( ms_GuiColor.r*ColorIngameAcaleA, @@ -2141,6 +2198,8 @@ void CMenus::OnRender() ms_GuiColor.b*ColorIngameAcaleA, ms_GuiColor.a); + ms_ColorTabbarHoverIngame = ColorRGBA(1, 1, 1, 0.75f); + // update the ui CUIRect *pScreen = UI()->Screen(); float mx = (m_MousePos.x/(float)Graphics()->ScreenWidth())*pScreen->w; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 46befc717..6bfdfb3d5 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -39,10 +39,13 @@ class CMenus : public CComponent static ColorRGBA ms_GuiColor; static ColorRGBA ms_ColorTabbarInactiveOutgame; static ColorRGBA ms_ColorTabbarActiveOutgame; + static ColorRGBA ms_ColorTabbarHoverOutgame; static ColorRGBA ms_ColorTabbarInactiveIngame; static ColorRGBA ms_ColorTabbarActiveIngame; + static ColorRGBA ms_ColorTabbarHoverIngame; static ColorRGBA ms_ColorTabbarInactive; static ColorRGBA ms_ColorTabbarActive; + static ColorRGBA ms_ColorTabbarHover; float ButtonColorMul(const void *pID); @@ -50,7 +53,7 @@ class CMenus : public CComponent int DoButton_Sprite(const void *pID, int ImageID, int SpriteID, int Checked, const CUIRect *pRect, int Corners); int DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect, bool Active); int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName = 0, int Corners = CUI::CORNER_ALL, float r = 5.0f, float FontFactor = 0.0f, vec4 ColorHot = vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4 Color = vec4(1, 1, 1, 0.5f)); - int DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners); + int DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners, const ColorRGBA *pDefaultColor = NULL, const ColorRGBA *pActiveColor = NULL, const ColorRGBA *pHoverColor = NULL, float EdgeRounding = 10); int DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect); int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect); @@ -72,8 +75,8 @@ class CMenus : public CComponent static void ui_draw_checkbox(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); */ - int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden=false, int Corners=CUI::CORNER_ALL, const char *pEmptyText = ""); - int DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden=false, int Corners=CUI::CORNER_ALL, const char *pEmptyText = ""); + int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden = false, int Corners = CUI::CORNER_ALL, const char *pEmptyText = ""); + int DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden = false, int Corners = CUI::CORNER_ALL, const char *pEmptyText = ""); //static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false); float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); @@ -93,8 +96,8 @@ class CMenus : public CComponent }; void UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems, - int ItemsPerRow, int SelectedIndex, float ScrollValue); - CListboxItem UiDoListboxNextItem(const void *pID, bool Selected = false, bool KeyEvents = true); + int ItemsPerRow, int SelectedIndex, float ScrollValue); + CListboxItem UiDoListboxNextItem(const void *pID, bool Selected = false, bool KeyEvents = true, bool NoHoverEffects = false); CListboxItem UiDoListboxNextRow(); int UiDoListboxEnd(float *pScrollValue, bool *pItemActivated, bool *pListBoxActive = 0); diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 252c78add..8e55bb7e9 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -28,7 +28,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) CUIRect Status; View.HSplitTop(ms_ListheaderHeight, &Headers, &View); - View.HSplitBottom(28.0f, &View, &Status); + View.HSplitBottom(80.0f + 10.0f, &View, &Status); // split of the scrollbar RenderTools()->DrawUIRect(&Headers, ColorRGBA(1,1,1,0.25f), CUI::CORNER_T, 5.0f); @@ -300,8 +300,15 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) SelectHitBox.h -= OriginalView.y-SelectHitBox.y; SelectHitBox.y = OriginalView.y; } - else if(SelectHitBox.y+SelectHitBox.h > OriginalView.y+OriginalView.h) // bottom - SelectHitBox.h = OriginalView.y+OriginalView.h-SelectHitBox.y; + else if(SelectHitBox.y + SelectHitBox.h > OriginalView.y + OriginalView.h) // bottom + SelectHitBox.h = OriginalView.y + OriginalView.h - SelectHitBox.y; + + if(!Selected && UI()->MouseInside(&SelectHitBox)) + { + CUIRect r = Row; + r.Margin(0.5f, &r); + RenderTools()->DrawUIRect(&r, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f); + } if(UI()->DoButtonLogic(pItem, "", Selected, &SelectHitBox)) { @@ -490,25 +497,56 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) Client()->Connect(g_Config.m_UiServerAddress); } - RenderTools()->DrawUIRect(&Status, ColorRGBA(1,1,1,0.25f), CUI::CORNER_B, 5.0f); + RenderTools()->DrawUIRect(&Status, ms_ColorTabbarActive, CUI::CORNER_B, 5.0f); Status.Margin(5.0f, &Status); - CUIRect QuickSearch, QuickExclude, Button, Status2, Status3; - Status.VSplitRight(250.0f, &Status2, &Status3); + CUIRect SearchInfoAndAddr, ServersAndConnect, Status3; + Status.VSplitRight(200.0f, &SearchInfoAndAddr, &ServersAndConnect); + if(SearchInfoAndAddr.w > 500.0f) + SearchInfoAndAddr.VSplitLeft(500.0f, &SearchInfoAndAddr, NULL); + CUIRect SearchAndInfo, ServerAddr, ConnectButtons; + SearchInfoAndAddr.HSplitTop(60.0f, &SearchAndInfo, &ServerAddr); + ServersAndConnect.HSplitTop(30.0f, &Status3, &ConnectButtons); + CUIRect QuickSearch, QuickExclude; + + CUIRect SearchInfoText, QuickExcludeAndSearch; + SearchAndInfo.HSplitTop(20.f, &SearchInfoText, &QuickExcludeAndSearch); + QuickExcludeAndSearch.HSplitTop(20.f, &QuickSearch, &QuickExclude); + QuickSearch.Margin(2.f, &QuickSearch); + QuickExclude.Margin(2.f, &QuickExclude); + + float SearchStrWidth = TextRender()->TextWidth(0, 14.0f, Localize("Search:"), -1, -1.0f); + float ExcludeStrWidth = TextRender()->TextWidth(0, 14.0f, Localize("Exclude:"), -1, -1.0f); + float ServerAddrStrWidth = TextRender()->TextWidth(0, 14.0f, Localize("Server address:"), -1, -1.0f); + + float SearchExcludeAddrStrMax = maximum(maximum(SearchStrWidth, ExcludeStrWidth), ServerAddrStrWidth); + + float SearchIconWidth = 0; + float ExcludeIconWidth = 0; + float ExcludeSearchIconMax = 0; + const char *pSearchLabel = "\xEE\xA2\xB6"; // U+0e8b6 + const char *pExcludeLabel = "\xEE\x85\x8B"; // U+0e14b + + SearchInfoText.Margin(2.f, &SearchInfoText); + UI()->DoLabelScaled(&SearchInfoText, Localize("Search servers:"), 14.0f, -1); - Status2.VSplitMid(&QuickSearch, &QuickExclude); - QuickExclude.VSplitLeft(5.0f, 0, &QuickExclude); // render quick search { - const char *pLabel = "\xEE\xA2\xB6"; // U+0e8b6 TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_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_OVERSIZE); - UI()->DoLabelScaled(&QuickSearch, pLabel, 16.0f, -1); - float w = TextRender()->TextWidth(0, 16.0f, pLabel, -1, -1.0f); + UI()->DoLabelScaled(&QuickSearch, pSearchLabel, 16.0f, -1); + SearchIconWidth = TextRender()->TextWidth(0, 16.0f, pSearchLabel, -1, -1.0f); + ExcludeIconWidth = TextRender()->TextWidth(0, 16.0f, pExcludeLabel, -1, -1.0f); + ExcludeSearchIconMax = maximum(SearchIconWidth, ExcludeIconWidth); TextRender()->SetRenderFlags(0); TextRender()->SetCurFont(NULL); - QuickSearch.VSplitLeft(w, 0, &QuickSearch); + QuickSearch.VSplitLeft(ExcludeSearchIconMax, 0, &QuickSearch); QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch); + + UI()->DoLabelScaled(&QuickSearch, Localize("Search:"), 14.0f, -1); + QuickSearch.VSplitLeft(SearchExcludeAddrStrMax, 0, &QuickSearch); + QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch); + static float Offset = 0.0f; if(Input()->KeyPress(KEY_F) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL))) UI()->SetActiveItem(&g_Config.m_BrFilterString); @@ -519,16 +557,18 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) // render quick exclude { - const char *pLabel = "\xEE\x85\x8B"; // U+0e14b TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_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_OVERSIZE); - UI()->DoLabelScaled(&QuickExclude, pLabel, 16.0f, -1); - float w = TextRender()->TextWidth(0, 16.0f, pLabel, -1, -1.0f); + UI()->DoLabelScaled(&QuickExclude, pExcludeLabel, 16.0f, -1); TextRender()->SetRenderFlags(0); TextRender()->SetCurFont(NULL); - QuickExclude.VSplitLeft(w, 0, &QuickExclude); + QuickExclude.VSplitLeft(ExcludeSearchIconMax, 0, &QuickExclude); QuickExclude.VSplitLeft(5.0f, 0, &QuickExclude); - QuickExclude.VSplitLeft(QuickExclude.w-15.0f, &QuickExclude, &Button); + + UI()->DoLabelScaled(&QuickExclude, Localize("Exclude:"), 14.0f, -1); + QuickExclude.VSplitLeft(SearchExcludeAddrStrMax, 0, &QuickExclude); + QuickExclude.VSplitLeft(5.0f, 0, &QuickExclude); + static int s_ClearButton = 0; static float Offset = 0.0f; if(Input()->KeyPress(KEY_X) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL))) @@ -538,10 +578,80 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) } // render status - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers, %d players"), ServerBrowser()->NumSortedServers(), ServerBrowser()->NumServers(), NumPlayers); - Status3.VSplitRight(TextRender()->TextWidth(0, 14.0f, aBuf, -1, -1.0f), 0, &Status3); - UI()->DoLabelScaled(&Status3, aBuf, 14.0f, -1); + char aBufSvr[128]; + char aBufPyr[128]; + if(ServerBrowser()->NumSortedServers() != 1) + str_format(aBufSvr, sizeof(aBufSvr), Localize("%d of %d servers"), ServerBrowser()->NumSortedServers(), ServerBrowser()->NumServers()); + else + str_format(aBufSvr, sizeof(aBufSvr), Localize("%d of %d server"), ServerBrowser()->NumSortedServers(), ServerBrowser()->NumServers()); + if(NumPlayers != 1) + str_format(aBufPyr, sizeof(aBufPyr), Localize("%d players"), NumPlayers); + else + str_format(aBufPyr, sizeof(aBufPyr), Localize("%d player"), NumPlayers); + + CUIRect SvrsOnline, PlysOnline; + Status3.HSplitTop(20.f, &PlysOnline, &SvrsOnline); + PlysOnline.VSplitRight(TextRender()->TextWidth(0, 12.0f, aBufPyr, -1, -1.0f), 0, &PlysOnline); + UI()->DoLabelScaled(&PlysOnline, aBufPyr, 12.0f, -1); + SvrsOnline.VSplitRight(TextRender()->TextWidth(0, 12.0f, aBufSvr, -1, -1.0f), 0, &SvrsOnline); + UI()->DoLabelScaled(&SvrsOnline, aBufSvr, 12.0f, -1); + + // status box + { + CUIRect ButtonRefresh, ButtonConnect, ButtonArea; + + ServerAddr.Margin(2.0f, &ServerAddr); + + // address info + UI()->DoLabelScaled(&ServerAddr, Localize("Server address:"), 14.0f, -1); + ServerAddr.VSplitLeft(SearchExcludeAddrStrMax + 5.0f + ExcludeSearchIconMax + 5.0f, NULL, &ServerAddr); + static float Offset = 0.0f; + DoEditBox(&g_Config.m_UiServerAddress, &ServerAddr, g_Config.m_UiServerAddress, sizeof(g_Config.m_UiServerAddress), 12.0f, &Offset); + + // button area + ButtonArea = ConnectButtons; + ButtonArea.HSplitMid(&ButtonRefresh, &ButtonConnect); + ButtonRefresh.HSplitTop(5.0f, NULL, &ButtonRefresh); + ButtonConnect.HSplitTop(2.5f, NULL, &ButtonConnect); + ButtonConnect.HSplitBottom(2.5f, &ButtonConnect, NULL); + + static int s_RefreshButton = 0; + char aBuf[64]; + if(ServerBrowser()->IsRefreshing()) + str_format(aBuf, sizeof(aBuf), "%s (%d%%)", Localize("Refresh"), ServerBrowser()->LoadingProgression()); + else + str_copy(aBuf, Localize("Refresh"), sizeof(aBuf)); + + if(DoButton_Menu(&s_RefreshButton, aBuf, 0, &ButtonRefresh, NULL, CUI::CORNER_ALL) || Input()->KeyPress(KEY_F5) || (Input()->KeyPress(KEY_R) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL)))) + { + if(g_Config.m_UiPage == PAGE_INTERNET) + ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); + else if(g_Config.m_UiPage == PAGE_LAN) + ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN); + else if(g_Config.m_UiPage == PAGE_FAVORITES) + ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES); + else if(g_Config.m_UiPage == PAGE_DDNET) + { + // start a new serverlist request + Client()->RequestDDNetInfo(); + ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET); + } + else if(g_Config.m_UiPage == PAGE_KOG) + { + // start a new serverlist request + Client()->RequestDDNetInfo(); + ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG); + } + m_DoubleClickIndex = -1; + } + + static int s_JoinButton = 0; + if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &ButtonConnect, NULL, CUI::CORNER_ALL, 5, 0, vec4(0.7f, 1, 0.7f, 0.1f), vec4(0.7f, 1, 0.7f, 0.2f)) || m_EnterPressed) + { + Client()->Connect(g_Config.m_UiServerAddress); + m_EnterPressed = false; + } + } } void CMenus::RenderServerbrowserFilters(CUIRect View) @@ -552,9 +662,10 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) // server filter ServerFilter.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFilter); - RenderTools()->DrawUIRect(&FilterHeader, ColorRGBA(1,1,1,0.25f), CUI::CORNER_T, 4.0f); - RenderTools()->DrawUIRect(&ServerFilter, ColorRGBA(0,0,0,0.15f), CUI::CORNER_B, 4.0f); - UI()->DoLabelScaled(&FilterHeader, Localize("Server filter"), FontSize+2.0f, 0); + RenderTools()->DrawUIRect(&FilterHeader, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_T, 4.0f); + + RenderTools()->DrawUIRect(&ServerFilter, ColorRGBA(0, 0, 0, 0.15f), CUI::CORNER_B, 4.0f); + UI()->DoLabelScaled(&FilterHeader, Localize("Server filter"), FontSize + 2.0f, 0); CUIRect Button, Button2; ServerFilter.VSplitLeft(5.0f, 0, &ServerFilter); @@ -658,10 +769,13 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) if(DoButton_CheckBox(&g_Config.m_BrFilterConnectingPlayers, Localize("Filter connecting players"), g_Config.m_BrFilterConnectingPlayers, &Button)) g_Config.m_BrFilterConnectingPlayers ^= 1; + CUIRect FilterTabs; + ServerFilter.HSplitBottom(23, &ServerFilter, &FilterTabs); + CUIRect ResetButton; //ServerFilter.HSplitBottom(5.0f, &ServerFilter, 0); - ServerFilter.HSplitBottom(ms_ButtonHeight-2.0f, &ServerFilter, &ResetButton); + ServerFilter.HSplitBottom(ms_ButtonHeight - 5.0f, &ServerFilter, &ResetButton); // ddnet country filters if(g_Config.m_UiPage == PAGE_DDNET) @@ -693,7 +807,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) // add more space ServerFilter.HSplitTop(5.0f, 0, &ServerFilter); ServerFilter.HSplitTop(20.0f, &Button, &ServerFilter); - ServerFilter.HSplitTop(123.0f, &ServerFilter, 0); + ServerFilter.HSplitTop(80.0f, &ServerFilter, 0); RenderTools()->DrawUIRect(&ServerFilter, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f); @@ -792,14 +906,14 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) else { char *pFilterExcludeCountries = Network == IServerBrowser::NETWORK_DDNET ? g_Config.m_BrFilterExcludeCountries : g_Config.m_BrFilterExcludeCountriesKoG; - ServerFilter.HSplitTop(17.0f, &ServerFilter, &ServerFilter); + ServerFilter.HSplitTop(15.0f, &ServerFilter, &ServerFilter); const float FlagWidth = 40.0f; const float FlagHeight = 20.0f; int MaxFlags = ServerBrowser()->NumCountries(Network); int NumFlags = ServerBrowser()->NumCountries(Network); - int PerLine = MaxFlags > 9 ? 4 : 3; + int PerLine = MaxFlags > 8 ? 5 : 4; CUIRect FlagsRect; @@ -807,7 +921,7 @@ void CMenus::RenderServerbrowserFilters(CUIRect View) while(NumFlags > 0) { - ServerFilter.HSplitTop(30.0f, &FlagsRect, &ServerFilter); + ServerFilter.HSplitTop(23.0f, &FlagsRect, &ServerFilter); for(int i = 0; i < PerLine && NumFlags > 0; i++, NumFlags--) { @@ -970,7 +1084,7 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) } // server scoreboard - //ServerScoreBoard.HSplitBottom(20.0f, &ServerScoreBoard, 0x0); + ServerScoreBoard.HSplitBottom(23.0f, &ServerScoreBoard, 0x0); if(pSelectedServer) { @@ -1109,6 +1223,8 @@ void CMenus::RenderServerbrowserFriends(CUIRect View) CUIRect ServerFriends = View, FilterHeader; const float FontSize = 10.0f; + ServerFriends.HSplitBottom(18.0f, &ServerFriends, NULL); + // header ServerFriends.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFriends); RenderTools()->DrawUIRect(&FilterHeader, ColorRGBA(1,1,1,0.25f), CUI::CORNER_T, 4.0f); @@ -1239,7 +1355,7 @@ void CMenus::RenderServerbrowser(CUIRect MainView) status box tab +-------+ */ - CUIRect ServerList, ToolBox, StatusBox, TabBar; + CUIRect ServerList, ToolBox; // background RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B, 10.0f); @@ -1247,8 +1363,6 @@ void CMenus::RenderServerbrowser(CUIRect MainView) // create server list, status box, tab bar and tool box area MainView.VSplitRight(205.0f, &ServerList, &ToolBox); - ServerList.HSplitBottom(70.0f, &ServerList, &StatusBox); - StatusBox.VSplitRight(100.0f, &StatusBox, &TabBar); ServerList.VSplitRight(5.0f, &ServerList, 0); // server list @@ -1258,41 +1372,9 @@ void CMenus::RenderServerbrowser(CUIRect MainView) int ToolboxPage = g_Config.m_UiToolboxPage; - // tab bar - { - CUIRect TabButton0, TabButton1, TabButton2; - TabBar.HSplitTop(5.0f, 0, &TabBar); - TabBar.HSplitTop(20.0f, &TabButton0, &TabBar); - TabBar.HSplitTop(2.5f, 0, &TabBar); - TabBar.HSplitTop(20.0f, &TabButton1, &TabBar); - TabBar.HSplitTop(2.5f, 0, &TabBar); - TabBar.HSplitTop(20.0f, &TabButton2, 0); - ColorRGBA Active = ms_ColorTabbarActive; - ColorRGBA InActive = ms_ColorTabbarInactive; - ms_ColorTabbarActive = ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f); - ms_ColorTabbarInactive = ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f); - - static int s_FiltersTab = 0; - if(DoButton_MenuTab(&s_FiltersTab, Localize("Filter"), ToolboxPage==0, &TabButton0, CUI::CORNER_L)) - ToolboxPage = 0; - - static int s_InfoTab = 0; - if(DoButton_MenuTab(&s_InfoTab, Localize("Info"), ToolboxPage==1, &TabButton1, CUI::CORNER_L)) - ToolboxPage = 1; - - static int s_FriendsTab = 0; - if(DoButton_MenuTab(&s_FriendsTab, Localize("Friends"), ToolboxPage==2, &TabButton2, CUI::CORNER_L)) - ToolboxPage = 2; - - ms_ColorTabbarActive = Active; - ms_ColorTabbarInactive = InActive; - g_Config.m_UiToolboxPage = ToolboxPage; - } - // tool box { - RenderTools()->DrawUIRect(&ToolBox, ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f), CUI::CORNER_T, 4.0f); - + RenderTools()->DrawUIRect(&ToolBox, ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f), CUI::CORNER_ALL, 4.0f); if(ToolboxPage == 0) RenderServerbrowserFilters(ToolBox); @@ -1302,64 +1384,35 @@ void CMenus::RenderServerbrowser(CUIRect MainView) RenderServerbrowserFriends(ToolBox); } - // status box + // tab bar { - CUIRect Button, ButtonArea; - StatusBox.HSplitTop(5.0f, 0, &StatusBox); - // button area - StatusBox.VSplitRight(170.0f, &StatusBox, &ButtonArea); - ButtonArea.HSplitTop(20.0f, &Button, &ButtonArea); - Button.VMargin(20.0f, &Button); + CUIRect TabBar; + ToolBox.HSplitBottom(18, &ToolBox, &TabBar); + CUIRect TabButton0, TabButton1, TabButton2; + float CurTabBarWidth = ToolBox.w; + TabBar.VSplitLeft(0.333f * CurTabBarWidth, &TabButton0, &TabBar); + TabBar.VSplitLeft(0.333f * CurTabBarWidth, &TabButton1, &TabBar); + TabBar.VSplitLeft(0.333f * CurTabBarWidth, &TabButton2, &TabBar); + ColorRGBA Active = ms_ColorTabbarActive; + ColorRGBA InActive = ms_ColorTabbarInactive; + ms_ColorTabbarActive = ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f); + ms_ColorTabbarInactive = ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f); - static int s_RefreshButton = 0; - char aBuf[64]; - if(ServerBrowser()->IsRefreshing()) - str_format(aBuf, sizeof(aBuf), "%s (%d%%)", Localize("Refresh"), ServerBrowser()->LoadingProgression()); - else - str_copy(aBuf, Localize("Refresh"), sizeof(aBuf)); + static int s_FiltersTab = 0; + if(DoButton_MenuTab(&s_FiltersTab, Localize("Filter"), ToolboxPage == 0, &TabButton0, CUI::CORNER_BL, NULL, NULL, NULL, 4.0f)) + ToolboxPage = 0; - if(DoButton_Menu(&s_RefreshButton, aBuf, 0, &Button) || Input()->KeyPress(KEY_F5) || (Input()->KeyPress(KEY_R) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL)))) - { - if(g_Config.m_UiPage == PAGE_INTERNET) - ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); - else if(g_Config.m_UiPage == PAGE_LAN) - ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN); - else if(g_Config.m_UiPage == PAGE_FAVORITES) - ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES); - else if(g_Config.m_UiPage == PAGE_DDNET) - { - // start a new serverlist request - Client()->RequestDDNetInfo(); - ServerBrowser()->Refresh(IServerBrowser::TYPE_DDNET); - } - else if(g_Config.m_UiPage == PAGE_KOG) - { - // start a new serverlist request - Client()->RequestDDNetInfo(); - ServerBrowser()->Refresh(IServerBrowser::TYPE_KOG); - } - m_DoubleClickIndex = -1; - } + static int s_InfoTab = 0; + if(DoButton_MenuTab(&s_InfoTab, Localize("Info"), ToolboxPage == 1, &TabButton1, 0, NULL, NULL, NULL, 4.0f)) + ToolboxPage = 1; - ButtonArea.HSplitTop(5.0f, 0, &ButtonArea); - ButtonArea.HSplitTop(20.0f, &Button, &ButtonArea); - Button.VMargin(20.0f, &Button); + static int s_FriendsTab = 0; + if(DoButton_MenuTab(&s_FriendsTab, Localize("Friends"), ToolboxPage == 2, &TabButton2, CUI::CORNER_BR, NULL, NULL, NULL, 4.0f)) + ToolboxPage = 2; - static int s_JoinButton = 0; - if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &Button) || m_EnterPressed) - { - Client()->Connect(g_Config.m_UiServerAddress); - m_EnterPressed = false; - } - - // address info - StatusBox.VSplitLeft(20.0f, 0, &StatusBox); - StatusBox.HSplitTop(5.0f, 0, &StatusBox); - StatusBox.HSplitTop(20.0f, &Button, &StatusBox); - UI()->DoLabelScaled(&Button, Localize("Host address"), 14.0f, -1); - StatusBox.HSplitTop(20.0f, &Button, 0); - static float Offset = 0.0f; - DoEditBox(&g_Config.m_UiServerAddress, &Button, g_Config.m_UiServerAddress, sizeof(g_Config.m_UiServerAddress), 14.0f, &Offset); + ms_ColorTabbarActive = Active; + ms_ColorTabbarInactive = InActive; + g_Config.m_UiToolboxPage = ToolboxPage; } } diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 784ffd4d6..c0f953e35 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -627,7 +627,7 @@ CMenus::CListboxItem CMenus::UiDoListboxNextRow() return Item; } -CMenus::CListboxItem CMenus::UiDoListboxNextItem(const void *pId, bool Selected, bool KeyEvents) +CMenus::CListboxItem CMenus::UiDoListboxNextItem(const void *pId, bool Selected, bool KeyEvents, bool NoHoverEffects) { int ThisItemIndex = gs_ListBoxItemIndex; if(Selected) @@ -707,6 +707,12 @@ CMenus::CListboxItem CMenus::UiDoListboxNextItem(const void *pId, bool Selected, r.Margin(1.5f, &r); RenderTools()->DrawUIRect(&r, ColorRGBA(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); } + else if(UI()->MouseInside(&Item.m_Rect) && !NoHoverEffects) + { + CUIRect r = Item.m_Rect; + r.Margin(1.5f, &r); + RenderTools()->DrawUIRect(&r, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f); + } return Item; } diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 0b9951395..0d9015bed 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -792,7 +792,7 @@ void CMenus::RenderSettingsControls(CUIRect MainView) UiDoListboxStart(&s_ControlsList , &MainView, 475.0f, Localize("Controls"), "", 1, 1, s_SelectedControl, s_ScrollValue); CUIRect MovementSettings, WeaponSettings, VotingSettings, ChatSettings, MiscSettings, ResetButton; - CListboxItem Item = UiDoListboxNextItem(&OldSelected, false, false); + CListboxItem Item = UiDoListboxNextItem(&OldSelected, false, false, true); Item.m_Rect.HSplitTop(10.0f, 0, &Item.m_Rect); Item.m_Rect.VSplitMid(&MovementSettings, &VotingSettings);