From 309d0e59f4697fdfc2763c7d3ee0075c514abe9b Mon Sep 17 00:00:00 2001 From: EmptyChaos Date: Sun, 29 May 2016 14:49:11 +0000 Subject: [PATCH] ISOProperties/GameListCtrl: Use Global INI Change event. ISOProperties no longer needs its hack to refresh the game list, the new INI Modified event can be used instead. --- Source/Core/DolphinWX/GameListCtrl.cpp | 139 +++++++++++++++--------- Source/Core/DolphinWX/GameListCtrl.h | 1 + Source/Core/DolphinWX/ISOFile.cpp | 46 +++++--- Source/Core/DolphinWX/ISOFile.h | 6 +- Source/Core/DolphinWX/ISOProperties.cpp | 18 +-- Source/Core/DolphinWX/ISOProperties.h | 4 +- 6 files changed, 128 insertions(+), 86 deletions(-) diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index 371d25887f..ef2ca15d18 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -167,51 +168,50 @@ CGameListCtrl::CGameListCtrl(wxWindow* parent, const wxWindowID id, const Bind(wxEVT_MENU, &CGameListCtrl::OnMultiDecompressISO, this, IDM_MULTI_DECOMPRESS_ISO); Bind(wxEVT_MENU, &CGameListCtrl::OnDeleteISO, this, IDM_DELETE_ISO); Bind(wxEVT_MENU, &CGameListCtrl::OnChangeDisc, this, IDM_LIST_CHANGE_DISC); + + wxTheApp->Bind(DOLPHIN_EVT_LOCAL_INI_CHANGED, &CGameListCtrl::OnLocalIniModified, this); } CGameListCtrl::~CGameListCtrl() { - if (m_imageListSmall) - delete m_imageListSmall; - ClearIsoFiles(); } void CGameListCtrl::InitBitmaps() { wxSize size(96, 32); - m_imageListSmall = new wxImageList(96, 32); - SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); + wxImageList* img_list = new wxImageList(96, 32); + AssignImageList(img_list, wxIMAGE_LIST_SMALL); m_FlagImageIndex.resize(DiscIO::IVolume::NUMBER_OF_COUNTRIES); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_JAPAN] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Japan", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_EUROPE] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Europe", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_USA] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_USA", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_AUSTRALIA] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Australia", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_FRANCE] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_France", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_GERMANY] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Germany", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_ITALY] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Italy", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_KOREA] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Korea", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_NETHERLANDS] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Netherlands", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_RUSSIA] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Russia", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_SPAIN] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Spain", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_TAIWAN] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Taiwan", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_WORLD] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_International", size)); - m_FlagImageIndex[DiscIO::IVolume::COUNTRY_UNKNOWN] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Flag_Unknown", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_JAPAN] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Japan", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_EUROPE] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Europe", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_USA] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_USA", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_AUSTRALIA] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Australia", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_FRANCE] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_France", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_GERMANY] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Germany", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_ITALY] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Italy", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_KOREA] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Korea", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_NETHERLANDS] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Netherlands", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_RUSSIA] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Russia", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_SPAIN] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Spain", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_TAIWAN] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Taiwan", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_WORLD] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_International", size)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_UNKNOWN] = img_list->Add(WxUtils::LoadResourceBitmap("Flag_Unknown", size)); m_PlatformImageIndex.resize(4); - m_PlatformImageIndex[DiscIO::IVolume::GAMECUBE_DISC] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Platform_Gamecube", size)); - m_PlatformImageIndex[DiscIO::IVolume::WII_DISC] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Platform_Wii", size)); - m_PlatformImageIndex[DiscIO::IVolume::WII_WAD] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Platform_Wad", size)); - m_PlatformImageIndex[DiscIO::IVolume::ELF_DOL] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("Platform_File", size)); + m_PlatformImageIndex[DiscIO::IVolume::GAMECUBE_DISC] = img_list->Add(WxUtils::LoadResourceBitmap("Platform_Gamecube", size)); + m_PlatformImageIndex[DiscIO::IVolume::WII_DISC] = img_list->Add(WxUtils::LoadResourceBitmap("Platform_Wii", size)); + m_PlatformImageIndex[DiscIO::IVolume::WII_WAD] = img_list->Add(WxUtils::LoadResourceBitmap("Platform_Wad", size)); + m_PlatformImageIndex[DiscIO::IVolume::ELF_DOL] = img_list->Add(WxUtils::LoadResourceBitmap("Platform_File", size)); m_EmuStateImageIndex.resize(6); - m_EmuStateImageIndex[0] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating0", size)); - m_EmuStateImageIndex[1] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating1", size)); - m_EmuStateImageIndex[2] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating2", size)); - m_EmuStateImageIndex[3] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating3", size)); - m_EmuStateImageIndex[4] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating4", size)); - m_EmuStateImageIndex[5] = m_imageListSmall->Add(WxUtils::LoadResourceBitmap("rating5", size)); + m_EmuStateImageIndex[0] = img_list->Add(WxUtils::LoadResourceBitmap("rating0", size)); + m_EmuStateImageIndex[1] = img_list->Add(WxUtils::LoadResourceBitmap("rating1", size)); + m_EmuStateImageIndex[2] = img_list->Add(WxUtils::LoadResourceBitmap("rating2", size)); + m_EmuStateImageIndex[3] = img_list->Add(WxUtils::LoadResourceBitmap("rating3", size)); + m_EmuStateImageIndex[4] = img_list->Add(WxUtils::LoadResourceBitmap("rating4", size)); + m_EmuStateImageIndex[5] = img_list->Add(WxUtils::LoadResourceBitmap("rating5", size)); } void CGameListCtrl::BrowseForDirectory() @@ -247,16 +247,9 @@ void CGameListCtrl::Update() if (Core::GetState() != Core::CORE_UNINITIALIZED) return; - if (m_imageListSmall) - { - delete m_imageListSmall; - m_imageListSmall = nullptr; - } - - Hide(); - ScanForISOs(); + Freeze(); ClearAll(); if (m_ISOFiles.size() != 0) @@ -320,6 +313,12 @@ void CGameListCtrl::Update() } else { + // Remove existing image list and replace it with the smallest possible one. + // The list needs an image list because it reserves screen pixels for the + // image even if we aren't going to use one. It uses the dimensions of the + // last non-null list so assigning nullptr doesn't work. + AssignImageList(new wxImageList(1, 1), wxIMAGE_LIST_SMALL); + wxString errorString; // We just check for one hide setting to be enabled, as we may only // have GC games for example, and hide them, so we should show the @@ -339,7 +338,9 @@ void CGameListCtrl::Update() } if (GetSelectedISO() == nullptr) main_frame->UpdateGUI(); - Show(); + // Thaw before calling AutomaticColumnWidth so that GetClientSize will + // correctly account for the width of scrollbars if they appear. + Thaw(); AutomaticColumnWidth(); ScrollLines(scrollPos); @@ -367,7 +368,7 @@ static wxString NiceSizeFormat(u64 size) // Update the column content of the item at _Index void CGameListCtrl::UpdateItemAtColumn(long _Index, int column) { - GameListItem& rISOFile = *m_ISOFiles[_Index]; + GameListItem& rISOFile = *m_ISOFiles[GetItemData(_Index)]; switch(column) { @@ -382,7 +383,7 @@ void CGameListCtrl::UpdateItemAtColumn(long _Index, int column) int ImageIndex = -1; if (rISOFile.GetBitmap().IsOk()) - ImageIndex = m_imageListSmall->Add(rISOFile.GetBitmap()); + ImageIndex = GetImageList(wxIMAGE_LIST_SMALL)->Add(rISOFile.GetBitmap()); SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); break; @@ -426,28 +427,32 @@ void CGameListCtrl::UpdateItemAtColumn(long _Index, int column) } } -void CGameListCtrl::InsertItemInReportView(long _Index) +void CGameListCtrl::InsertItemInReportView(long index) { // When using wxListCtrl, there is no hope of per-column text colors. // But for reference, here are the old colors that were used: (BGR) // title: 0xFF0000 // company: 0x007030 - // Insert a first row with nothing in it, that will be used as the Index - long ItemIndex = InsertItem(_Index, wxEmptyString); + // Insert a first column with nothing in it, that will be used as the Index + long item_index; + { + wxListItem li; + li.SetId(index); + li.SetData(index); + li.SetMask(wxLIST_MASK_DATA); + item_index = InsertItem(li); + } // Iterate over all columns and fill them with content if they are visible for (int i = 1; i < NUMBER_OF_COLUMN; i++) { if (GetColumnWidth(i) != 0) - UpdateItemAtColumn(_Index, i); + UpdateItemAtColumn(item_index, i); } // Background color SetBackgroundColor(); - - // Item data - SetItemData(_Index, ItemIndex); } static wxColour blend50(const wxColour& c1, const wxColour& c2) @@ -653,6 +658,41 @@ void CGameListCtrl::ScanForISOs() std::sort(m_ISOFiles.begin(), m_ISOFiles.end()); } +void CGameListCtrl::OnLocalIniModified(wxCommandEvent& ev) +{ + ev.Skip(); + std::string game_id = WxStrToStr(ev.GetString()); + // NOTE: The same game may occur multiple times if there are multiple + // physical copies in the search paths. + for (std::size_t i = 0; i < m_ISOFiles.size(); ++i) + { + if (m_ISOFiles[i]->GetUniqueID() != game_id) + continue; + m_ISOFiles[i]->ReloadINI(); + + // The indexes in m_ISOFiles and the list do not line up. + // We need to find the corresponding item in the list (if it exists) + long item_id = 0; + for (; item_id < GetItemCount(); ++item_id) + { + if (i == static_cast(GetItemData(item_id))) + break; + } + // If the item is not currently being displayed then we're done. + if (item_id == GetItemCount()) + continue; + + // Update all the columns + for (int j = 1; j < NUMBER_OF_COLUMN; ++j) + { + // NOTE: Banner is not modified by the INI and updating it will + // duplicate it in memory which is not wanted. + if (j != COLUMN_BANNER && GetColumnWidth(j) != 0) + UpdateItemAtColumn(item_id, j); + } + } +} + void CGameListCtrl::OnColBeginDrag(wxListEvent& event) { const int column_id = event.GetColumn(); @@ -1310,19 +1350,19 @@ void CGameListCtrl::OnChangeDisc(wxCommandEvent& WXUNUSED(event)) void CGameListCtrl::OnSize(wxSizeEvent& event) { + event.Skip(); if (lastpos == event.GetSize()) return; lastpos = event.GetSize(); AutomaticColumnWidth(); - - event.Skip(); } void CGameListCtrl::AutomaticColumnWidth() { wxRect rc(GetClientRect()); + Freeze(); if (GetColumnCount() == 1) { SetColumnWidth(0, rc.GetWidth()); @@ -1359,6 +1399,7 @@ void CGameListCtrl::AutomaticColumnWidth() SetColumnWidth(COLUMN_TITLE, resizable); } } + Thaw(); } void CGameListCtrl::UnselectAll() diff --git a/Source/Core/DolphinWX/GameListCtrl.h b/Source/Core/DolphinWX/GameListCtrl.h index 328b69747c..6914d23fb6 100644 --- a/Source/Core/DolphinWX/GameListCtrl.h +++ b/Source/Core/DolphinWX/GameListCtrl.h @@ -102,6 +102,7 @@ private: void OnMultiCompressISO(wxCommandEvent& event); void OnMultiDecompressISO(wxCommandEvent& event); void OnChangeDisc(wxCommandEvent& event); + void OnLocalIniModified(wxCommandEvent& event); void CompressSelection(bool _compress); void AutomaticColumnWidth(); diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index 3312394dda..886837af52 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -124,27 +124,19 @@ GameListItem::GameListItem(const std::string& _rFileName, const std::unordered_m if (IsValid()) { - IniFile ini = SConfig::LoadGameIni(m_UniqueID, m_Revision); - ini.GetIfExists("EmuState", "EmulationStateId", &m_emu_state); - ini.GetIfExists("EmuState", "EmulationIssues", &m_issues); - m_has_custom_name = ini.GetIfExists("EmuState", "Title", &m_custom_name); + std::string game_id = m_UniqueID; - if (!m_has_custom_name) + // Ignore publisher ID for WAD files + if (m_Platform == DiscIO::IVolume::WII_WAD && game_id.size() > 4) + game_id.erase(4); + + auto it = custom_titles.find(game_id); + if (it != custom_titles.end()) { - std::string game_id = m_UniqueID; - - // Ignore publisher ID for WAD files - if (m_Platform == DiscIO::IVolume::WII_WAD && game_id.size() > 4) - game_id.erase(4); - - auto end = custom_titles.end(); - auto it = custom_titles.find(game_id); - if (it != end) - { - m_custom_name = it->second; - m_has_custom_name = true; - } + m_custom_name_titles_txt = it->second; } + + ReloadINI(); } if (!IsValid() && IsElfOrDol()) @@ -183,6 +175,24 @@ GameListItem::~GameListItem() { } +void GameListItem::ReloadINI() +{ + if (!IsValid()) + return; + + IniFile ini = SConfig::LoadGameIni(m_UniqueID, m_Revision); + ini.GetIfExists("EmuState", "EmulationStateId", &m_emu_state, 0); + ini.GetIfExists("EmuState", "EmulationIssues", &m_issues, std::string()); + + m_custom_name.clear(); + m_has_custom_name = ini.GetIfExists("EmuState", "Title", &m_custom_name); + if (!m_has_custom_name && !m_custom_name_titles_txt.empty()) + { + m_custom_name = m_custom_name_titles_txt; + m_has_custom_name = true; + } +} + bool GameListItem::LoadFromCache() { return CChunkFileReader::Load(CreateCacheFilename(), CACHE_REVISION, *this); diff --git a/Source/Core/DolphinWX/ISOFile.h b/Source/Core/DolphinWX/ISOFile.h index 448139fd43..a814820ec0 100644 --- a/Source/Core/DolphinWX/ISOFile.h +++ b/Source/Core/DolphinWX/ISOFile.h @@ -25,6 +25,9 @@ public: GameListItem(const std::string& _rFileName, const std::unordered_map& custom_titles); ~GameListItem(); + // Reload settings after INI changes + void ReloadINI(); + bool IsValid() const {return m_Valid;} const std::string& GetFileName() const {return m_FileName;} std::string GetName(DiscIO::IVolume::ELanguage language) const; @@ -86,7 +89,8 @@ private: int m_ImageWidth, m_ImageHeight; u8 m_disc_number; - std::string m_custom_name; + std::string m_custom_name_titles_txt; // Custom title from titles.txt + std::string m_custom_name; // Custom title from INI or titles.txt bool m_has_custom_name; bool LoadFromCache(); diff --git a/Source/Core/DolphinWX/ISOProperties.cpp b/Source/Core/DolphinWX/ISOProperties.cpp index 9071f70bd3..39b4e2c041 100644 --- a/Source/Core/DolphinWX/ISOProperties.cpp +++ b/Source/Core/DolphinWX/ISOProperties.cpp @@ -63,7 +63,6 @@ #include "DiscIO/Volume.h" #include "DiscIO/VolumeCreator.h" #include "DolphinWX/ARCodeAddEdit.h" -#include "DolphinWX/GameListCtrl.h" #include "DolphinWX/Globals.h" #include "DolphinWX/ISOFile.h" #include "DolphinWX/ISOProperties.h" @@ -77,8 +76,7 @@ BEGIN_EVENT_TABLE(CISOProperties, wxDialog) EVT_BUTTON(ID_EDITCONFIG, CISOProperties::OnEditConfig) EVT_BUTTON(ID_MD5SUMCOMPUTE, CISOProperties::OnComputeMD5Sum) EVT_BUTTON(ID_SHOWDEFAULTCONFIG, CISOProperties::OnShowDefaultConfig) - EVT_CHOICE(ID_EMUSTATE, CISOProperties::SetRefresh) - EVT_CHOICE(ID_EMU_ISSUES, CISOProperties::SetRefresh) + EVT_CHOICE(ID_EMUSTATE, CISOProperties::OnEmustateChanged) EVT_LISTBOX(ID_PATCHES_LIST, CISOProperties::ListSelectionChanged) EVT_BUTTON(ID_EDITPATCH, CISOProperties::PatchButtonClicked) EVT_BUTTON(ID_ADDPATCH, CISOProperties::PatchButtonClicked) @@ -114,8 +112,6 @@ CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* par GameIniLocal = SConfig::LoadLocalGameIni(game_id, m_open_iso->GetRevision()); // Setup GUI - bRefreshList = false; - CreateGUIControls(); LoadGameConfig(); @@ -647,8 +643,6 @@ void CISOProperties::OnClose(wxCloseEvent& WXUNUSED (event)) { if (!SaveGameConfig()) WxUtils::ShowErrorDialog(wxString::Format(_("Could not save %s."), GameIniFileLocal.c_str())); - if (bRefreshList) - ((CGameListCtrl*)GetParent())->Update(); Destroy(); } @@ -991,12 +985,9 @@ void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event) } } -void CISOProperties::SetRefresh(wxCommandEvent& event) +void CISOProperties::OnEmustateChanged(wxCommandEvent& event) { - bRefreshList = true; - - if (event.GetId() == ID_EMUSTATE) - EmuIssues->Enable(event.GetSelection() != 0); + EmuIssues->Enable(event.GetSelection() != 0); } void CISOProperties::SetCheckboxValueFromGameini(const char* section, const char* key, wxCheckBox* checkbox) @@ -1211,9 +1202,6 @@ void CISOProperties::LaunchExternalEditor(const std::string& filename, bool wait WxUtils::ShowErrorDialog(_("wxExecute returned -1 on application run!")); return; } - - if (wait_until_closed) - bRefreshList = true; // Just in case #endif } diff --git a/Source/Core/DolphinWX/ISOProperties.h b/Source/Core/DolphinWX/ISOProperties.h index 4743d7299b..a702d8e256 100644 --- a/Source/Core/DolphinWX/ISOProperties.h +++ b/Source/Core/DolphinWX/ISOProperties.h @@ -209,7 +209,7 @@ private: void OnExtractDir(wxCommandEvent& event); void OnExtractDataFromHeader(wxCommandEvent& event); void CheckPartitionIntegrity(wxCommandEvent& event); - void SetRefresh(wxCommandEvent& event); + void OnEmustateChanged(wxCommandEvent& event); void OnChangeBannerLang(wxCommandEvent& event); const GameListItem OpenGameListItem; @@ -233,8 +233,6 @@ private: std::set DefaultPatches; std::set DefaultCheats; - bool bRefreshList; - void LoadGameConfig(); bool SaveGameConfig(); void OnLocalIniModified(wxCommandEvent& ev);