From 4d78aea41de1ec640bff8bbbed43a0d0fa6afa4d Mon Sep 17 00:00:00 2001 From: Christian Widmer Date: Thu, 8 Oct 2015 15:27:28 +0200 Subject: [PATCH 1/2] DolphinWX: Add items to visible columns only Before the columns of the gamelist were filled with content regardless of their visibility. This led to display bugs when certain columns, for example the region column, were hidden. The first problem was the InsertItemInReportView() function because it refilled all columns with content on every call to update() without checking for their visibility. While this issue would have easily been solved by adding conditionals before each column update, the maker column would have still caused problems for it autohides on resize and those do not call update(). Therefore it was necessary to move the column update logic from InsertItemInReportView() to a new one that allows for seperate modification of an item's columns. --- Source/Core/DolphinWX/GameListCtrl.cpp | 135 ++++++++++++++++++------- Source/Core/DolphinWX/GameListCtrl.h | 3 + 2 files changed, 103 insertions(+), 35 deletions(-) diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index c056d1756c..33aa82d285 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -361,52 +361,81 @@ static wxString NiceSizeFormat(u64 _size) return StrToWxStr(StringFromFormat("%s %s", value.c_str(), unit_symbols[unit])); } +// Update the column content of the item at _Index +void CGameListCtrl::UpdateItemAtColumn(long _Index, int column) +{ + GameListItem& rISOFile = *m_ISOFiles[_Index]; + + switch(column) + { + case COLUMN_PLATFORM: + { + SetItemColumnImage(_Index, COLUMN_PLATFORM, + m_PlatformImageIndex[rISOFile.GetPlatform()]); + break; + } + case COLUMN_BANNER: + { + int ImageIndex = -1; + + if (rISOFile.GetBitmap().IsOk()) + ImageIndex = m_imageListSmall->Add(rISOFile.GetBitmap()); + + SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); + break; + } + case COLUMN_TITLE: + { + wxString name = StrToWxStr(rISOFile.GetName()); + int disc_number = rISOFile.GetDiscNumber() + 1; + + if (disc_number > 1 && + name.Lower().find(wxString::Format("disc %i", disc_number)) == std::string::npos && + name.Lower().find(wxString::Format("disc%i", disc_number)) == std::string::npos) + { + name = wxString::Format(_("%s (Disc %i)"), name.c_str(), disc_number); + } + + SetItem(_Index, COLUMN_TITLE, name, -1); + break; + } + case COLUMN_MAKER: + SetItem(_Index, COLUMN_MAKER, StrToWxStr(rISOFile.GetCompany()), -1); + break; + case COLUMN_EMULATION_STATE: + SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, + m_EmuStateImageIndex[rISOFile.GetEmuState()]); + break; + case COLUMN_COUNTRY: + SetItemColumnImage(_Index, COLUMN_COUNTRY, + m_FlagImageIndex[rISOFile.GetCountry()]); + break; + case COLUMN_SIZE: + SetItem(_Index, COLUMN_SIZE, NiceSizeFormat(rISOFile.GetFileSize()), -1); + break; + case COLUMN_ID: + SetItem(_Index, COLUMN_ID, rISOFile.GetUniqueID(), -1); + break; + } +} + 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 - int ImageIndex = -1; - - GameListItem& rISOFile = *m_ISOFiles[_Index]; // Insert a first row with nothing in it, that will be used as the Index long ItemIndex = InsertItem(_Index, wxEmptyString); - // Insert the platform's image in the first (visible) column - SetItemColumnImage(_Index, COLUMN_PLATFORM, m_PlatformImageIndex[rISOFile.GetPlatform()]); - - if (rISOFile.GetBitmap().IsOk()) - ImageIndex = m_imageListSmall->Add(rISOFile.GetBitmap()); - - // Set the game's banner in the second column - SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); - - wxString name = StrToWxStr(rISOFile.GetName()); - - int disc_number = rISOFile.GetDiscNumber() + 1; - if (disc_number > 1 && name.Lower().find(wxString::Format("disc %i", disc_number)) == std::string::npos - && name.Lower().find(wxString::Format("disc%i", disc_number)) == std::string::npos) + // Iterate over all columns and fill them with content if they are visible + for (int i = 1; i < NUMBER_OF_COLUMN; i++) { - name = wxString::Format(_("%s (Disc %i)"), name.c_str(), disc_number); + if (GetColumnWidth(i) != 0) + UpdateItemAtColumn(_Index, i); } - SetItem(_Index, COLUMN_TITLE, name, -1); - SetItem(_Index, COLUMN_MAKER, StrToWxStr(rISOFile.GetCompany()), -1); - - // Emulation state - SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[rISOFile.GetEmuState()]); - - // Country - SetItemColumnImage(_Index, COLUMN_COUNTRY, m_FlagImageIndex[rISOFile.GetCountry()]); - - // File size - SetItem(_Index, COLUMN_SIZE, NiceSizeFormat(rISOFile.GetFileSize()), -1); - - // Game ID - SetItem(_Index, COLUMN_ID, rISOFile.GetUniqueID(), -1); - // Background color SetBackgroundColor(); @@ -1270,7 +1299,9 @@ void CGameListCtrl::AutomaticColumnWidth() if (SConfig::GetInstance().m_showMakerColumn) { SetColumnWidth(COLUMN_TITLE, resizable / 2); - SetColumnWidth(COLUMN_MAKER, resizable / 2); + + // If the maker column has been autohidden, we need to show it again + ShowColumn(COLUMN_MAKER, resizable / 2); } else { @@ -1280,11 +1311,45 @@ void CGameListCtrl::AutomaticColumnWidth() else { SetColumnWidth(COLUMN_TITLE, resizable); - SetColumnWidth(COLUMN_MAKER, 0); + HideColumn(COLUMN_MAKER); } } } +// Fills a previously hidden column with items. Acts +// as a SetColumnWidth if width is nonzero. +void CGameListCtrl::ShowColumn(int column, int width) +{ + // Fill the column with items if it was hidden + if (GetColumnWidth(column) == 0) + { + for (int i = 0; i < GetItemCount(); i++) + { + UpdateItemAtColumn(i, column); + } + } + SetColumnWidth(column, width); +} + +// Hide the passed column from the gamelist. +// It is not enough to set the width to zero because this leads to +// graphical glitches where the content of the hidden column is +// squeezed into the next column. Therefore we need to clear the +// items, too. +void CGameListCtrl::HideColumn(int column) +{ + // Do nothing if the column is already hidden + if (GetColumnWidth(column) == 0) + return; + + // Remove the items from the column + for (int i = 0; i < GetItemCount(); i++) + { + SetItem(i, column, "", -1); + } + SetColumnWidth(column, 0); +} + void CGameListCtrl::UnselectAll() { for (int i = 0; i < GetItemCount(); i++) diff --git a/Source/Core/DolphinWX/GameListCtrl.h b/Source/Core/DolphinWX/GameListCtrl.h index fb504d267b..0da134fb35 100644 --- a/Source/Core/DolphinWX/GameListCtrl.h +++ b/Source/Core/DolphinWX/GameListCtrl.h @@ -74,6 +74,7 @@ private: wxSize lastpos; wxEmuStateTip *toolTip; void InitBitmaps(); + void UpdateItemAtColumn(long _Index, int column); void InsertItemInReportView(long _Index); void SetBackgroundColor(); void ScanForISOs(); @@ -100,6 +101,8 @@ private: void CompressSelection(bool _compress); void AutomaticColumnWidth(); + void ShowColumn(int column, int width); + void HideColumn(int column); void UnselectAll(); static size_t m_currentItem; From 3fdaf377b0c83cd981424029e0eedb0d93435632 Mon Sep 17 00:00:00 2001 From: Christian Widmer Date: Sun, 11 Oct 2015 04:44:53 +0200 Subject: [PATCH 2/2] DolphinWX: Add a filename column --- Source/Core/Core/ConfigManager.cpp | 2 + Source/Core/Core/ConfigManager.h | 1 + Source/Core/DolphinWX/FrameTools.cpp | 5 +++ Source/Core/DolphinWX/GameListCtrl.cpp | 51 +++++++++++++++++++++++--- Source/Core/DolphinWX/GameListCtrl.h | 1 + Source/Core/DolphinWX/Globals.h | 1 + 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 271dd4cd5a..279878e60a 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -210,6 +210,7 @@ void SConfig::SaveGameListSettings(IniFile& ini) gamelist->Set("ColumnPlatform", m_showSystemColumn); gamelist->Set("ColumnBanner", m_showBannerColumn); gamelist->Set("ColumnNotes", m_showMakerColumn); + gamelist->Set("ColumnFileName", m_showFileNameColumn); gamelist->Set("ColumnID", m_showIDColumn); gamelist->Set("ColumnRegion", m_showRegionColumn); gamelist->Set("ColumnSize", m_showSizeColumn); @@ -459,6 +460,7 @@ void SConfig::LoadGameListSettings(IniFile& ini) gamelist->Get("ColumnPlatform", &m_showSystemColumn, true); gamelist->Get("ColumnBanner", &m_showBannerColumn, true); gamelist->Get("ColumnNotes", &m_showMakerColumn, true); + gamelist->Get("ColumnFileName", &m_showFileNameColumn, false); gamelist->Get("ColumnID", &m_showIDColumn, false); gamelist->Get("ColumnRegion", &m_showRegionColumn, true); gamelist->Get("ColumnSize", &m_showSizeColumn, true); diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 1714d7a880..6699c872d4 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -232,6 +232,7 @@ struct SConfig : NonCopyable bool m_showSystemColumn; bool m_showBannerColumn; bool m_showMakerColumn; + bool m_showFileNameColumn; bool m_showIDColumn; bool m_showRegionColumn; bool m_showSizeColumn; diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index d79981b56a..9598ab63e3 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -355,6 +355,8 @@ wxMenuBar* CFrame::CreateMenu() columnsMenu->Check(IDM_SHOW_BANNER, SConfig::GetInstance().m_showBannerColumn); columnsMenu->AppendCheckItem(IDM_SHOW_MAKER, _("Maker")); columnsMenu->Check(IDM_SHOW_MAKER, SConfig::GetInstance().m_showMakerColumn); + columnsMenu->AppendCheckItem(IDM_SHOW_FILENAME, _("File Name")); + columnsMenu->Check(IDM_SHOW_FILENAME, SConfig::GetInstance().m_showFileNameColumn); columnsMenu->AppendCheckItem(IDM_SHOW_ID, _("Game ID")); columnsMenu->Check(IDM_SHOW_ID, SConfig::GetInstance().m_showIDColumn); columnsMenu->AppendCheckItem(IDM_SHOW_REGION, _("Region")); @@ -2004,6 +2006,9 @@ void CFrame::OnChangeColumnsVisible(wxCommandEvent& event) case IDM_SHOW_MAKER: SConfig::GetInstance().m_showMakerColumn = !SConfig::GetInstance().m_showMakerColumn; break; + case IDM_SHOW_FILENAME: + SConfig::GetInstance().m_showFileNameColumn = !SConfig::GetInstance().m_showFileNameColumn; + break; case IDM_SHOW_ID: SConfig::GetInstance().m_showIDColumn = !SConfig::GetInstance().m_showIDColumn; break; diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index 33aa82d285..6a3754cb50 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "Common/CDUtils.h" #include "Common/CommonPaths.h" @@ -95,10 +96,19 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is return t * (iso1->GetRevision() > iso2->GetRevision() ? 1 : -1); if (iso1->GetDiscNumber() != iso2->GetDiscNumber()) return t * (iso1->GetDiscNumber() > iso2->GetDiscNumber() ? 1 : -1); + + wxString iso1_filename = wxFileNameFromPath(iso1->GetFileName()); + wxString iso2_filename = wxFileNameFromPath(iso2->GetFileName()); + + if (iso1_filename != iso2_filename) + return t * wxStricmp(iso1_filename, iso2_filename); } return strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str()) * t; case CGameListCtrl::COLUMN_MAKER: return strcasecmp(iso1->GetCompany().c_str(), iso2->GetCompany().c_str()) * t; + case CGameListCtrl::COLUMN_FILENAME: + return wxStricmp(wxFileNameFromPath(iso1->GetFileName()), + wxFileNameFromPath(iso2->GetFileName())) * t; case CGameListCtrl::COLUMN_ID: return strcasecmp(iso1->GetUniqueID().c_str(), iso2->GetUniqueID().c_str()) * t; case CGameListCtrl::COLUMN_COUNTRY: @@ -265,6 +275,7 @@ void CGameListCtrl::Update() InsertColumn(COLUMN_TITLE, _("Title")); InsertColumn(COLUMN_MAKER, _("Maker")); + InsertColumn(COLUMN_FILENAME, _("File")); InsertColumn(COLUMN_ID, _("ID")); InsertColumn(COLUMN_COUNTRY, ""); InsertColumn(COLUMN_SIZE, _("Size")); @@ -282,6 +293,7 @@ void CGameListCtrl::Update() SetColumnWidth(COLUMN_BANNER, SConfig::GetInstance().m_showBannerColumn ? 96 + platform_padding : 0); SetColumnWidth(COLUMN_TITLE, 175 + platform_padding); SetColumnWidth(COLUMN_MAKER, SConfig::GetInstance().m_showMakerColumn ? 150 + platform_padding : 0); + SetColumnWidth(COLUMN_FILENAME, SConfig::GetInstance().m_showFileNameColumn ? 100 + platform_padding : 0); SetColumnWidth(COLUMN_ID, SConfig::GetInstance().m_showIDColumn ? 75 + platform_padding : 0); SetColumnWidth(COLUMN_COUNTRY, SConfig::GetInstance().m_showRegionColumn ? 32 + platform_padding : 0); SetColumnWidth(COLUMN_EMULATION_STATE, SConfig::GetInstance().m_showStateColumn ? 50 + platform_padding : 0); @@ -402,6 +414,10 @@ void CGameListCtrl::UpdateItemAtColumn(long _Index, int column) case COLUMN_MAKER: SetItem(_Index, COLUMN_MAKER, StrToWxStr(rISOFile.GetCompany()), -1); break; + case COLUMN_FILENAME: + SetItem(_Index, COLUMN_FILENAME, + wxFileNameFromPath(rISOFile.GetFileName()), -1); + break; case COLUMN_EMULATION_STATE: SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[rISOFile.GetEmuState()]); @@ -644,7 +660,9 @@ void CGameListCtrl::ScanForISOs() void CGameListCtrl::OnColBeginDrag(wxListEvent& event) { - if (event.GetColumn() != COLUMN_TITLE && event.GetColumn() != COLUMN_MAKER) + const int column_id = event.GetColumn(); + + if (column_id != COLUMN_TITLE && column_id != COLUMN_MAKER && column_id != COLUMN_FILENAME) event.Veto(); } @@ -1294,15 +1312,28 @@ void CGameListCtrl::AutomaticColumnWidth() + GetColumnWidth(COLUMN_EMULATION_STATE)); // We hide the Maker column if the window is too small - if (resizable > 400) + // Use ShowColumn() instead of SetColumnWidth because + // the maker column may have been autohidden and the + // therefore the content needs to be restored. + if (resizable > 425) { - if (SConfig::GetInstance().m_showMakerColumn) + if (SConfig::GetInstance().m_showMakerColumn && + SConfig::GetInstance().m_showFileNameColumn) + { + SetColumnWidth(COLUMN_TITLE, resizable / 3); + ShowColumn(COLUMN_MAKER, resizable / 3); + SetColumnWidth(COLUMN_FILENAME, resizable / 3); + } + else if (SConfig::GetInstance().m_showMakerColumn) { SetColumnWidth(COLUMN_TITLE, resizable / 2); - - // If the maker column has been autohidden, we need to show it again ShowColumn(COLUMN_MAKER, resizable / 2); } + else if (SConfig::GetInstance().m_showFileNameColumn) + { + SetColumnWidth(COLUMN_TITLE, resizable / 2); + SetColumnWidth(COLUMN_FILENAME, resizable / 2); + } else { SetColumnWidth(COLUMN_TITLE, resizable); @@ -1310,7 +1341,15 @@ void CGameListCtrl::AutomaticColumnWidth() } else { - SetColumnWidth(COLUMN_TITLE, resizable); + if (SConfig::GetInstance().m_showFileNameColumn) + { + SetColumnWidth(COLUMN_TITLE, resizable / 2); + SetColumnWidth(COLUMN_FILENAME, resizable / 2); + } + else + { + SetColumnWidth(COLUMN_TITLE, resizable); + } HideColumn(COLUMN_MAKER); } } diff --git a/Source/Core/DolphinWX/GameListCtrl.h b/Source/Core/DolphinWX/GameListCtrl.h index 0da134fb35..8da314e47f 100644 --- a/Source/Core/DolphinWX/GameListCtrl.h +++ b/Source/Core/DolphinWX/GameListCtrl.h @@ -46,6 +46,7 @@ public: COLUMN_BANNER, COLUMN_TITLE, COLUMN_MAKER, + COLUMN_FILENAME, COLUMN_ID, COLUMN_COUNTRY, COLUMN_SIZE, diff --git a/Source/Core/DolphinWX/Globals.h b/Source/Core/DolphinWX/Globals.h index c784e94479..2f20597c11 100644 --- a/Source/Core/DolphinWX/Globals.h +++ b/Source/Core/DolphinWX/Globals.h @@ -179,6 +179,7 @@ enum IDM_SHOW_SYSTEM, IDM_SHOW_BANNER, IDM_SHOW_MAKER, + IDM_SHOW_FILENAME, IDM_SHOW_ID, IDM_SHOW_REGION, IDM_SHOW_SIZE,