void CMenus::RenderServerbrowserServerDetail(CUIRect View) { CUIRect ServerDetails = View; CUIRect ServerScoreBoard, ServerHeader; const CServerInfo *pSelectedServer = ServerBrowser()->SortedGet(m_SelectedIndex); // split off a piece to use for scoreboard ServerDetails.HSplitTop(90.0f, &ServerDetails, &ServerScoreBoard); ServerDetails.HSplitBottom(2.5f, &ServerDetails, 0x0); // server details CTextCursor Cursor; const float FontSize = 12.0f; ServerDetails.HSplitTop(ms_ListheaderHeight, &ServerHeader, &ServerDetails); RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); RenderTools()->DrawUIRect(&ServerDetails, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); UI()->DoLabelScaled(&ServerHeader, Localize("Server details"), FontSize+2.0f, 0); if (pSelectedServer) { ServerDetails.VSplitLeft(5.0f, 0, &ServerDetails); ServerDetails.Margin(3.0f, &ServerDetails); CUIRect Row; static CLocConstString s_aLabels[] = { "Version", // Localize - these strings are localized within CLocConstString "Game type", "Ping"}; CUIRect LeftColumn; CUIRect RightColumn; // { CUIRect Button; ServerDetails.HSplitBottom(20.0f, &ServerDetails, &Button); Button.VSplitLeft(5.0f, 0, &Button); static int s_AddFavButton = 0; if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), pSelectedServer->m_Favorite, &Button)) { if(pSelectedServer->m_Favorite) ServerBrowser()->RemoveFavorite(pSelectedServer->m_NetAddr); else ServerBrowser()->AddFavorite(pSelectedServer->m_NetAddr); } } ServerDetails.VSplitLeft(5.0f, 0x0, &ServerDetails); ServerDetails.VSplitLeft(80.0f, &LeftColumn, &RightColumn); for (unsigned int i = 0; i < sizeof(s_aLabels) / sizeof(s_aLabels[0]); i++) { LeftColumn.HSplitTop(15.0f, &Row, &LeftColumn); UI()->DoLabelScaled(&Row, s_aLabels[i], FontSize, -1); } RightColumn.HSplitTop(15.0f, &Row, &RightColumn); TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Row.w; TextRender()->TextEx(&Cursor, pSelectedServer->m_aVersion, -1); RightColumn.HSplitTop(15.0f, &Row, &RightColumn); TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Row.w; TextRender()->TextEx(&Cursor, pSelectedServer->m_aGameType, -1); char aTemp[16]; str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_Latency); RightColumn.HSplitTop(15.0f, &Row, &RightColumn); TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Row.w; TextRender()->TextEx(&Cursor, aTemp, -1); } // server scoreboard ServerScoreBoard.HSplitBottom(20.0f, &ServerScoreBoard, 0x0); ServerScoreBoard.HSplitTop(ms_ListheaderHeight, &ServerHeader, &ServerScoreBoard); RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); RenderTools()->DrawUIRect(&ServerScoreBoard, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); UI()->DoLabelScaled(&ServerHeader, Localize("Scoreboard"), FontSize+2.0f, 0); if(pSelectedServer) { ServerScoreBoard.Margin(3.0f, &ServerScoreBoard); for (int i = 0; i < pSelectedServer->m_NumClients; i++) { CUIRect Name, Clan, Score, Flag; ServerScoreBoard.HSplitTop(25.0f, &Name, &ServerScoreBoard); if(UI()->DoButtonLogic(&pSelectedServer->m_aClients[i], "", 0, &Name)) { if(pSelectedServer->m_aClients[i].m_FriendState == IFriends::FRIEND_PLAYER) m_pClient->Friends()->RemoveFriend(pSelectedServer->m_aClients[i].m_aName, pSelectedServer->m_aClients[i].m_aClan); else m_pClient->Friends()->AddFriend(pSelectedServer->m_aClients[i].m_aName, pSelectedServer->m_aClients[i].m_aClan); FriendlistOnUpdate(); Client()->ServerBrowserUpdate(); } vec4 Colour = pSelectedServer->m_aClients[i].m_FriendState == IFriends::FRIEND_NO ? vec4(1.0f, 1.0f, 1.0f, (i%2+1)*0.05f) : vec4(0.5f, 1.0f, 0.5f, 0.15f+(i%2+1)*0.05f); RenderTools()->DrawUIRect(&Name, Colour, CUI::CORNER_ALL, 4.0f); Name.VSplitLeft(5.0f, 0, &Name); Name.VSplitLeft(30.0f, &Score, &Name); Name.VSplitRight(34.0f, &Name, &Flag); Flag.HMargin(4.0f, &Flag); Name.HSplitTop(11.0f, &Name, &Clan); // score if(pSelectedServer->m_aClients[i].m_Player) { char aTemp[16]; str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_aClients[i].m_Score); TextRender()->SetCursor(&Cursor, Score.x, Score.y+(Score.h-FontSize)/4.0f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Score.w; TextRender()->TextEx(&Cursor, aTemp, -1); } // name TextRender()->SetCursor(&Cursor, Name.x, Name.y, FontSize-2, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Name.w; const char *pName = pSelectedServer->m_aClients[i].m_aName; if(g_Config.m_BrFilterString[0]) { // highlight the parts that matches const char *s = str_find_nocase(pName, g_Config.m_BrFilterString); if(s) { TextRender()->TextEx(&Cursor, pName, (int)(s-pName)); TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1.0f); TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString)); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1); } else TextRender()->TextEx(&Cursor, pName, -1); } else TextRender()->TextEx(&Cursor, pName, -1); // clan TextRender()->SetCursor(&Cursor, Clan.x, Clan.y, FontSize-2, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Clan.w; const char *pClan = pSelectedServer->m_aClients[i].m_aClan; if(g_Config.m_BrFilterString[0]) { // highlight the parts that matches const char *s = str_find_nocase(pClan, g_Config.m_BrFilterString); if(s) { TextRender()->TextEx(&Cursor, pClan, (int)(s-pClan)); TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1.0f); TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString)); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1); } else TextRender()->TextEx(&Cursor, pClan, -1); } else TextRender()->TextEx(&Cursor, pClan, -1); // flag vec4 Color(1.0f, 1.0f, 1.0f, 0.5f); m_pClient->m_pCountryFlags->Render(pSelectedServer->m_aClients[i].m_Country, &Color, Flag.x, Flag.y, Flag.w, Flag.h); } } }
void CMenus::RenderServerbrowserFriends(CUIRect View) { static int s_Inited = 0; if(!s_Inited) { FriendlistOnUpdate(); s_Inited = 1; } CUIRect ServerFriends = View, FilterHeader; const float FontSize = 10.0f; // header ServerFriends.HSplitTop(ms_ListheaderHeight, &FilterHeader, &ServerFriends); RenderTools()->DrawUIRect(&FilterHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); RenderTools()->DrawUIRect(&ServerFriends, vec4(0,0,0,0.15f), 0, 4.0f); UI()->DoLabelScaled(&FilterHeader, Localize("Friends"), FontSize+4.0f, 0); CUIRect Button, List; ServerFriends.Margin(3.0f, &ServerFriends); ServerFriends.VMargin(3.0f, &ServerFriends); ServerFriends.HSplitBottom(100.0f, &List, &ServerFriends); // friends list(remove friend) static float s_ScrollValue = 0; UiDoListboxStart(&m_lFriends, &List, 30.0f, "", "", m_lFriends.size(), 1, m_FriendlistSelectedIndex, s_ScrollValue); m_lFriends.sort_range(); for(int i = 0; i < m_lFriends.size(); ++i) { CListboxItem Item = UiDoListboxNextItem(&m_lFriends[i]); if(Item.m_Visible) { Item.m_Rect.Margin(1.5f, &Item.m_Rect); CUIRect OnState; Item.m_Rect.VSplitRight(30.0f, &Item.m_Rect, &OnState); RenderTools()->DrawUIRect(&Item.m_Rect, vec4(1.0f, 1.0f, 1.0f, 0.1f), CUI::CORNER_L, 4.0f); Item.m_Rect.VMargin(2.5f, &Item.m_Rect); Item.m_Rect.HSplitTop(12.0f, &Item.m_Rect, &Button); UI()->DoLabelScaled(&Item.m_Rect, m_lFriends[i].m_pFriendInfo->m_aName, FontSize, -1); UI()->DoLabelScaled(&Button, m_lFriends[i].m_pFriendInfo->m_aClan, FontSize, -1); RenderTools()->DrawUIRect(&OnState, m_lFriends[i].m_NumFound ? vec4(0.0f, 1.0f, 0.0f, 0.25f) : vec4(1.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_R, 4.0f); OnState.HMargin((OnState.h-FontSize)/3, &OnState); OnState.VMargin(5.0f, &OnState); char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%i", m_lFriends[i].m_NumFound); UI()->DoLabelScaled(&OnState, aBuf, FontSize+2, 1); } } bool Activated = false; m_FriendlistSelectedIndex = UiDoListboxEnd(&s_ScrollValue, &Activated); // activate found server with friend if(Activated && !m_EnterPressed && m_lFriends[m_FriendlistSelectedIndex].m_NumFound) { bool Found = false; int NumServers = ServerBrowser()->NumSortedServers(); for (int i = 0; i < NumServers && !Found; i++) { int ItemIndex = m_SelectedIndex != -1 ? (m_SelectedIndex+i+1)%NumServers : i; const CServerInfo *pItem = ServerBrowser()->SortedGet(ItemIndex); if(pItem->m_FriendState != IFriends::FRIEND_NO) { for(int j = 0; j < pItem->m_NumClients && !Found; ++j) { if(pItem->m_aClients[j].m_FriendState != IFriends::FRIEND_NO && str_quickhash(pItem->m_aClients[j].m_aClan) == m_lFriends[m_FriendlistSelectedIndex].m_pFriendInfo->m_ClanHash && (!m_lFriends[m_FriendlistSelectedIndex].m_pFriendInfo->m_aName[0] || str_quickhash(pItem->m_aClients[j].m_aName) == m_lFriends[m_FriendlistSelectedIndex].m_pFriendInfo->m_NameHash)) { str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress)); m_ScrollOffset = ItemIndex; m_SelectedIndex = ItemIndex; Found = true; } } } } } ServerFriends.HSplitTop(2.5f, 0, &ServerFriends); ServerFriends.HSplitTop(20.0f, &Button, &ServerFriends); if(m_FriendlistSelectedIndex != -1) { static int s_RemoveButton = 0; if(DoButton_Menu(&s_RemoveButton, Localize("Remove"), 0, &Button)) m_Popup = POPUP_REMOVE_FRIEND; } // add friend if(m_pClient->Friends()->NumFriends() < IFriends::MAX_FRIENDS) { ServerFriends.HSplitTop(10.0f, 0, &ServerFriends); ServerFriends.HSplitTop(19.0f, &Button, &ServerFriends); char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); UI()->DoLabelScaled(&Button, aBuf, FontSize, -1); Button.VSplitLeft(80.0f, 0, &Button); static char s_aName[MAX_NAME_LENGTH] = {0}; static float s_OffsetName = 0.0f; DoEditBox(&s_aName, &Button, s_aName, sizeof(s_aName), FontSize, &s_OffsetName); ServerFriends.HSplitTop(3.0f, 0, &ServerFriends); ServerFriends.HSplitTop(19.0f, &Button, &ServerFriends); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Clan")); UI()->DoLabelScaled(&Button, aBuf, FontSize, -1); Button.VSplitLeft(80.0f, 0, &Button); static char s_aClan[MAX_CLAN_LENGTH] = {0}; static float s_OffsetClan = 0.0f; DoEditBox(&s_aClan, &Button, s_aClan, sizeof(s_aClan), FontSize, &s_OffsetClan); ServerFriends.HSplitTop(3.0f, 0, &ServerFriends); ServerFriends.HSplitTop(20.0f, &Button, &ServerFriends); static int s_AddButton = 0; if(DoButton_Menu(&s_AddButton, Localize("Add Friend"), 0, &Button)) { m_pClient->Friends()->AddFriend(s_aName, s_aClan); FriendlistOnUpdate(); Client()->ServerBrowserUpdate(); } } }
int CMenus::Render() { CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); static bool s_First = true; if(s_First) { 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); m_pClient->m_pSounds->Enqueue(CSounds::CHN_MUSIC, SOUND_MENU); s_First = false; } if(Client()->State() == IClient::STATE_ONLINE) { ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame; ms_ColorTabbarActive = ms_ColorTabbarActiveIngame; } else { RenderBackground(); ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame; ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame; } CUIRect TabBar; CUIRect MainView; // some margin around the screen Screen.Margin(10.0f, &Screen); static bool s_SoundCheck = false; if(!s_SoundCheck && m_Popup == POPUP_NONE) { if(Client()->SoundInitFailed()) m_Popup = POPUP_SOUNDERROR; s_SoundCheck = true; } if(m_Popup == POPUP_NONE) { // do tab bar Screen.HSplitTop(24.0f, &TabBar, &MainView); TabBar.VMargin(20.0f, &TabBar); RenderMenubar(TabBar); // news is not implemented yet if(g_Config.m_UiPage <= PAGE_NEWS || g_Config.m_UiPage > PAGE_SETTINGS || (Client()->State() == IClient::STATE_OFFLINE && g_Config.m_UiPage >= PAGE_GAME && g_Config.m_UiPage <= PAGE_CALLVOTE)) { ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); g_Config.m_UiPage = PAGE_INTERNET; } // render current page if(Client()->State() != IClient::STATE_OFFLINE) { if(m_GamePage == PAGE_GAME) RenderGame(MainView); else if(m_GamePage == PAGE_PLAYERS) RenderPlayers(MainView); else if(m_GamePage == PAGE_SERVER_INFO) RenderServerInfo(MainView); else if(m_GamePage == PAGE_DDRace) RenderInGameDDRace(MainView); else if(m_GamePage == PAGE_CALLVOTE) RenderServerControl(MainView); else if(m_GamePage == PAGE_SETTINGS) RenderSettings(MainView); else if(m_GamePage == PAGE_GHOST) RenderGhost(MainView); else if(m_GamePage == PAGE_BROWSER) RenderInGameBrowser(MainView); } else if(g_Config.m_UiPage == PAGE_NEWS) RenderNews(MainView); else if(g_Config.m_UiPage == PAGE_INTERNET) RenderServerbrowser(MainView); else if(g_Config.m_UiPage == PAGE_LAN) RenderServerbrowser(MainView); else if(g_Config.m_UiPage == PAGE_DEMOS) RenderDemoList(MainView); else if(g_Config.m_UiPage == PAGE_FAVORITES) RenderServerbrowser(MainView); else if(g_Config.m_UiPage == PAGE_SETTINGS) RenderSettings(MainView); } else { // make sure that other windows doesn't do anything funnay! //UI()->SetHotItem(0); //UI()->SetActiveItem(0); char aBuf[128]; const char *pTitle = ""; const char *pExtraText = ""; const char *pButtonText = ""; int ExtraAlign = 0; if(m_Popup == POPUP_MESSAGE) { pTitle = m_aMessageTopic; pExtraText = m_aMessageBody; pButtonText = m_aMessageButton; } else if(m_Popup == POPUP_CONNECTING) { pTitle = Localize("Connecting to"); pExtraText = g_Config.m_UiServerAddress; // TODO: query the client about the address pButtonText = Localize("Abort"); if(Client()->MapDownloadTotalsize() > 0) { pTitle = Localize("Downloading map"); pExtraText = ""; } } else if(m_Popup == POPUP_DISCONNECTED) { pTitle = Localize("Disconnected"); pExtraText = Client()->ErrorString(); pButtonText = Localize("Ok"); ExtraAlign = -1; } else if(m_Popup == POPUP_PURE) { pTitle = Localize("Disconnected"); pExtraText = Localize("The server is running a non-standard tuning on a pure game type."); pButtonText = Localize("Ok"); ExtraAlign = -1; } else if(m_Popup == POPUP_DELETE_DEMO) { pTitle = Localize("Delete demo"); pExtraText = Localize("Are you sure that you want to delete the demo?"); ExtraAlign = -1; } else if(m_Popup == POPUP_RENAME_DEMO) { pTitle = Localize("Rename demo"); pExtraText = ""; ExtraAlign = -1; } else if(m_Popup == POPUP_REMOVE_FRIEND) { pTitle = Localize("Remove friend"); pExtraText = Localize("Are you sure that you want to remove the player from your friends list?"); ExtraAlign = -1; } else if(m_Popup == POPUP_SOUNDERROR) { pTitle = Localize("Sound error"); pExtraText = Localize("The audio device couldn't be initialised."); pButtonText = Localize("Ok"); ExtraAlign = -1; } else if(m_Popup == POPUP_PASSWORD) { pTitle = Localize("Password incorrect"); pExtraText = ""; pButtonText = Localize("Try again"); } else if(m_Popup == POPUP_QUIT) { pTitle = Localize("Quit"); pExtraText = Localize("Are you sure that you want to quit?"); ExtraAlign = -1; } else if(m_Popup == POPUP_FIRST_LAUNCH) { pTitle = Localize("Welcome to Teeworlds"); pExtraText = Localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server."); pButtonText = Localize("Ok"); ExtraAlign = -1; } CUIRect Box, Part; Box = Screen; Box.VMargin(150.0f/UI()->Scale(), &Box); Box.HMargin(150.0f/UI()->Scale(), &Box); // render the box RenderTools()->DrawUIRect(&Box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f); Box.HSplitTop(20.f/UI()->Scale(), &Part, &Box); Box.HSplitTop(24.f/UI()->Scale(), &Part, &Box); UI()->DoLabelScaled(&Part, pTitle, 24.f, 0); Box.HSplitTop(20.f/UI()->Scale(), &Part, &Box); Box.HSplitTop(24.f/UI()->Scale(), &Part, &Box); Part.VMargin(20.f/UI()->Scale(), &Part); if(ExtraAlign == -1) UI()->DoLabelScaled(&Part, pExtraText, 20.f, -1, (int)Part.w); else UI()->DoLabelScaled(&Part, pExtraText, 20.f, 0, -1); if(m_Popup == POPUP_QUIT) { CUIRect Yes, No; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); // additional info Box.HSplitTop(10.0f, 0, &Box); Box.VMargin(20.f/UI()->Scale(), &Box); if(m_pClient->Editor()->HasUnsavedData()) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "%s\n%s", Localize("There's an unsaved map in the editor, you might want to save it before you quit the game."), Localize("Quit anyway?")); UI()->DoLabelScaled(&Box, aBuf, 20.f, -1, Part.w-20.0f); } // buttons Part.VMargin(80.0f, &Part); Part.VSplitMid(&No, &Yes); Yes.VMargin(20.0f, &Yes); No.VMargin(20.0f, &No); static int s_ButtonAbort = 0; if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed) m_Popup = POPUP_NONE; static int s_ButtonTryAgain = 0; if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed) Client()->Quit(); } else if(m_Popup == POPUP_PASSWORD) { CUIRect Label, TextBox, TryAgain, Abort; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(80.0f, &Part); Part.VSplitMid(&Abort, &TryAgain); TryAgain.VMargin(20.0f, &TryAgain); Abort.VMargin(20.0f, &Abort); static int s_ButtonAbort = 0; if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed) m_Popup = POPUP_NONE; static int s_ButtonTryAgain = 0; if(DoButton_Menu(&s_ButtonTryAgain, Localize("Try again"), 0, &TryAgain) || m_EnterPressed) { Client()->Connect(g_Config.m_UiServerAddress); } Box.HSplitBottom(60.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VSplitLeft(60.0f, 0, &Label); Label.VSplitLeft(100.0f, 0, &TextBox); TextBox.VSplitLeft(20.0f, 0, &TextBox); TextBox.VSplitRight(60.0f, &TextBox, 0); UI()->DoLabel(&Label, Localize("Password"), 18.0f, -1); static float Offset = 0.0f; DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, &Offset, true); } else if(m_Popup == POPUP_CONNECTING) { Box = Screen; Box.VMargin(150.0f, &Box); Box.HMargin(150.0f, &Box); Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(120.0f, &Part); static int s_Button = 0; if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed) { Client()->Disconnect(); m_Popup = POPUP_NONE; } if(Client()->MapDownloadTotalsize() > 0) { int64 Now = time_get(); if(Now-m_DownloadLastCheckTime >= time_freq()) { if(m_DownloadLastCheckSize > Client()->MapDownloadAmount()) { // map downloaded restarted m_DownloadLastCheckSize = 0; } // update download speed float Diff = Client()->MapDownloadAmount()-m_DownloadLastCheckSize; float StartDiff = m_DownloadLastCheckSize-0.0f; if(StartDiff+Diff > 0.0f) m_DownloadSpeed = (Diff/(StartDiff+Diff))*(Diff/1.0f) + (StartDiff/(Diff+StartDiff))*m_DownloadSpeed; else m_DownloadSpeed = 0.0f; m_DownloadLastCheckTime = Now; m_DownloadLastCheckSize = Client()->MapDownloadAmount(); } Box.HSplitTop(64.f, 0, &Box); Box.HSplitTop(24.f, &Part, &Box); str_format(aBuf, sizeof(aBuf), "%d/%d KiB (%.1f KiB/s)", Client()->MapDownloadAmount()/1024, Client()->MapDownloadTotalsize()/1024, m_DownloadSpeed/1024.0f); UI()->DoLabel(&Part, aBuf, 20.f, 0, -1); // time left const char *pTimeLeftString; int TimeLeft = max(1, m_DownloadSpeed > 0.0f ? static_cast<int>((Client()->MapDownloadTotalsize()-Client()->MapDownloadAmount())/m_DownloadSpeed) : 1); if(TimeLeft >= 60) { TimeLeft /= 60; pTimeLeftString = TimeLeft == 1 ? Localize("%i minute left") : Localize("%i minutes left"); } else pTimeLeftString = TimeLeft == 1 ? Localize("%i second left") : Localize("%i seconds left"); Box.HSplitTop(20.f, 0, &Box); Box.HSplitTop(24.f, &Part, &Box); str_format(aBuf, sizeof(aBuf), pTimeLeftString, TimeLeft); UI()->DoLabel(&Part, aBuf, 20.f, 0, -1); // progress bar Box.HSplitTop(20.f, 0, &Box); Box.HSplitTop(24.f, &Part, &Box); Part.VMargin(40.0f, &Part); RenderTools()->DrawUIRect(&Part, vec4(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, 5.0f); Part.w = max(10.0f, (Part.w*Client()->MapDownloadAmount())/Client()->MapDownloadTotalsize()); RenderTools()->DrawUIRect(&Part, vec4(1.0f, 1.0f, 1.0f, 0.5f), CUI::CORNER_ALL, 5.0f); } } else if(m_Popup == POPUP_LANGUAGE) { Box = Screen; Box.VMargin(150.0f, &Box); Box.HMargin(150.0f, &Box); Box.HSplitTop(20.f, &Part, &Box); Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Box.HSplitBottom(20.f, &Box, 0); Box.VMargin(20.0f, &Box); RenderLanguageSelection(Box); Part.VMargin(120.0f, &Part); static int s_Button = 0; if(DoButton_Menu(&s_Button, Localize("Ok"), 0, &Part) || m_EscapePressed || m_EnterPressed) m_Popup = POPUP_FIRST_LAUNCH; } else if(m_Popup == POPUP_COUNTRY) { Box = Screen; Box.VMargin(150.0f, &Box); Box.HMargin(150.0f, &Box); Box.HSplitTop(20.f, &Part, &Box); Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Box.HSplitBottom(20.f, &Box, 0); Box.VMargin(20.0f, &Box); static int ActSelection = -2; if(ActSelection == -2) ActSelection = g_Config.m_BrFilterCountryIndex; static float s_ScrollValue = 0.0f; int OldSelected = -1; UiDoListboxStart(&s_ScrollValue, &Box, 50.0f, Localize("Country"), "", m_pClient->m_pCountryFlags->Num(), 6, OldSelected, s_ScrollValue); for(int i = 0; i < m_pClient->m_pCountryFlags->Num(); ++i) { const CCountryFlags::CCountryFlag *pEntry = m_pClient->m_pCountryFlags->GetByIndex(i); if(pEntry->m_CountryCode == ActSelection) OldSelected = i; CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i); if(Item.m_Visible) { CUIRect Label; Item.m_Rect.Margin(5.0f, &Item.m_Rect); Item.m_Rect.HSplitBottom(10.0f, &Item.m_Rect, &Label); float OldWidth = Item.m_Rect.w; Item.m_Rect.w = Item.m_Rect.h*2; Item.m_Rect.x += (OldWidth-Item.m_Rect.w)/ 2.0f; Graphics()->TextureSet(pEntry->m_Texture); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, Item.m_Rect.w, Item.m_Rect.h); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); UI()->DoLabel(&Label, pEntry->m_aCountryCodeString, 10.0f, 0); } } const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) ActSelection = m_pClient->m_pCountryFlags->GetByIndex(NewSelected)->m_CountryCode; Part.VMargin(120.0f, &Part); static int s_Button = 0; if(DoButton_Menu(&s_Button, Localize("Ok"), 0, &Part) || m_EnterPressed) { g_Config.m_BrFilterCountryIndex = ActSelection; Client()->ServerBrowserUpdate(); m_Popup = POPUP_NONE; } if(m_EscapePressed) { ActSelection = g_Config.m_BrFilterCountryIndex; m_Popup = POPUP_NONE; } } else if(m_Popup == POPUP_DELETE_DEMO) { CUIRect Yes, No; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(80.0f, &Part); Part.VSplitMid(&No, &Yes); Yes.VMargin(20.0f, &Yes); No.VMargin(20.0f, &No); static int s_ButtonAbort = 0; if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed) m_Popup = POPUP_NONE; static int s_ButtonTryAgain = 0; if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed) { m_Popup = POPUP_NONE; // delete demo if(m_DemolistSelectedIndex >= 0 && !m_DemolistSelectedIsDir) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); if(Storage()->RemoveFile(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType)) { DemolistPopulate(); DemolistOnUpdate(false); } else PopupMessage(Localize("Error"), Localize("Unable to delete the demo"), Localize("Ok")); } } } else if(m_Popup == POPUP_RENAME_DEMO) { CUIRect Label, TextBox, Ok, Abort; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(80.0f, &Part); Part.VSplitMid(&Abort, &Ok); Ok.VMargin(20.0f, &Ok); Abort.VMargin(20.0f, &Abort); static int s_ButtonAbort = 0; if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed) m_Popup = POPUP_NONE; static int s_ButtonOk = 0; if(DoButton_Menu(&s_ButtonOk, Localize("Ok"), 0, &Ok) || m_EnterPressed) { m_Popup = POPUP_NONE; // rename demo if(m_DemolistSelectedIndex >= 0 && !m_DemolistSelectedIsDir) { char aBufOld[512]; str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); int Length = str_length(m_aCurrentDemoFile); char aBufNew[512]; if(Length <= 4 || m_aCurrentDemoFile[Length-5] != '.' || str_comp_nocase(m_aCurrentDemoFile+Length-4, "demo")) str_format(aBufNew, sizeof(aBufNew), "%s/%s.demo", m_aCurrentDemoFolder, m_aCurrentDemoFile); else str_format(aBufNew, sizeof(aBufNew), "%s/%s", m_aCurrentDemoFolder, m_aCurrentDemoFile); if(Storage()->RenameFile(aBufOld, aBufNew, m_lDemos[m_DemolistSelectedIndex].m_StorageType)) { DemolistPopulate(); DemolistOnUpdate(false); } else PopupMessage(Localize("Error"), Localize("Unable to rename the demo"), Localize("Ok")); } } Box.HSplitBottom(60.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VSplitLeft(60.0f, 0, &Label); Label.VSplitLeft(120.0f, 0, &TextBox); TextBox.VSplitLeft(20.0f, 0, &TextBox); TextBox.VSplitRight(60.0f, &TextBox, 0); UI()->DoLabel(&Label, Localize("New name:"), 18.0f, -1); static float Offset = 0.0f; DoEditBox(&Offset, &TextBox, m_aCurrentDemoFile, sizeof(m_aCurrentDemoFile), 12.0f, &Offset); } else if(m_Popup == POPUP_REMOVE_FRIEND) { CUIRect Yes, No; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(80.0f, &Part); Part.VSplitMid(&No, &Yes); Yes.VMargin(20.0f, &Yes); No.VMargin(20.0f, &No); static int s_ButtonAbort = 0; if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed) m_Popup = POPUP_NONE; static int s_ButtonTryAgain = 0; if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed) { m_Popup = POPUP_NONE; // remove friend if(m_FriendlistSelectedIndex >= 0) { m_pClient->Friends()->RemoveFriend(m_lFriends[m_FriendlistSelectedIndex].m_pFriendInfo->m_aName, m_lFriends[m_FriendlistSelectedIndex].m_pFriendInfo->m_aClan); FriendlistOnUpdate(); Client()->ServerBrowserUpdate(); } } } else if(m_Popup == POPUP_FIRST_LAUNCH) { CUIRect Label, TextBox; Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(80.0f, &Part); static int s_EnterButton = 0; if(DoButton_Menu(&s_EnterButton, Localize("Enter"), 0, &Part) || m_EnterPressed) m_Popup = POPUP_NONE; Box.HSplitBottom(40.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VSplitLeft(60.0f, 0, &Label); Label.VSplitLeft(100.0f, 0, &TextBox); TextBox.VSplitLeft(20.0f, 0, &TextBox); TextBox.VSplitRight(60.0f, &TextBox, 0); UI()->DoLabel(&Label, Localize("Nickname"), 18.0f, -1); static float Offset = 0.0f; DoEditBox(&g_Config.m_PlayerName, &TextBox, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 12.0f, &Offset); } else { Box.HSplitBottom(20.f, &Box, &Part); Box.HSplitBottom(24.f, &Box, &Part); Part.VMargin(120.0f, &Part); static int s_Button = 0; if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed) m_Popup = POPUP_NONE; } } return 0; }