void CMenus::RenderSettingsPlayer(CUIRect MainView) { CUIRect Button; CUIRect LeftView, RightView; MainView.VSplitMid(&LeftView, &RightView); LeftView.HSplitTop(20.0f, &Button, &LeftView); // render settings { char aBuf[128]; LeftView.HSplitTop(20.0f, &Button, &LeftView); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); UI()->DoLabel(&Button, aBuf, 14.0, -1); Button.VSplitLeft(80.0f, 0, &Button); Button.VSplitLeft(180.0f, &Button, 0); static float Offset = 0.0f; if(DoEditBox(g_Config.m_PlayerName, &Button, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 14.0f, &Offset)) m_NeedSendinfo = true; // extra spacing LeftView.HSplitTop(10.0f, 0, &LeftView); static int s_DynamicCameraButton = 0; LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&s_DynamicCameraButton, Localize("Dynamic Camera"), g_Config.m_ClMouseDeadzone != 0, &Button)) { if(g_Config.m_ClMouseDeadzone) { g_Config.m_ClMouseFollowfactor = 0; g_Config.m_ClMouseMaxDistance = 400; g_Config.m_ClMouseDeadzone = 0; } else { g_Config.m_ClMouseFollowfactor = 60; g_Config.m_ClMouseMaxDistance = 1000; g_Config.m_ClMouseDeadzone = 300; } } LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&g_Config.m_ClAutoswitchWeapons, Localize("Switch weapon on pickup"), g_Config.m_ClAutoswitchWeapons, &Button)) g_Config.m_ClAutoswitchWeapons ^= 1; LeftView.HSplitTop(20.0f, &Button, &LeftView); if(DoButton_CheckBox(&g_Config.m_ClNameplates, Localize("Show name plates"), g_Config.m_ClNameplates, &Button)) g_Config.m_ClNameplates ^= 1; LeftView.HSplitTop(20.0f, &Button, &LeftView); if(g_Config.m_ClNameplates) { Button.VSplitLeft(15.0f, 0, &Button); if(DoButton_CheckBox(&g_Config.m_ClNameplatesAlways, Localize("Always show name plates"), g_Config.m_ClNameplatesAlways, &Button)) g_Config.m_ClNameplatesAlways ^= 1; // draw nameplates size slider CUIRect Label; LeftView.HSplitTop(20.0f, &Button, &LeftView); Button.VSplitLeft(15.0f, 0, &Button); Button.VSplitRight(10.0f, &Button, 0); Button.VSplitLeft(140.0f, &Label, &Button); Button.HMargin(2.0f, &Button); UI()->DoLabel(&Label, Localize("Name plates size"), 13.0f, -1); g_Config.m_ClNameplatesSize = (int)(DoScrollbarH(&g_Config.m_ClNameplatesSize, &Button, g_Config.m_ClNameplatesSize/100.0f)*100.0f+0.1f); } else LeftView.HSplitTop(20.0f, &Button, &LeftView); { const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(max(0, m_pClient->m_pSkins->Find(g_Config.m_PlayerSkin))); CTeeRenderInfo OwnSkinInfo; OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; OwnSkinInfo.m_ColorBody = vec4(1, 1, 1, 1); OwnSkinInfo.m_ColorFeet = vec4(1, 1, 1, 1); if(g_Config.m_PlayerUseCustomColor) { OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorBody); OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorFeet); OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; } OwnSkinInfo.m_Size = 50.0f*UI()->Scale(); LeftView.HSplitTop(20.0f, &Button, &LeftView); LeftView.HSplitTop(20.0f, &Button, &LeftView); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Your skin")); UI()->DoLabelScaled(&Button, aBuf, 14.0f, -1); CUIRect SkinRect; LeftView.VSplitLeft(LeftView.w/1.2f/UI()->Scale(), &SkinRect, 0); SkinRect.HSplitTop(50.0f, &SkinRect, 0); RenderTools()->DrawUIRect(&SkinRect, vec4(1, 1, 1, 0.25f), CUI::CORNER_ALL, 10.0f); Button.VSplitLeft(30.0f, 0, &Button); Button.HSplitTop(50.0f, 0, &Button); RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Button.x, Button.y)); LeftView.HSplitTop(20.0f, &Button, &LeftView); Button.HSplitTop(15.0f, 0, &Button); Button.VSplitLeft(100.0f, 0, &Button); str_format(aBuf, sizeof(aBuf), "%s", g_Config.m_PlayerSkin); CTextCursor Cursor; TextRender()->SetCursor(&Cursor, Button.x, Button.y, 14.0f*UI()->Scale(), TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = SkinRect.w-(Button.x-SkinRect.x)-5.0f; TextRender()->TextEx(&Cursor, aBuf, -1); } RightView.HSplitTop(20.0f, &Button, &RightView); RightView.HSplitTop(20.0f, &Button, &RightView); if(DoButton_CheckBox(&g_Config.m_PlayerColorBody, Localize("Custom colors"), g_Config.m_PlayerUseCustomColor, &Button)) { g_Config.m_PlayerUseCustomColor = g_Config.m_PlayerUseCustomColor?0:1; m_NeedSendinfo = true; } if(g_Config.m_PlayerUseCustomColor) { int *paColors[2]; paColors[0] = &g_Config.m_PlayerColorBody; paColors[1] = &g_Config.m_PlayerColorFeet; const char *paParts[] = { Localize("Body"), Localize("Feet") }; const char *paLabels[] = { Localize("Hue"), Localize("Sat."), Localize("Lht.") }; static int s_aColorSlider[2][3] = {{0}}; //static float v[2][3] = {{0, 0.5f, 0.25f}, {0, 0.5f, 0.25f}}; for(int i = 0; i < 2; i++) { CUIRect Text; RightView.HSplitTop(20.0f, &Text, &RightView); Text.VSplitLeft(15.0f, 0, &Text); UI()->DoLabelScaled(&Text, paParts[i], 14.0f, -1); int PrevColor = *paColors[i]; int Color = 0; for(int s = 0; s < 3; s++) { CUIRect Text; RightView.HSplitTop(19.0f, &Button, &RightView); Button.VSplitLeft(30.0f, 0, &Button); Button.VSplitLeft(70.0f, &Text, &Button); Button.VSplitRight(5.0f, &Button, 0); Button.HSplitTop(4.0f, 0, &Button); float k = ((PrevColor>>((2-s)*8))&0xff) / 255.0f; k = DoScrollbarH(&s_aColorSlider[i][s], &Button, k); Color <<= 8; Color += clamp((int)(k*255), 0, 255); UI()->DoLabelScaled(&Text, paLabels[s], 15.0f, -1); } if(*paColors[i] != Color) m_NeedSendinfo = true; *paColors[i] = Color; RightView.HSplitTop(5.0f, 0, &RightView); } } MainView.HSplitTop(MainView.h/2, 0, &MainView); // render skinselector static bool s_InitSkinlist = true; static sorted_array<const CSkins::CSkin *> s_paSkinList; static float s_ScrollValue = 0; if(s_InitSkinlist) { s_paSkinList.clear(); for(int i = 0; i < m_pClient->m_pSkins->Num(); ++i) { const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i); // no special skins if(s->m_aName[0] == 'x' && s->m_aName[1] == '_') continue; s_paSkinList.add(s); } s_InitSkinlist = false; } int OldSelected = -1; UiDoListboxStart(&s_InitSkinlist, &MainView, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue); for(int i = 0; i < s_paSkinList.size(); ++i) { const CSkins::CSkin *s = s_paSkinList[i]; if(s == 0) continue; if(str_comp(s->m_aName, g_Config.m_PlayerSkin) == 0) OldSelected = i; CListboxItem Item = UiDoListboxNextItem(&s_paSkinList[i], OldSelected == i); if(Item.m_Visible) { CTeeRenderInfo Info; Info.m_Texture = s->m_OrgTexture; Info.m_ColorBody = vec4(1, 1, 1, 1); Info.m_ColorFeet = vec4(1, 1, 1, 1); if(g_Config.m_PlayerUseCustomColor) { Info.m_ColorBody = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorBody); Info.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(g_Config.m_PlayerColorFeet); Info.m_Texture = s->m_ColorTexture; } Info.m_Size = UI()->Scale()*50.0f; Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1, 0), vec2(Item.m_Rect.x+Item.m_Rect.w/2, Item.m_Rect.y+Item.m_Rect.h/2)); if(g_Config.m_Debug) { vec3 BloodColor = g_Config.m_PlayerUseCustomColor ? m_pClient->m_pSkins->GetColorV3(g_Config.m_PlayerColorBody) : s->m_BloodColor; Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(BloodColor.r, BloodColor.g, BloodColor.b, 1.0f); IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, 12, 12); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } } } const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { mem_copy(g_Config.m_PlayerSkin, s_paSkinList[NewSelected]->m_aName, sizeof(g_Config.m_PlayerSkin)); m_NeedSendinfo = true; } }
void CMenus::RenderDemoList(CUIRect MainView) { static int s_Inited = 0; if(!s_Inited) { DemolistPopulate(); DemolistOnUpdate(true); s_Inited = 1; } char aFooterLabel[128] = {0}; if(m_DemolistSelectedIndex >= 0) { CDemoItem *Item = &m_lDemos[m_DemolistSelectedIndex]; if(str_comp(Item->m_aFilename, "..") == 0) str_copy(aFooterLabel, Localize("Parent Folder"), sizeof(aFooterLabel)); else if(m_DemolistSelectedIsDir) str_copy(aFooterLabel, Localize("Folder"), sizeof(aFooterLabel)); else { if(!Item->m_InfosLoaded) { char aBuffer[512]; str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aCurrentDemoFolder, Item->m_aFilename); Item->m_Valid = DemoPlayer()->GetDemoInfo(Storage(), aBuffer, Item->m_StorageType, &Item->m_Info); Item->m_InfosLoaded = true; } if(!Item->m_Valid) str_copy(aFooterLabel, Localize("Invalid Demo"), sizeof(aFooterLabel)); else str_copy(aFooterLabel, Localize("Demo details"), sizeof(aFooterLabel)); } } // render background RenderTools()->DrawUIRect(&MainView, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_ALL, 10.0f); MainView.Margin(10.0f, &MainView); CUIRect ButtonBar, RefreshRect, PlayRect, DeleteRect, RenameRect, FileIcon, ListBox; MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar); ButtonBar.HSplitTop(5.0f, 0, &ButtonBar); ButtonBar.VSplitRight(130.0f, &ButtonBar, &PlayRect); ButtonBar.VSplitLeft(130.0f, &RefreshRect, &ButtonBar); ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &DeleteRect, &ButtonBar); ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &RenameRect, &ButtonBar); MainView.HSplitBottom(140.0f, &ListBox, &MainView); // render demo info MainView.VMargin(5.0f, &MainView); MainView.HSplitBottom(5.0f, &MainView, 0); RenderTools()->DrawUIRect(&MainView, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); if(!m_DemolistSelectedIsDir && m_DemolistSelectedIndex >= 0 && m_lDemos[m_DemolistSelectedIndex].m_Valid) { CUIRect Left, Right, Labels; MainView.Margin(20.0f, &MainView); MainView.VSplitMid(&Labels, &MainView); // left side Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Created:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aTimestamp, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Type:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aType, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Length:"), 14.0f, -1); int Length = ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[0]<<24)&0xFF000000) | ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[1]<<16)&0xFF0000) | ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[2]<<8)&0xFF00) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[3]&0xFF); char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%d:%02d", Length/60, Length%60); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Version:"), 14.0f, -1); str_format(aBuf, sizeof(aBuf), "%d", m_lDemos[m_DemolistSelectedIndex].m_Info.m_Version); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); // right side Labels = MainView; Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Map:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapName, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(20.0f, 0, &Left); Left.VSplitLeft(130.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Size:"), 14.0f, -1); unsigned Size = (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[0]<<24) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[1]<<16) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[2]<<8) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[3]); str_format(aBuf, sizeof(aBuf), Localize("%d Bytes"), Size); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(20.0f, 0, &Left); Left.VSplitLeft(130.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Crc:"), 14.0f, -1); unsigned Crc = (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[0]<<24) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[1]<<16) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[2]<<8) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[3]); str_format(aBuf, sizeof(aBuf), "%08x", Crc); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Netversion:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aNetversion, 14.0f, -1); } static int s_DemoListId = 0; static float s_ScrollValue = 0; UiDoListboxStart(&s_DemoListId, &ListBox, 17.0f, Localize("Demos"), aFooterLabel, m_lDemos.size(), 1, m_DemolistSelectedIndex, s_ScrollValue); for(sorted_array<CDemoItem>::range r = m_lDemos.all(); !r.empty(); r.pop_front()) { CListboxItem Item = UiDoListboxNextItem((void*)(&r.front())); if(Item.m_Visible) { Item.m_Rect.VSplitLeft(Item.m_Rect.h, &FileIcon, &Item.m_Rect); Item.m_Rect.VSplitLeft(5.0f, 0, &Item.m_Rect); DoButton_Icon(IMAGE_FILEICONS, r.front().m_IsDir?SPRITE_FILE_FOLDER:SPRITE_FILE_DEMO1, &FileIcon); UI()->DoLabel(&Item.m_Rect, r.front().m_aName, Item.m_Rect.h*ms_FontmodHeight, -1); } } bool Activated = false; m_DemolistSelectedIndex = UiDoListboxEnd(&s_ScrollValue, &Activated); DemolistOnUpdate(false); static int s_RefreshButton = 0; if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect)) { DemolistPopulate(); DemolistOnUpdate(false); } static int s_PlayButton = 0; if(DoButton_Menu(&s_PlayButton, m_DemolistSelectedIsDir?Localize("Open"):Localize("Play"), 0, &PlayRect) || Activated) { if(m_DemolistSelectedIndex >= 0) { if(m_DemolistSelectedIsDir) // folder { if(str_comp(m_lDemos[m_DemolistSelectedIndex].m_aFilename, "..") == 0) // parent folder fs_parent_dir(m_aCurrentDemoFolder); else // sub folder { char aTemp[256]; str_copy(aTemp, m_aCurrentDemoFolder, sizeof(aTemp)); str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", aTemp, m_lDemos[m_DemolistSelectedIndex].m_aFilename); m_DemolistStorageType = m_lDemos[m_DemolistSelectedIndex].m_StorageType; } DemolistPopulate(); DemolistOnUpdate(true); } else // file { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); const char *pError = Client()->DemoPlayer_Play(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType); if(pError) PopupMessage(Localize("Error loading demo"), pError, Localize("Ok")); else { UI()->SetActiveItem(0); return; } } } } if(!m_DemolistSelectedIsDir) { static int s_DeleteButton = 0; if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &DeleteRect) || m_DeletePressed) { if(m_DemolistSelectedIndex >= 0) { UI()->SetActiveItem(0); m_Popup = POPUP_DELETE_DEMO; return; } } static int s_RenameButton = 0; if(DoButton_Menu(&s_RenameButton, Localize("Rename"), 0, &RenameRect)) { if(m_DemolistSelectedIndex >= 0) { UI()->SetActiveItem(0); m_Popup = POPUP_RENAME_DEMO; str_copy(m_aCurrentDemoFile, m_lDemos[m_DemolistSelectedIndex].m_aFilename, sizeof(m_aCurrentDemoFile)); return; } } } }
void CMenus::RenderServerbrowser(CUIRect MainView) { RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); CUIRect View; MainView.Margin(10.0f, &View); /* +-----------------+ +------+ | | | | | | | tool | | | | box | | | | | | | +------+ +-----------------+ button status toolbar box */ //CUIRect filters; CUIRect StatusToolBox; CUIRect ToolBox; CUIRect ButtonBox; // split off a piece for filters, details and scoreboard View.VSplitRight(200.0f, &View, &ToolBox); ToolBox.HSplitBottom(80.0f, &ToolBox, &ButtonBox); View.HSplitBottom(ms_ButtonHeight+5.0f, &View, &StatusToolBox); RenderServerbrowserServerList(View); int ToolboxPage = g_Config.m_UiToolboxPage; ToolBox.VSplitLeft(5.0f, 0, &ToolBox); // do tabbar { CUIRect TabBar; CUIRect TabButton0, TabButton1; ToolBox.HSplitTop(22.0f, &TabBar, &ToolBox); TabBar.VSplitMid(&TabButton0, &TabButton1); //TabButton0.VSplitRight(5.0f, &TabButton0, 0); //TabButton1.VSplitLeft(5.0f, 0, &TabButton1); static int s_FiltersTab = 0; if (DoButton_MenuTab(&s_FiltersTab, Localize("Filter"), ToolboxPage==0, &TabButton0, CUI::CORNER_TL)) ToolboxPage = 0; static int s_InfoTab = 0; if (DoButton_MenuTab(&s_InfoTab, Localize("Info"), ToolboxPage==1, &TabButton1, CUI::CORNER_TR)) ToolboxPage = 1; } g_Config.m_UiToolboxPage = ToolboxPage; RenderTools()->DrawUIRect(&ToolBox, vec4(0,0,0,0.15f), 0, 0); ToolBox.HSplitTop(5.0f, 0, &ToolBox); if(ToolboxPage == 0) RenderServerbrowserFilters(ToolBox); else if(ToolboxPage == 1) RenderServerbrowserServerDetail(ToolBox); { StatusToolBox.HSplitTop(5.0f, 0, &StatusToolBox); CUIRect Button; //buttons.VSplitRight(20.0f, &buttons, &button); StatusToolBox.VSplitRight(110.0f, &StatusToolBox, &Button); Button.VMargin(2.0f, &Button); static int s_RefreshButton = 0; if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &Button)) { 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); } char aBuf[512]; if(str_comp(Client()->LatestVersion(), "0") != 0) str_format(aBuf, sizeof(aBuf), Localize("Teeworlds %s is out! Download it at www.teeworlds.com!"), Client()->LatestVersion()); else str_format(aBuf, sizeof(aBuf), Localize("Current version: %s"), GAME_VERSION); UI()->DoLabelScaled(&StatusToolBox, aBuf, 14.0f, -1); } // do the button box { ButtonBox.VSplitLeft(5.0f, 0, &ButtonBox); ButtonBox.VSplitRight(5.0f, &ButtonBox, 0); CUIRect Button; ButtonBox.HSplitBottom(ms_ButtonHeight, &ButtonBox, &Button); Button.VSplitRight(120.0f, 0, &Button); Button.VMargin(2.0f, &Button); //button.VMargin(2.0f, &button); static int s_JoinButton = 0; if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &Button) || m_EnterPressed) { //dbg_msg("", "%s", g_Config.m_UiServerAddress); Client()->Connect(g_Config.m_UiServerAddress); m_EnterPressed = false; } ButtonBox.HSplitBottom(5.0f, &ButtonBox, &Button); ButtonBox.HSplitBottom(20.0f, &ButtonBox, &Button); static float Offset = 0.0f; DoEditBox(&g_Config.m_UiServerAddress, &Button, g_Config.m_UiServerAddress, sizeof(g_Config.m_UiServerAddress), 14.0f, &Offset); ButtonBox.HSplitBottom(20.0f, &ButtonBox, &Button); UI()->DoLabelScaled(&Button, Localize("Host address"), 14.0f, -1); } }
void CMenus::RenderDemoList(CUIRect MainView) { CALLSTACK_ADD(); static int s_Inited = 0; if(!s_Inited) { DemolistPopulate(); DemolistOnUpdate(true); s_Inited = 1; } char aFooterLabel[128] = {0}; if(m_DemolistSelectedIndex >= 0) { CDemoItem *Item = &m_lDemos[m_DemolistSelectedIndex]; if(str_comp(Item->m_aFilename, "..") == 0) str_copy(aFooterLabel, Localize("Parent Folder"), sizeof(aFooterLabel)); else if(m_DemolistSelectedIsDir) str_copy(aFooterLabel, Localize("Folder"), sizeof(aFooterLabel)); else { if(!Item->m_InfosLoaded) { char aBuffer[512]; str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aCurrentDemoFolder, Item->m_aFilename); Item->m_Valid = DemoPlayer()->GetDemoInfo(Storage(), aBuffer, Item->m_StorageType, &Item->m_Info); Item->m_InfosLoaded = true; } if(!Item->m_Valid) str_copy(aFooterLabel, Localize("Invalid Demo"), sizeof(aFooterLabel)); else str_copy(aFooterLabel, Localize("Demo details"), sizeof(aFooterLabel)); } } // render background RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); MainView.Margin(10.0f, &MainView); CUIRect ButtonBar, RefreshRect, PlayRect, DeleteRect, RenameRect, ListBox; MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar); ButtonBar.HSplitTop(5.0f, 0, &ButtonBar); ButtonBar.VSplitRight(130.0f, &ButtonBar, &PlayRect); ButtonBar.VSplitLeft(130.0f, &RefreshRect, &ButtonBar); ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &DeleteRect, &ButtonBar); ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &RenameRect, &ButtonBar); MainView.HSplitBottom(140.0f, &ListBox, &MainView); // render demo info MainView.VMargin(5.0f, &MainView); MainView.HSplitBottom(5.0f, &MainView, 0); RenderTools()->DrawUIRect(&MainView, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); if(!m_DemolistSelectedIsDir && m_DemolistSelectedIndex >= 0 && m_lDemos[m_DemolistSelectedIndex].m_Valid) { CUIRect Left, Right, Labels; MainView.Margin(20.0f, &MainView); MainView.VSplitMid(&Labels, &MainView); // left side Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Created:"), 14.0f, -1); char aTimestamp[256]; str_timestamp_ex(m_lDemos[m_DemolistSelectedIndex].m_Date, aTimestamp, sizeof(aTimestamp), "%Y-%m-%d %H:%M:%S"); UI()->DoLabelScaled(&Right, aTimestamp, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Type:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aType, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Length:"), 14.0f, -1); int Length = ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[0]<<24)&0xFF000000) | ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[1]<<16)&0xFF0000) | ((m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[2]<<8)&0xFF00) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aLength[3]&0xFF); char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%d:%02d", Length/60, Length%60); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Version:"), 14.0f, -1); str_format(aBuf, sizeof(aBuf), "%d", m_lDemos[m_DemolistSelectedIndex].m_Info.m_Version); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); // right side Labels = MainView; Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Map:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapName, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(20.0f, 0, &Left); Left.VSplitLeft(130.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Size:"), 14.0f, -1); unsigned Size = (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[0]<<24) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[1]<<16) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[2]<<8) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapSize[3]); if(Size > 1024*1024) str_format(aBuf, sizeof(aBuf), Localize("%.2f MiB"), float(Size)/(1024*1024)); else str_format(aBuf, sizeof(aBuf), Localize("%.2f KiB"), float(Size)/1024); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(20.0f, 0, &Left); Left.VSplitLeft(130.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Crc:"), 14.0f, -1); unsigned Crc = (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[0]<<24) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[1]<<16) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[2]<<8) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[3]); str_format(aBuf, sizeof(aBuf), "%08x", Crc); UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabelScaled(&Left, Localize("Netversion:"), 14.0f, -1); UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aNetversion, 14.0f, -1); } // demo list CUIRect Headers; ListBox.HSplitTop(ms_ListheaderHeight, &Headers, &ListBox); struct CColumn { int m_ID; int m_Sort; CLocConstString m_Caption; int m_Direction; float m_Width; int m_Flags; CUIRect m_Rect; CUIRect m_Spacer; }; enum { COL_ICON=0, COL_DEMONAME, COL_DATE, SORT_DEMONAME=0, SORT_DATE, }; static CColumn s_aCols[] = { {COL_ICON, -1, " ", -1, 14.0f, 0, 0, 0}, {COL_DEMONAME, SORT_DEMONAME, "Demo", 0, 0.0f, 0, 0, 0}, {COL_DATE, SORT_DATE, "Date", 1, 300.0f, 0, 0, 0}, }; RenderTools()->DrawUIRect(&Headers, vec4(0.0f,0,0,0.15f), 0, 0); int NumCols = sizeof(s_aCols)/sizeof(CColumn); // do layout for(int i = 0; i < NumCols; i++) { if(s_aCols[i].m_Direction == -1) { Headers.VSplitLeft(s_aCols[i].m_Width, &s_aCols[i].m_Rect, &Headers); if(i+1 < NumCols) { //Cols[i].flags |= SPACER; Headers.VSplitLeft(2, &s_aCols[i].m_Spacer, &Headers); } } } for(int i = NumCols-1; i >= 0; i--) { if(s_aCols[i].m_Direction == 1) { Headers.VSplitRight(s_aCols[i].m_Width, &Headers, &s_aCols[i].m_Rect); Headers.VSplitRight(2, &Headers, &s_aCols[i].m_Spacer); } } for(int i = 0; i < NumCols; i++) { if(s_aCols[i].m_Direction == 0) s_aCols[i].m_Rect = Headers; } // do headers for(int i = 0; i < NumCols; i++) { CPointerContainer Container(s_aCols[i].m_Caption); if(DoButton_GridHeader(&Container, s_aCols[i].m_Caption, g_Config.m_BrDemoSort == s_aCols[i].m_Sort, &s_aCols[i].m_Rect)) { if(s_aCols[i].m_Sort != -1) { if(g_Config.m_BrDemoSort == s_aCols[i].m_Sort) g_Config.m_BrDemoSortOrder ^= 1; else g_Config.m_BrDemoSortOrder = 0; g_Config.m_BrDemoSort = s_aCols[i].m_Sort; } DemolistPopulate(); DemolistOnUpdate(false); } } // scrollbar CUIRect Scroll; #if defined(__ANDROID__) ListBox.VSplitRight(50, &ListBox, &Scroll); #else ListBox.VSplitRight(15, &ListBox, &Scroll); #endif int Num = (int)(ListBox.h/s_aCols[0].m_Rect.h) + 1; static CButtonContainer s_ScrollBar; static float s_ScrollValue = 0; Scroll.HMargin(5.0f, &Scroll); s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); int ScrollNum = m_lDemos.size()-Num+1; if(ScrollNum > 0) { if(m_ScrollOffset) { s_ScrollValue = (float)(m_ScrollOffset)/ScrollNum; m_ScrollOffset = 0; } if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP) && UI()->MouseInside(&ListBox) && m_pClient->m_pGameConsole->IsClosed()) s_ScrollValue -= 3.0f/ScrollNum; if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN) && UI()->MouseInside(&ListBox) && m_pClient->m_pGameConsole->IsClosed()) s_ScrollValue += 3.0f/ScrollNum; } else ScrollNum = 0; if(m_DemolistSelectedIndex > -1) { for(int i = 0; i < m_NumInputEvents; i++) { int NewIndex = -1; if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS) { if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = m_DemolistSelectedIndex + 1; if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = m_DemolistSelectedIndex - 1; } if(NewIndex > -1 && NewIndex < m_lDemos.size()) { //scroll float IndexY = ListBox.y - s_ScrollValue*ScrollNum*s_aCols[0].m_Rect.h + NewIndex*s_aCols[0].m_Rect.h; int Scroll = ListBox.y > IndexY ? -1 : ListBox.y+ListBox.h < IndexY+s_aCols[0].m_Rect.h ? 1 : 0; if(Scroll) { if(Scroll < 0) { int NumScrolls = (ListBox.y-IndexY+s_aCols[0].m_Rect.h-1.0f)/s_aCols[0].m_Rect.h; s_ScrollValue -= (1.0f/ScrollNum)*NumScrolls; } else { int NumScrolls = (IndexY+s_aCols[0].m_Rect.h-(ListBox.y+ListBox.h)+s_aCols[0].m_Rect.h-1.0f)/s_aCols[0].m_Rect.h; s_ScrollValue += (1.0f/ScrollNum)*NumScrolls; } } m_DemolistSelectedIndex = NewIndex; str_copy(g_Config.m_UiDemoSelected, m_lDemos[NewIndex].m_aName, sizeof(g_Config.m_UiDemoSelected)); DemolistOnUpdate(false); } } } if(s_ScrollValue < 0) s_ScrollValue = 0; if(s_ScrollValue > 1) s_ScrollValue = 1; // set clipping UI()->ClipEnable(&ListBox); CUIRect OriginalView = ListBox; ListBox.y -= s_ScrollValue*ScrollNum*s_aCols[0].m_Rect.h; int NewSelected = -1; #if defined(__ANDROID__) int DoubleClicked = 0; #endif int ItemIndex = -1; for(sorted_array<CDemoItem>::range r = m_lDemos.all(); !r.empty(); r.pop_front()) { ItemIndex++; CUIRect Row; CUIRect SelectHitBox; ListBox.HSplitTop(ms_ListheaderHeight, &Row, &ListBox); SelectHitBox = Row; int Selected = ItemIndex == m_DemolistSelectedIndex; // make sure that only those in view can be selected if(Row.y+Row.h > OriginalView.y && Row.y < OriginalView.y+OriginalView.h) { if(Selected) { CUIRect r = Row; r.Margin(1.5f, &r); RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); } // clip the selection if(SelectHitBox.y < OriginalView.y) // top { 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; if(UI()->DoButtonLogic(r.front().m_aName /* TODO: */, "", Selected, &SelectHitBox)) { NewSelected = ItemIndex; str_copy(g_Config.m_UiDemoSelected, r.front().m_aName, sizeof(g_Config.m_UiDemoSelected)); DemolistOnUpdate(false); #if defined(__ANDROID__) if(NewSelected == m_DoubleClickIndex) DoubleClicked = 1; #endif m_DoubleClickIndex = NewSelected; } } else { // don't render invisible items continue; } for(int c = 0; c < NumCols; c++) { CUIRect Button; Button.x = s_aCols[c].m_Rect.x; Button.y = Row.y; Button.h = Row.h; Button.w = s_aCols[c].m_Rect.w; int ID = s_aCols[c].m_ID; if (ID == COL_ICON) { DoButton_Icon(IMAGE_FILEICONS, r.front().m_IsDir?SPRITE_FILE_FOLDER:SPRITE_FILE_DEMO1, &Button); } else if(ID == COL_DEMONAME) { CTextCursor Cursor; TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f * UI()->Scale(), TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Button.w; TextRender()->TextEx(&Cursor, r.front().m_aName, -1); } else if (ID == COL_DATE && !r.front().m_IsDir) { CTextCursor Cursor; TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f * UI()->Scale(), TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Button.w; char aBuf[256]; str_timestamp_ex(r.front().m_Date, aBuf, sizeof(aBuf), "%Y-%m-%d %H:%M:%S"); TextRender()->TextEx(&Cursor, aBuf, -1); } } } UI()->ClipDisable(); bool Activated = false; #if defined(__ANDROID__) if (m_EnterPressed || (DoubleClicked && UI()->HotItem() == m_lDemos[m_DemolistSelectedIndex].m_aName)) #else if (m_EnterPressed || (Input()->MouseDoubleClick() && UI()->HotItem() == m_lDemos[m_DemolistSelectedIndex].m_aName)) #endif { UI()->SetActiveItem(0); Activated = true; } static CButtonContainer s_RefreshButton; if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect) || Input()->KeyPress(KEY_F5) || (Input()->KeyPress(KEY_R) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL)))) { DemolistPopulate(); DemolistOnUpdate(false); } static CButtonContainer s_PlayButton; if(DoButton_Menu(&s_PlayButton, m_DemolistSelectedIsDir?Localize("Open"):Localize("Play"), 0, &PlayRect) || Activated) { if(m_DemolistSelectedIndex >= 0) { if(m_DemolistSelectedIsDir) // folder { if(str_comp(m_lDemos[m_DemolistSelectedIndex].m_aFilename, "..") == 0) // parent folder fs_parent_dir(m_aCurrentDemoFolder); else // sub folder { char aTemp[256]; str_copy(aTemp, m_aCurrentDemoFolder, sizeof(aTemp)); str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", aTemp, m_lDemos[m_DemolistSelectedIndex].m_aFilename); m_DemolistStorageType = m_lDemos[m_DemolistSelectedIndex].m_StorageType; } DemolistPopulate(); DemolistOnUpdate(true); } else // file { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); const char *pError = Client()->DemoPlayer_Play(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType); if(pError) PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("Error loading demo"), Localize("Ok")); else { UI()->SetActiveItem(0); return; } } } } if(!m_DemolistSelectedIsDir) { static CButtonContainer s_DeleteButton; if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &DeleteRect) || m_DeletePressed) { if(m_DemolistSelectedIndex >= 0) { UI()->SetActiveItem(0); m_Popup = POPUP_DELETE_DEMO; return; } } static CButtonContainer s_RenameButton; if(DoButton_Menu(&s_RenameButton, Localize("Rename"), 0, &RenameRect)) { if(m_DemolistSelectedIndex >= 0) { UI()->SetActiveItem(0); m_Popup = POPUP_RENAME_DEMO; str_copy(m_aCurrentDemoFile, m_lDemos[m_DemolistSelectedIndex].m_aFilename, sizeof(m_aCurrentDemoFile)); return; } } } }
void CMenus::RenderSPPage0(CUIRect MainView) { // settings player page 0 CUIRect Button, Label; MainView.HSplitTop(10.0f, 0, &MainView); // player name MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); char aBuf[128]; str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); static float s_OffsetName = 0.0f; if(DoEditBox(g_Config.m_PlayerName, &Button, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 14.0f, &s_OffsetName)) m_NeedSendinfo = true; // player clan MainView.HSplitTop(5.0f, 0, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(80.0f, &Label, &Button); Button.VSplitLeft(150.0f, &Button, 0); str_format(aBuf, sizeof(aBuf), "%s:", Localize("Clan")); UI()->DoLabelScaled(&Label, aBuf, 14.0, -1); static float s_OffsetClan = 0.0f; if(DoEditBox(g_Config.m_PlayerClan, &Button, g_Config.m_PlayerClan, sizeof(g_Config.m_PlayerClan), 14.0f, &s_OffsetClan)) m_NeedSendinfo = true; // country flag selector MainView.HSplitTop(20.0f, 0, &MainView); MainView.HSplitTop(200.0f, &Button, &MainView); static float s_ScrollValue = 0.0f; int OldSelected = -1; UiDoListboxStart(&s_ScrollValue, &Button, 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->Get(i); if(pEntry == 0) continue; if(pEntry->m_CountryCode == g_Config.m_PlayerCountry) OldSelected = i; CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i); if(Item.m_Visible) { Item.m_Rect.Margin(10.0f, &Item.m_Rect); float OldWidth = Item.m_Rect.w; Item.m_Rect.w = 96.0f*Item.m_Rect.h/64.0f; 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(); } } const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { g_Config.m_PlayerCountry = m_pClient->m_pCountryFlags->Get(NewSelected)->m_CountryCode; m_NeedSendinfo = true; } CUIRect Left, Right; MainView.HSplitTop(20.0f, 0, &MainView); MainView.VSplitMid(&Left, &Right); Left.VSplitRight(5.0f, &Left, 0); Right.VMargin(5.0f, &Right); // dynamic camera Left.HSplitTop(20.0f, &Button, &Left); static int s_DynamicCameraButton = 0; if(DoButton_CheckBox(&s_DynamicCameraButton, Localize("Dynamic Camera"), g_Config.m_ClMouseDeadzone != 0, &Button)) { if(g_Config.m_ClMouseDeadzone) { g_Config.m_ClMouseFollowfactor = 0; g_Config.m_ClMouseMaxDistance = 400; g_Config.m_ClMouseDeadzone = 0; } else { g_Config.m_ClMouseFollowfactor = 60; g_Config.m_ClMouseMaxDistance = 1000; g_Config.m_ClMouseDeadzone = 300; } } // weapon pickup Left.HSplitTop(5.0f, 0, &Left); Left.HSplitTop(20.0f, &Button, &Left); if(DoButton_CheckBox(&g_Config.m_ClAutoswitchWeapons, Localize("Switch weapon on pickup"), g_Config.m_ClAutoswitchWeapons, &Button)) g_Config.m_ClAutoswitchWeapons ^= 1; // show hud Left.HSplitTop(5.0f, 0, &Left); Left.HSplitTop(20.0f, &Button, &Left); if(DoButton_CheckBox(&g_Config.m_ClShowhud, Localize("Show ingame HUD"), g_Config.m_ClShowhud, &Button)) g_Config.m_ClShowhud ^= 1; // name plates Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClNameplates, Localize("Show name plates"), g_Config.m_ClNameplates, &Button)) g_Config.m_ClNameplates ^= 1; if(g_Config.m_ClNameplates) { Right.HSplitTop(2.5f, 0, &Right); Right.VSplitLeft(30.0f, 0, &Right); Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClNameplatesAlways, Localize("Always show name plates"), g_Config.m_ClNameplatesAlways, &Button)) g_Config.m_ClNameplatesAlways ^= 1; Right.HSplitTop(2.5f, 0, &Right); Right.HSplitTop(20.0f, &Label, &Right); Right.HSplitTop(20.0f, &Button, &Right); str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Name plates size"), g_Config.m_ClNameplatesSize); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Button.HMargin(2.0f, &Button); g_Config.m_ClNameplatesSize = (int)(DoScrollbarH(&g_Config.m_ClNameplatesSize, &Button, g_Config.m_ClNameplatesSize/100.0f)*100.0f+0.1f); Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClNameplatesTeamcolors, Localize("Use team colors for name plates"), g_Config.m_ClNameplatesTeamcolors, &Button)) g_Config.m_ClNameplatesTeamcolors ^= 1; } }
float CMenus::RenderDemoDetails(CUIRect View, void *pUser) { CMenus *pSelf = (CMenus*)pUser; // render demo info if(!pSelf->m_DemolistSelectedIsDir && pSelf->m_DemolistSelectedIndex >= 0 && pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Valid) { CUIRect Button; const float ButtonHeight = 20.0f; const float Spacing = 2.0f; View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); pSelf->DoInfoBox(&Button, Localize("Created"), pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aTimestamp); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); pSelf->DoInfoBox(&Button, Localize("Type"), pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aType); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); int Length = ((pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aLength[0]<<24)&0xFF000000) | ((pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aLength[1]<<16)&0xFF0000) | ((pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aLength[2]<<8)&0xFF00) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aLength[3]&0xFF); char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%d:%02d", Length/60, Length%60); pSelf->DoInfoBox(&Button, Localize("Length"), aBuf); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); str_format(aBuf, sizeof(aBuf), "%d", pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_Version); pSelf->DoInfoBox(&Button, Localize("Version"), aBuf); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); pSelf->DoInfoBox(&Button, Localize("Netversion"), pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aNetversion); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); const int MarkerCount = DemoGetMarkerCount(pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info); str_format(aBuf, sizeof(aBuf), "%d", MarkerCount); if(MarkerCount > 0) pSelf->TextRender()->TextColor(0.5, 1, 0.5, 1); pSelf->DoInfoBox(&Button, Localize("Markers"), aBuf); pSelf->TextRender()->TextColor(1, 1, 1, 1); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); pSelf->DoInfoBox(&Button, Localize("Map"), pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapName); View.HSplitTop(Spacing, 0, &View); View.HSplitTop(ButtonHeight, &Button, &View); Button.VMargin(ButtonHeight, &Button); CUIRect ButtonRight; Button.VSplitMid(&Button, &ButtonRight); float Size = float((pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapSize[0]<<24) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapSize[1]<<16) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapSize[2]<<8) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapSize[3]))/1024.0f; str_format(aBuf, sizeof(aBuf), Localize("%.3f KiB"), Size); pSelf->DoInfoBox(&Button, Localize("Size"), aBuf); unsigned Crc = (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapCrc[0]<<24) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapCrc[1]<<16) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapCrc[2]<<8) | (pSelf->m_lDemos[pSelf->m_DemolistSelectedIndex].m_Info.m_aMapCrc[3]); str_format(aBuf, sizeof(aBuf), "%08x", Crc); pSelf->DoInfoBox(&ButtonRight, Localize("Crc"), aBuf); } //unused return 0.0f; }
void CMenus::RenderSettingsIdentTee(CUIRect MainView, int Page) { CIdentity::CIdentEntry *pEntry = m_pClient->m_pIdentity->GetIdent(Page); if(!m_pClient->m_pIdentity->NumIdents() || !pEntry) return; CUIRect Button, Label, View; // skin info const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(pEntry->m_aSkin)); CTeeRenderInfo OwnSkinInfo; if(pEntry->m_UseCustomColor) { OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorBody); OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColorV4(pEntry->m_ColorFeet); } else { OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; OwnSkinInfo.m_ColorBody = vec4(1.0f, 1.0f, 1.0f, 1.0f); OwnSkinInfo.m_ColorFeet = vec4(1.0f, 1.0f, 1.0f, 1.0f); } OwnSkinInfo.m_Size = 50.0f*UI()->Scale(); MainView.Margin(10.0f, &MainView); MainView.HSplitTop(50.0f, &Label, &MainView); Label.VSplitMid(&View, &Label); // skin view RenderTools()->DrawUIRect(&Label, vec4(1.0f, 1.0f, 1.0f, 0.25f), CUI::CORNER_ALL, 10.0f); RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Label.x+30.0f, Label.y+28.0f)); Label.HSplitTop(15.0f, 0, &Label); Label.VSplitLeft(70.0f, 0, &Label); UI()->DoLabelScaled(&Label, pEntry->m_aSkin, 14.0f, -1, 150); // player name View.HSplitTop(20.0f, &Button, &View); Button.VSplitLeft(230.0f, &Button, 0); static CButtonContainer s_VanillaSkinsOnly; if(DoButton_CheckBox(&s_VanillaSkinsOnly, Localize("Allow Vanilla Skins only"), g_Config.m_ClVanillaSkinsOnly, &Button)) { g_Config.m_ClVanillaSkinsOnly ^= 1; GameClient()->m_pSkins->RefreshSkinList(); m_InitSkinlist = true; } // player clan View.HSplitTop(5.0f, 0, &View); View.HSplitTop(20.0f, &Button, &View); Button.VSplitLeft(230.0f, &Button, 0); static CButtonContainer s_CheckboxUseCustomColor; if(DoButton_CheckBox(&s_CheckboxUseCustomColor, Localize("Custom colors"), pEntry->m_UseCustomColor, &Button)) { pEntry->m_UseCustomColor ^= 1; m_NeedSendinfo = true; } // apply identity MainView.HSplitTop(5.0f, 0, &MainView); // vanilla skins only MainView.HSplitTop(10.0f, 0, &View); if(pEntry->m_UseCustomColor) { CUIRect aRects[2]; MainView.VSplitMid(&aRects[0], &aRects[1]); aRects[0].VSplitRight(10.0f, &aRects[0], 0); aRects[1].VSplitRight(10.0f, &aRects[1], 0); int *paColors[2] = { &pEntry->m_ColorBody, &pEntry->m_ColorFeet }; const char *paParts[] = { Localize("Body"), Localize("Feet")}; const char *paLabels[] = { Localize("Hue"), Localize("Sat."), Localize("Lht.")}; static int s_aColorSlider[2][3] = { { 0 } }; for(int i = 0; i < 2; i++) { aRects[i].HSplitTop(20.0f, &Label, &aRects[i]); UI()->DoLabelScaled(&Label, paParts[i], 14.0f, -1); aRects[i].VSplitLeft(20.0f, 0, &aRects[i]); aRects[i].HSplitTop(2.5f, 0, &aRects[i]); int PrevColor = *paColors[i]; int Color = 0; for(int s = 0; s < 3; s++) { aRects[i].HSplitTop(20.0f, &Label, &aRects[i]); Label.VSplitLeft(100.0f, &Label, &Button); Button.HMargin(2.0f, &Button); float k = ((PrevColor>>((2-s)*8))&0xff) / 255.0f; CPointerContainer Container(&s_aColorSlider[i][s]); k = DoScrollbarH(&Container, &Button, k, 0, (int)(k * 100.0f)); Color <<= 8; Color += clamp((int)(k*255), 0, 255); UI()->DoLabelScaled(&Label, paLabels[s], 14.0f, -1); } if(PrevColor != Color) m_NeedSendinfo = true; *paColors[i] = Color; } }
void CScoreboard::RenderScoreboard64(float x, float y, float w, int Team, const char *pTitle) { if(Team == TEAM_SPECTATORS) return; bool isDDRace = Client()->IsServerType("ddrace"); float h = 760.0f; CUIRect area; area.x = x; area.y = y; area.w = w; area.h = h; Graphics()->BlendNormal(); Graphics()->TextureSet(-1); // render title CUIRect rTitle; area.HSplitTop(60.0f, &rTitle, &area); float TitleFontsize = 40.0f; if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) pTitle = Localize("Game over"); else pTitle = Localize("Score board"); RenderTools()->DrawUIRect(&rTitle, HexToVec4(g_Config.m_hcContainerHeaderBackgroundColor), CUI::CORNER_T, 10.0f); rTitle.Margin(10.0f, &rTitle); char aBuf[128] = {0}; if(m_pClient->m_Snap.m_pGameDataObj) { int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue; str_format(aBuf, sizeof(aBuf), "%d", Score); } float tw = TextRender()->TextWidth(0, TitleFontsize, aBuf, -1); CUIRect rTitlePoints; rTitle.VSplitRight(tw+5.0f, 0x0, &rTitlePoints); TextRender()->Text(0, rTitlePoints.x, rTitlePoints.y-5.0f, TitleFontsize, aBuf, -1); float LineHeight = 40.0f; float TeeSizeMod = 0.4f; float Spacing = 0.0f; float HeadlineFontsize = 12.0f; float FontSize = 14.0f; int part = 0; CTextCursor Cursor; CUIRect parts[4]; area.VSplitMid(&parts[0], &parts[2]); parts[0].VSplitMid(&parts[0], &parts[1]); parts[2].VSplitMid(&parts[2], &parts[3]); float ScoreOffset, ScoreLength; float TeeOffset, TeeLength; float NameOffset, NameLength; float PingOffset, PingLength; float CountryOffset, CountryLength; float ClanOffset, ClanLength; int nPlayers = 0; bool fi = false; for(int i = 0; i < MAX_CLIENTS; i++) { if (!fi || (i%16) == 0) { if (fi) part++; x = parts[part].x; y = parts[part].y; ScoreOffset = x+10.0f; ScoreLength = 60.0f; TeeOffset = parts[part].x+90.0f; TeeLength = 60*TeeSizeMod; NameOffset = TeeOffset+TeeLength; NameLength = 200.0f-TeeLength; PingOffset = x+390.0f; PingLength = 65.0f; CountryOffset = PingOffset-(LineHeight-Spacing-TeeSizeMod); CountryLength = (LineHeight-Spacing-TeeSizeMod*3.0f)*2.0f; ClanOffset = x+230.0f; ClanLength = 230.0f-CountryLength; // render headlines CUIRect rHeadLines, rLabel; parts[part].HSplitTop(40.0f, &rHeadLines, &parts[part]); RenderTools()->DrawUIRect(&rHeadLines, HexToVec4(g_Config.m_hcListHeaderBackgroundColor), 0, 0.0f); rHeadLines.Margin(5.0f,&rHeadLines); y += 50.0f; rHeadLines.VSplitLeft(80.0f, &rLabel, &rHeadLines); TextRender()->Text(0, rLabel.x + 20.0f, rLabel.y, HeadlineFontsize, Localize(isDDRace?"Time":"Score"), -1); rHeadLines.VSplitLeft(200.0f, &rLabel, &rHeadLines); TextRender()->Text(0, rLabel.x, rLabel.y, HeadlineFontsize, Localize("Name"), -1); rHeadLines.VSplitLeft(150.0f, &rLabel, &rHeadLines); TextRender()->Text(0, rLabel.x, rLabel.y, HeadlineFontsize, Localize("Clan"), -1); rHeadLines.VSplitLeft(80.0f, &rLabel, &rHeadLines); TextRender()->Text(0, rLabel.x, rLabel.y, HeadlineFontsize, Localize("Ping"), -1); int corner = 0; if (part==0) corner = CUI::CORNER_BL; else if (part==3) corner = CUI::CORNER_BR; vec4 baColor = HexToVec4(g_Config.m_hcContainerBackgroundColor); RenderTools()->DrawUIRect(&parts[part], vec4(baColor.r, baColor.g, baColor.b, part%2==0?0.5f:0.65f), corner, 10.0f); fi = true; } // make sure that we render the correct team const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_paInfoByDDTeam[i]; if(!pInfo) continue; nPlayers++; // background so it's easy to find the local player or the followed one in spectator mode if(pInfo->m_Local || (m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientID == m_pClient->m_Snap.m_SpecInfo.m_SpectatorID)) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); RenderTools()->DrawRoundRectExt(x, y, parts[part].w, LineHeight, 0.0f, 0); Graphics()->QuadsEnd(); } // score if(isDDRace) { if (pInfo->m_Score == -9999) str_copy(aBuf, "––:––", sizeof(aBuf)); else { int Time = abs(pInfo->m_Score); str_format(aBuf, sizeof(aBuf), "%02d:%02d", Time/60, Time%60); } } else str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 999)); tw = TextRender()->TextWidth(0, FontSize, aBuf, -1); TextRender()->SetCursor(&Cursor, ScoreOffset+ScoreLength-tw, y+Spacing+3.0f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = ScoreLength; TextRender()->TextEx(&Cursor, aBuf, -1); // avatar CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo; TeeInfo.m_Size *= TeeSizeMod; RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(TeeOffset+TeeLength/2, y+LineHeight/2-3.0f)); // name if (g_Config.m_hcColorClan && m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_aClan[0] != 0 && str_comp_nocase(m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_aClan) == 0) //H-Client TextRender()->TextColor(0.7f, 0.7f, 0.2f, 1.0f); TextRender()->SetCursor(&Cursor, NameOffset, y+Spacing+3.0f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = NameLength; TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); // clan tw = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1); TextRender()->SetCursor(&Cursor, ClanOffset+ClanLength/2-tw/2-5.0f, y+Spacing+3.0f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = ClanLength; TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1); // country flag Graphics()->TextureSet(m_pClient->m_pCountryFlags->GetByCountryCode(m_pClient->m_aClients[pInfo->m_ClientID].m_Country)->m_Texture); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f); IGraphics::CQuadItem QuadItem(CountryOffset, y+(Spacing+TeeSizeMod*5.0f)/2.0f, CountryLength, LineHeight-Spacing-TeeSizeMod*5.0f); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // ping //H-Client const int maxLatency = 200; vec3 Rgb = HslToRgb(vec3(1.0f, 1.0f, 0.5f)); if (pInfo->m_Latency <= maxLatency) Rgb = HslToRgb(vec3((((maxLatency - pInfo->m_Latency) * 0.35f) / maxLatency), 1.0f, 0.5f)); TextRender()->TextColor(Rgb.r, Rgb.g, Rgb.b, 1.0f); // str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 1000)); tw = TextRender()->TextWidth(0, FontSize, aBuf, -1); TextRender()->SetCursor(&Cursor, PingOffset+PingLength-tw, y+Spacing+3.0f, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = PingLength; TextRender()->TextEx(&Cursor, aBuf, -1); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); y += LineHeight+Spacing; } //Title char aTitle[128]={0}; str_format(aTitle, sizeof(aTitle), "%s [%d]", pTitle, nPlayers); TextRender()->Text(0, rTitle.x, rTitle.y-5.0f, TitleFontsize, aTitle, -1); }