diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index d56cd80dd..f88b0489f 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1215,7 +1215,7 @@ int CMenus::Render() else if(m_Popup == POPUP_RENAME_DEMO) { dbg_assert(m_DemolistSelectedIndex >= 0, "m_DemolistSelectedIndex invalid for POPUP_RENAME_DEMO"); - pTitle = m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir ? Localize("Rename folder") : Localize("Rename demo"); + pTitle = m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir ? Localize("Rename folder") : Localize("Rename demo"); } #if defined(CONF_VIDEORECORDER) else if(m_Popup == POPUP_RENDER_DEMO) @@ -1519,31 +1519,31 @@ int CMenus::Render() m_Popup = POPUP_NONE; // rename demo char aBufOld[IO_MAX_PATH_LENGTH]; - str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); char aBufNew[IO_MAX_PATH_LENGTH]; str_format(aBufNew, sizeof(aBufNew), "%s/%s", m_aCurrentDemoFolder, m_DemoRenameInput.GetString()); - if(!m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir && !str_endswith(aBufNew, ".demo")) + if(!m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir && !str_endswith(aBufNew, ".demo")) str_append(aBufNew, ".demo"); - if(Storage()->FileExists(aBufNew, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType)) + if(Storage()->FileExists(aBufNew, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType)) { PopupMessage(Localize("Error"), Localize("A demo with this name already exists"), Localize("Ok"), POPUP_RENAME_DEMO); } - else if(Storage()->FolderExists(aBufNew, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType)) + else if(Storage()->FolderExists(aBufNew, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType)) { PopupMessage(Localize("Error"), Localize("A folder with this name already exists"), Localize("Ok"), POPUP_RENAME_DEMO); } - else if(Storage()->RenameFile(aBufOld, aBufNew, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType)) + else if(Storage()->RenameFile(aBufOld, aBufNew, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType)) { str_copy(m_aCurrentDemoSelectionName, m_DemoRenameInput.GetString()); - if(!m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) + if(!m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) fs_split_file_extension(m_DemoRenameInput.GetString(), m_aCurrentDemoSelectionName, sizeof(m_aCurrentDemoSelectionName)); DemolistPopulate(); DemolistOnUpdate(false); } else { - PopupMessage(Localize("Error"), m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir ? Localize("Unable to rename the folder") : Localize("Unable to rename the demo"), Localize("Ok"), POPUP_RENAME_DEMO); + PopupMessage(Localize("Error"), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir ? Localize("Unable to rename the folder") : Localize("Unable to rename the demo"), Localize("Ok"), POPUP_RENAME_DEMO); } } @@ -1560,7 +1560,7 @@ int CMenus::Render() #if defined(CONF_VIDEORECORDER) else if(m_Popup == POPUP_RENDER_DEMO) { - dbg_assert(m_DemolistSelectedIndex >= 0 && !m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir, "m_DemolistSelectedIndex invalid for POPUP_RENDER_DEMO"); + dbg_assert(m_DemolistSelectedIndex >= 0 && !m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir, "m_DemolistSelectedIndex invalid for POPUP_RENDER_DEMO"); CUIRect Label, TextBox, Ok, Abort, Button; @@ -1793,12 +1793,12 @@ int CMenus::Render() void CMenus::PopupConfirmDemoReplaceVideo() { char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); char aVideoName[IO_MAX_PATH_LENGTH]; str_copy(aVideoName, m_DemoRenderInput.GetString()); if(!str_endswith(aVideoName, ".mp4")) str_append(aVideoName, ".mp4"); - const char *pError = Client()->DemoPlayer_Render(aBuf, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType, aVideoName, m_Speed, m_StartPaused); + const char *pError = Client()->DemoPlayer_Render(aBuf, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType, aVideoName, m_Speed, m_StartPaused); m_Speed = 4; m_StartPaused = false; m_LastPauseChange = -1.0f; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 9c72bd85c..b51313b3e 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -594,8 +594,9 @@ public: // DDRace int DoButton_CheckBox_Tristate(const void *pID, const char *pText, TRISTATE Checked, const CUIRect *pRect); std::vector m_vDemos; - std::vector m_vFilteredDemos; + std::vector m_vpFilteredDemos; void DemolistPopulate(); + void RefreshFilteredDemos(); void DemoSeekTick(IDemoPlayer::ETickOffset TickOffset); bool m_Dummy; diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 666ed2edf..a84bdb302 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -890,6 +890,19 @@ void CMenus::DemolistPopulate() std::stable_sort(m_vDemos.begin(), m_vDemos.end()); } + RefreshFilteredDemos(); +} + +void CMenus::RefreshFilteredDemos() +{ + m_vpFilteredDemos.clear(); + for(auto &Demo : m_vDemos) + { + if(str_find_nocase(Demo.m_aFilename, m_DemoSearchInput.GetString())) + { + m_vpFilteredDemos.push_back(&Demo); + } + } } void CMenus::DemolistOnUpdate(bool Reset) @@ -901,23 +914,24 @@ void CMenus::DemolistOnUpdate(bool Reset) bool Found = false; int SelectedIndex = -1; // search for selected index - for(auto &Item : m_vFilteredDemos) + for(auto &Item : m_vpFilteredDemos) { SelectedIndex++; - if(str_comp(m_aCurrentDemoSelectionName, Item.m_aName) == 0) + if(str_comp(m_aCurrentDemoSelectionName, Item->m_aName) == 0) { Found = true; break; } } + RefreshFilteredDemos(); if(Found) m_DemolistSelectedIndex = SelectedIndex; } - m_DemolistSelectedIndex = Reset ? !m_vFilteredDemos.empty() ? 0 : -1 : - m_DemolistSelectedIndex >= (int)m_vFilteredDemos.size() ? m_vFilteredDemos.size() - 1 : m_DemolistSelectedIndex; + m_DemolistSelectedIndex = Reset ? !m_vpFilteredDemos.empty() ? 0 : -1 : + m_DemolistSelectedIndex >= (int)m_vpFilteredDemos.size() ? m_vpFilteredDemos.size() - 1 : m_DemolistSelectedIndex; m_DemolistSelectedReveal = true; } @@ -952,26 +966,17 @@ void CMenus::RenderDemoList(CUIRect MainView) s_Inited = 1; } - m_vFilteredDemos.clear(); - for(auto &Demo : m_vDemos) - { - if(str_find_nocase(Demo.m_aFilename, m_DemoSearchInput.GetString())) - { - m_vFilteredDemos.push_back(Demo); - } - } - char aFooterLabel[128] = {0}; if(m_DemolistSelectedIndex >= 0) { - CDemoItem &Item = m_vFilteredDemos[m_DemolistSelectedIndex]; - if(str_comp(Item.m_aFilename, "..") == 0) + CDemoItem* Item = m_vpFilteredDemos[m_DemolistSelectedIndex]; + if(str_comp(Item->m_aFilename, "..") == 0) str_copy(aFooterLabel, Localize("Parent Folder")); - else if(m_vFilteredDemos[m_DemolistSelectedIndex].m_IsLink) + else if(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsLink) str_copy(aFooterLabel, Localize("Folder Link")); - else if(m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) + else if(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) str_copy(aFooterLabel, Localize("Folder")); - else if(!FetchHeader(Item)) + else if(!FetchHeader(*Item)) str_copy(aFooterLabel, Localize("Invalid Demo")); else str_copy(aFooterLabel, Localize("Demo details")); @@ -1015,7 +1020,7 @@ void CMenus::RenderDemoList(CUIRect MainView) MainView.VMargin(5.0f, &MainView); MainView.HSplitBottom(5.0f, &MainView, 0); MainView.Draw(ColorRGBA(0, 0, 0, 0.15f), IGraphics::CORNER_B, 4.0f); - if(m_DemolistSelectedIndex >= 0 && !m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir && m_vFilteredDemos[m_DemolistSelectedIndex].m_Valid) + if(m_DemolistSelectedIndex >= 0 && !m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir && m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Valid) { CUIRect Left, Right, Labels; MainView.VMargin(20.0f, &MainView); @@ -1028,19 +1033,19 @@ void CMenus::RenderDemoList(CUIRect MainView) UI()->DoLabel(&Left, Localize("Created:"), 14.0f, TEXTALIGN_ML); char aTimestamp[256]; - str_timestamp_ex(m_vFilteredDemos[m_DemolistSelectedIndex].m_Date, aTimestamp, sizeof(aTimestamp), FORMAT_SPACE); + str_timestamp_ex(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Date, aTimestamp, sizeof(aTimestamp), FORMAT_SPACE); UI()->DoLabel(&Right, aTimestamp, 14.0f, TEXTALIGN_ML); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Type:"), 14.0f, TEXTALIGN_ML); - UI()->DoLabel(&Right, m_vFilteredDemos[m_DemolistSelectedIndex].m_Info.m_aType, 14.0f, TEXTALIGN_ML); + UI()->DoLabel(&Right, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Info.m_aType, 14.0f, TEXTALIGN_ML); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Length:"), 14.0f, TEXTALIGN_ML); - int Length = m_vFilteredDemos[m_DemolistSelectedIndex].Length(); + int Length = m_vpFilteredDemos[m_DemolistSelectedIndex]->Length(); char aBuf[64]; str_time((int64_t)Length * 100, TIME_HOURS, aBuf, sizeof(aBuf)); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); @@ -1048,13 +1053,13 @@ void CMenus::RenderDemoList(CUIRect MainView) Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Version:"), 14.0f, TEXTALIGN_ML); - str_from_int(m_vFilteredDemos[m_DemolistSelectedIndex].m_Info.m_Version, aBuf); + str_from_int(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Info.m_Version, aBuf); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Markers:"), 14.0f, TEXTALIGN_ML); - str_from_int(m_vFilteredDemos[m_DemolistSelectedIndex].NumMarkers(), aBuf); + str_from_int(m_vpFilteredDemos[m_DemolistSelectedIndex]->NumMarkers(), aBuf); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); // right side @@ -1062,12 +1067,12 @@ void CMenus::RenderDemoList(CUIRect MainView) Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Map:"), 14.0f, TEXTALIGN_ML); - UI()->DoLabel(&Right, m_vFilteredDemos[m_DemolistSelectedIndex].m_Info.m_aMapName, 14.0f, TEXTALIGN_ML); + UI()->DoLabel(&Right, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Info.m_aMapName, 14.0f, TEXTALIGN_ML); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Size:"), 14.0f, TEXTALIGN_ML); - const float Size = m_vFilteredDemos[m_DemolistSelectedIndex].Size() / 1024.0f; + const float Size = m_vpFilteredDemos[m_DemolistSelectedIndex]->Size() / 1024.0f; if(Size > 1024) str_format(aBuf, sizeof(aBuf), Localize("%.2f MiB"), Size / 1024.0f); else @@ -1076,17 +1081,17 @@ void CMenus::RenderDemoList(CUIRect MainView) Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); - if(m_vFilteredDemos[m_DemolistSelectedIndex].m_MapInfo.m_Sha256 != SHA256_ZEROED) + if(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_MapInfo.m_Sha256 != SHA256_ZEROED) { UI()->DoLabel(&Left, "SHA256:", 14.0f, TEXTALIGN_ML); char aSha[SHA256_MAXSTRSIZE]; - sha256_str(m_vFilteredDemos[m_DemolistSelectedIndex].m_MapInfo.m_Sha256, aSha, sizeof(aSha) / 2); + sha256_str(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_MapInfo.m_Sha256, aSha, sizeof(aSha) / 2); UI()->DoLabel(&Right, aSha, Right.w > 235 ? 14.0f : 11.0f, TEXTALIGN_ML); } else { UI()->DoLabel(&Left, Localize("Crc:"), 14.0f, TEXTALIGN_ML); - str_format(aBuf, sizeof(aBuf), "%08x", m_vFilteredDemos[m_DemolistSelectedIndex].m_MapInfo.m_Crc); + str_format(aBuf, sizeof(aBuf), "%08x", m_vpFilteredDemos[m_DemolistSelectedIndex]->m_MapInfo.m_Crc); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); } Labels.HSplitTop(5.0f, 0, &Labels); @@ -1094,7 +1099,7 @@ void CMenus::RenderDemoList(CUIRect MainView) Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Netversion:"), 14.0f, TEXTALIGN_ML); - UI()->DoLabel(&Right, m_vFilteredDemos[m_DemolistSelectedIndex].m_Info.m_aNetversion, 14.0f, TEXTALIGN_ML); + UI()->DoLabel(&Right, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_Info.m_aNetversion, 14.0f, TEXTALIGN_ML); } // demo list @@ -1177,7 +1182,7 @@ void CMenus::RenderDemoList(CUIRect MainView) } // Don't rescan in order to keep fetched headers, just resort - std::stable_sort(m_vFilteredDemos.begin(), m_vFilteredDemos.end()); + std::stable_sort(m_vpFilteredDemos.begin(), m_vpFilteredDemos.end()); DemolistOnUpdate(false); } } @@ -1188,10 +1193,10 @@ void CMenus::RenderDemoList(CUIRect MainView) m_DemolistSelectedReveal = false; } - s_ListBox.DoStart(ms_ListheaderHeight, m_vFilteredDemos.size(), 1, 3, m_DemolistSelectedIndex, &ListBox, false, IGraphics::CORNER_ALL, true); + s_ListBox.DoStart(ms_ListheaderHeight, m_vpFilteredDemos.size(), 1, 3, m_DemolistSelectedIndex, &ListBox, false, IGraphics::CORNER_ALL, true); int ItemIndex = -1; - for(auto &Item : m_vFilteredDemos) + for(auto &Item : m_vpFilteredDemos) { ItemIndex++; @@ -1214,15 +1219,15 @@ void CMenus::RenderDemoList(CUIRect MainView) Button.Margin(1.0f, &Button); const char *pIconType; - if(Item.m_IsLink || str_comp(Item.m_aFilename, "..") == 0) + if(Item->m_IsLink || str_comp(Item->m_aFilename, "..") == 0) pIconType = FONT_ICON_FOLDER_TREE; - else if(Item.m_IsDir) + else if(Item->m_IsDir) pIconType = FONT_ICON_FOLDER; else pIconType = FONT_ICON_FILM; ColorRGBA IconColor; - if(!Item.m_IsDir && (!Item.m_InfosLoaded || !Item.m_Valid)) + if(!Item->m_IsDir && (!Item->m_InfosLoaded || !Item->m_Valid)) IconColor = ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f); // not loaded else IconColor = ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f); @@ -1241,26 +1246,26 @@ void CMenus::RenderDemoList(CUIRect MainView) Props.m_MaxWidth = Button.w; Props.m_EllipsisAtEnd = true; Props.m_EnableWidthCheck = false; - UI()->DoLabel(&Button, Item.m_aName, 12.0f, TEXTALIGN_ML, Props); + UI()->DoLabel(&Button, Item->m_aName, 12.0f, TEXTALIGN_ML, Props); } - else if(ID == COL_MARKERS && !Item.m_IsDir && Item.m_InfosLoaded && Item.m_Valid) + else if(ID == COL_MARKERS && !Item->m_IsDir && Item->m_InfosLoaded && Item->m_Valid) { char aBuf[3]; - str_from_int(Item.NumMarkers(), aBuf); + str_from_int(Item->NumMarkers(), aBuf); Button.VMargin(4.0f, &Button); UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR); } - else if(ID == COL_LENGTH && !Item.m_IsDir && Item.m_InfosLoaded && Item.m_Valid) + else if(ID == COL_LENGTH && !Item->m_IsDir && Item->m_InfosLoaded && Item->m_Valid) { char aBuf[32]; - str_time((int64_t)Item.Length() * 100, TIME_HOURS, aBuf, sizeof(aBuf)); + str_time((int64_t)Item->Length() * 100, TIME_HOURS, aBuf, sizeof(aBuf)); Button.VMargin(4.0f, &Button); UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR); } - else if(ID == COL_DATE && !Item.m_IsDir) + else if(ID == COL_DATE && !Item->m_IsDir) { char aBuf[64]; - str_timestamp_ex(Item.m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE); + str_timestamp_ex(Item->m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE); Button.VMargin(4.0f, &Button); UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR); } @@ -1272,7 +1277,7 @@ void CMenus::RenderDemoList(CUIRect MainView) { m_DemolistSelectedIndex = NewSelected; if(m_DemolistSelectedIndex >= 0) - str_copy(m_aCurrentDemoSelectionName, m_vFilteredDemos[m_DemolistSelectedIndex].m_aName); + str_copy(m_aCurrentDemoSelectionName, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aName); DemolistOnUpdate(false); } @@ -1291,14 +1296,14 @@ void CMenus::RenderDemoList(CUIRect MainView) } static CButtonContainer s_PlayButton; - if(DoButton_Menu(&s_PlayButton, (m_DemolistSelectedIndex >= 0 && m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) ? Localize("Open") : Localize("Play", "Demo browser"), 0, &PlayRect) || s_ListBox.WasItemActivated() || UI()->ConsumeHotkey(CUI::HOTKEY_ENTER) || (Input()->KeyPress(KEY_P) && m_pClient->m_GameConsole.IsClosed() && !m_DemoSearchInput.IsActive())) + if(DoButton_Menu(&s_PlayButton, (m_DemolistSelectedIndex >= 0 && m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) ? Localize("Open") : Localize("Play", "Demo browser"), 0, &PlayRect) || s_ListBox.WasItemActivated() || UI()->ConsumeHotkey(CUI::HOTKEY_ENTER) || (Input()->KeyPress(KEY_P) && m_pClient->m_GameConsole.IsClosed() && !m_DemoSearchInput.IsActive())) { if(m_DemolistSelectedIndex >= 0) { - if(m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) // folder + if(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) // folder { m_DemoSearchInput.Clear(); - const bool ParentFolder = str_comp(m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename, "..") == 0; + const bool ParentFolder = str_comp(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename, "..") == 0; if(ParentFolder) // parent folder { str_copy(m_aCurrentDemoSelectionName, fs_filename(m_aCurrentDemoFolder)); @@ -1322,8 +1327,8 @@ void CMenus::RenderDemoList(CUIRect MainView) if(m_aCurrentDemoFolder[0] != '\0') str_append(m_aCurrentDemoFolder, "/"); else - m_DemolistStorageType = m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType; - str_append(m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + m_DemolistStorageType = m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType; + str_append(m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); } DemolistPopulate(); DemolistOnUpdate(!ParentFolder); @@ -1331,8 +1336,8 @@ void CMenus::RenderDemoList(CUIRect MainView) else // file { char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); - const char *pError = Client()->DemoPlayer_Play(aBuf, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType); + str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); + const char *pError = Client()->DemoPlayer_Play(aBuf, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType); m_LastPauseChange = -1.0f; m_LastSpeedChange = -1.0f; if(pError) @@ -1350,7 +1355,7 @@ void CMenus::RenderDemoList(CUIRect MainView) if(DoButton_Menu(&s_DirectoryButtonID, Localize("Demos directory"), 0, &DirectoryButton)) { char aBuf[IO_MAX_PATH_LENGTH]; - Storage()->GetCompletePath(m_DemolistSelectedIndex >= 0 ? m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType : IStorage::TYPE_SAVE, m_aCurrentDemoFolder[0] == '\0' ? "demos" : m_aCurrentDemoFolder, aBuf, sizeof(aBuf)); + Storage()->GetCompletePath(m_DemolistSelectedIndex >= 0 ? m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType : IStorage::TYPE_SAVE, m_aCurrentDemoFolder[0] == '\0' ? "demos" : m_aCurrentDemoFolder, aBuf, sizeof(aBuf)); if(!open_file(aBuf)) { dbg_msg("menus", "couldn't open file '%s'", aBuf); @@ -1360,14 +1365,14 @@ void CMenus::RenderDemoList(CUIRect MainView) if(m_DemolistSelectedIndex >= 0 && m_aCurrentDemoFolder[0] != '\0') { - if(str_comp(m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename, "..") != 0 && m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType == IStorage::TYPE_SAVE) + if(str_comp(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename, "..") != 0 && m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType == IStorage::TYPE_SAVE) { static CButtonContainer s_DeleteButton; if(DoButton_Menu(&s_DeleteButton, Localize("Delete"), 0, &DeleteRect) || UI()->ConsumeHotkey(CUI::HOTKEY_DELETE) || (Input()->KeyPress(KEY_D) && m_pClient->m_GameConsole.IsClosed() && !m_DemoSearchInput.IsActive())) { char aBuf[128 + IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir ? Localize("Are you sure that you want to delete the folder '%s'?") : Localize("Are you sure that you want to delete the demo '%s'?"), m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); - PopupConfirm(m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir ? Localize("Delete folder") : Localize("Delete demo"), aBuf, Localize("Yes"), Localize("No"), m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir ? &CMenus::PopupConfirmDeleteFolder : &CMenus::PopupConfirmDeleteDemo); + str_format(aBuf, sizeof(aBuf), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir ? Localize("Are you sure that you want to delete the folder '%s'?") : Localize("Are you sure that you want to delete the demo '%s'?"), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); + PopupConfirm(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir ? Localize("Delete folder") : Localize("Delete demo"), aBuf, Localize("Yes"), Localize("No"), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir ? &CMenus::PopupConfirmDeleteFolder : &CMenus::PopupConfirmDeleteDemo); return; } @@ -1375,14 +1380,14 @@ void CMenus::RenderDemoList(CUIRect MainView) if(DoButton_Menu(&s_RenameButton, Localize("Rename"), 0, &RenameRect)) { m_Popup = POPUP_RENAME_DEMO; - if(m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) + if(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) { - m_DemoRenameInput.Set(m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + m_DemoRenameInput.Set(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); } else { char aNameWithoutExt[IO_MAX_PATH_LENGTH]; - fs_split_file_extension(m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename, aNameWithoutExt, sizeof(aNameWithoutExt)); + fs_split_file_extension(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename, aNameWithoutExt, sizeof(aNameWithoutExt)); m_DemoRenameInput.Set(aNameWithoutExt); } UI()->SetActiveItem(&m_DemoRenameInput); @@ -1391,7 +1396,7 @@ void CMenus::RenderDemoList(CUIRect MainView) } #if defined(CONF_VIDEORECORDER) - if(!m_vFilteredDemos[m_DemolistSelectedIndex].m_IsDir) + if(!m_vpFilteredDemos[m_DemolistSelectedIndex]->m_IsDir) { static CButtonContainer s_RenderButton; if(DoButton_Menu(&s_RenderButton, Localize("Render"), 0, &RenderRect) || (Input()->KeyPress(KEY_R) && m_pClient->m_GameConsole.IsClosed() && !m_DemoSearchInput.IsActive())) @@ -1399,7 +1404,7 @@ void CMenus::RenderDemoList(CUIRect MainView) m_Popup = POPUP_RENDER_DEMO; m_StartPaused = false; char aNameWithoutExt[IO_MAX_PATH_LENGTH]; - fs_split_file_extension(m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename, aNameWithoutExt, sizeof(aNameWithoutExt)); + fs_split_file_extension(m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename, aNameWithoutExt, sizeof(aNameWithoutExt)); m_DemoRenderInput.Set(aNameWithoutExt); UI()->SetActiveItem(&m_DemoRenderInput); return; @@ -1412,20 +1417,13 @@ void CMenus::RenderDemoList(CUIRect MainView) // render quick search { - float SearchIconWidth = 0; - float ExcludeIconWidth = 0; - float ExcludeSearchIconMax = 0; - TextRender()->SetFontPreset(EFontPreset::ICON_FONT); TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags::TEXT_RENDER_FLAG_NO_OVERSIZE); UI()->DoLabel(&DemoSearch, FONT_ICON_MAGNIFYING_GLASS, 16.0f, TEXTALIGN_ML); - SearchIconWidth = TextRender()->TextWidth(16.0f, FONT_ICON_MAGNIFYING_GLASS, -1, -1.0f); - ExcludeIconWidth = TextRender()->TextWidth(16.0f, FONT_ICON_BAN, -1, -1.0f); - ExcludeSearchIconMax = maximum(SearchIconWidth, ExcludeIconWidth); TextRender()->SetRenderFlags(0); TextRender()->SetFontPreset(EFontPreset::DEFAULT_FONT); - DemoSearch.VSplitLeft(ExcludeSearchIconMax, 0, &DemoSearch); + DemoSearch.VSplitLeft(TextRender()->TextWidth(16.0f, FONT_ICON_MAGNIFYING_GLASS), nullptr, &DemoSearch); DemoSearch.VSplitLeft(5.0f, 0, &DemoSearch); m_DemoSearchInput.SetEmptyText(Localize("Search")); @@ -1434,15 +1432,19 @@ void CMenus::RenderDemoList(CUIRect MainView) UI()->SetActiveItem(&m_DemoSearchInput); m_DemoSearchInput.SelectAll(); } - UI()->DoClearableEditBox(&m_DemoSearchInput, &DemoSearch, 12.0f); + if(UI()->DoClearableEditBox(&m_DemoSearchInput, &DemoSearch, 12.0f)) + { + RefreshFilteredDemos(); + DemolistOnUpdate(false); + } } } void CMenus::PopupConfirmDeleteDemo() { char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); - if(Storage()->RemoveFile(aBuf, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType)) + str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); + if(Storage()->RemoveFile(aBuf, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType)) { DemolistPopulate(); DemolistOnUpdate(false); @@ -1450,7 +1452,7 @@ void CMenus::PopupConfirmDeleteDemo() else { char aError[128 + IO_MAX_PATH_LENGTH]; - str_format(aError, sizeof(aError), Localize("Unable to delete the demo '%s'"), m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + str_format(aError, sizeof(aError), Localize("Unable to delete the demo '%s'"), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); PopupMessage(Localize("Error"), aError, Localize("Ok")); } } @@ -1458,8 +1460,8 @@ void CMenus::PopupConfirmDeleteDemo() void CMenus::PopupConfirmDeleteFolder() { char aBuf[IO_MAX_PATH_LENGTH]; - str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); - if(Storage()->RemoveFolder(aBuf, m_vFilteredDemos[m_DemolistSelectedIndex].m_StorageType)) + str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); + if(Storage()->RemoveFolder(aBuf, m_vpFilteredDemos[m_DemolistSelectedIndex]->m_StorageType)) { DemolistPopulate(); DemolistOnUpdate(false); @@ -1467,7 +1469,7 @@ void CMenus::PopupConfirmDeleteFolder() else { char aError[128 + IO_MAX_PATH_LENGTH]; - str_format(aError, sizeof(aError), Localize("Unable to delete the folder '%s'. Make sure it's empty first."), m_vFilteredDemos[m_DemolistSelectedIndex].m_aFilename); + str_format(aError, sizeof(aError), Localize("Unable to delete the folder '%s'. Make sure it's empty first."), m_vpFilteredDemos[m_DemolistSelectedIndex]->m_aFilename); PopupMessage(Localize("Error"), aError, Localize("Ok")); } }