From e3b6e6dd94c96ed4ece8e2d10169a81524c4de20 Mon Sep 17 00:00:00 2001 From: Aneesh Maganti <28660350+aminoa@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:07:39 -0500 Subject: [PATCH] DolphinQT: Add "Time Played" column to game list view Shows minutes/hours in the list view and handles column visibility. --- Source/Core/DolphinQt/GameList/GameList.cpp | 3 ++ .../Core/DolphinQt/GameList/GameListModel.cpp | 30 +++++++++++++++++++ .../Core/DolphinQt/GameList/GameListModel.h | 6 ++++ Source/Core/DolphinQt/MenuBar.cpp | 1 + 4 files changed, 40 insertions(+) diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index 782492539615..a4514a044934 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -208,6 +208,7 @@ void GameList::MakeListView() SetResizeMode(Column::FileFormat, Mode::Fixed); SetResizeMode(Column::BlockSize, Mode::Fixed); SetResizeMode(Column::Compression, Mode::Fixed); + SetResizeMode(Column::TimePlayed, Mode::Interactive); SetResizeMode(Column::Tags, Mode::Interactive); // Cells have 3 pixels of padding, so the width of these needs to be image width + 6. Banners @@ -273,6 +274,7 @@ void GameList::UpdateColumnVisibility() SetVisiblity(Column::FileFormat, Config::Get(Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT)); SetVisiblity(Column::BlockSize, Config::Get(Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE)); SetVisiblity(Column::Compression, Config::Get(Config::MAIN_GAMELIST_COLUMN_COMPRESSION)); + SetVisiblity(Column::TimePlayed, Config::Get(Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED)); SetVisiblity(Column::Tags, Config::Get(Config::MAIN_GAMELIST_COLUMN_TAGS)); } @@ -1005,6 +1007,7 @@ void GameList::OnColumnVisibilityToggled(const QString& row, bool visible) {tr("File Format"), Column::FileFormat}, {tr("Block Size"), Column::BlockSize}, {tr("Compression"), Column::Compression}, + {tr("Time Played"), Column::TimePlayed}, {tr("Tags"), Column::Tags}, }; diff --git a/Source/Core/DolphinQt/GameList/GameListModel.cpp b/Source/Core/DolphinQt/GameList/GameListModel.cpp index c70a870c2310..967fef4f465f 100644 --- a/Source/Core/DolphinQt/GameList/GameListModel.cpp +++ b/Source/Core/DolphinQt/GameList/GameListModel.cpp @@ -9,6 +9,8 @@ #include #include "Core/Config/MainSettings.h" +#include "Core/Core.h" +#include "Core/TimePlayed.h" #include "DiscIO/Enums.h" @@ -32,6 +34,8 @@ GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent) &GameTracker::RefreshAll); connect(&Settings::Instance(), &Settings::TitleDBReloadRequested, [this] { m_title_database = Core::TitleDatabase(); }); + connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, + &GameListModel::OnEmulationStateChanged); for (const QString& dir : Settings::Instance().GetPaths()) m_tracker.AddDirectory(dir); @@ -187,6 +191,22 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const return compression.isEmpty() ? tr("No Compression") : compression; } break; + case Column::TimePlayed: + if (role == Qt::DisplayRole || role == SORT_ROLE) + { + std::string game_id = game.GetGameID(); + std::chrono::milliseconds total_time = m_timer.GetTimePlayed(game_id); + std::chrono::minutes total_minutes = + std::chrono::duration_cast(total_time); + std::chrono::hours total_hours = std::chrono::duration_cast(total_time); + + // i18n: A time displayed as hours and minutes + QString formatted_time = tr("%1h %2m") + .arg(total_hours.count()) + .arg(total_minutes.count() - total_hours.count() * 60); + return formatted_time; + } + break; case Column::Tags: if (role == Qt::DisplayRole || role == SORT_ROLE) { @@ -232,6 +252,8 @@ QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int return tr("Block Size"); case Column::Compression: return tr("Compression"); + case Column::TimePlayed: + return tr("Time Played"); case Column::Tags: return tr("Tags"); default: @@ -480,3 +502,11 @@ void GameListModel::PurgeCache() { m_tracker.PurgeCache(); } + +void GameListModel::OnEmulationStateChanged(Core::State state) +{ + if (state == Core::State::Uninitialized) + { + m_timer.Reload(); + } +} diff --git a/Source/Core/DolphinQt/GameList/GameListModel.h b/Source/Core/DolphinQt/GameList/GameListModel.h index b76e0a37c275..baac5d507d4a 100644 --- a/Source/Core/DolphinQt/GameList/GameListModel.h +++ b/Source/Core/DolphinQt/GameList/GameListModel.h @@ -12,6 +12,8 @@ #include #include +#include "Core/Core.h" +#include "Core/TimePlayed.h" #include "Core/TitleDatabase.h" #include "DolphinQt/GameList/GameTracker.h" @@ -58,6 +60,7 @@ class GameListModel final : public QAbstractTableModel FileFormat, BlockSize, Compression, + TimePlayed, Tags, Count, }; @@ -87,12 +90,15 @@ class GameListModel final : public QAbstractTableModel // Index in m_games, or -1 if it isn't found int FindGameIndex(const std::string& path) const; + void OnEmulationStateChanged(Core::State state); + QStringList m_tag_list; QMap m_game_tags; GameTracker m_tracker; QList> m_games; Core::TitleDatabase m_title_database; + TimePlayed m_timer; QString m_term; float m_scale = 1.0; }; diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index fef441c0626d..24c6cc2d04a2 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -701,6 +701,7 @@ void MenuBar::AddListColumnsMenu(QMenu* view_menu) {tr("File Format"), &Config::MAIN_GAMELIST_COLUMN_FILE_FORMAT}, {tr("Block Size"), &Config::MAIN_GAMELIST_COLUMN_BLOCK_SIZE}, {tr("Compression"), &Config::MAIN_GAMELIST_COLUMN_COMPRESSION}, + {tr("Time Played"), &Config::MAIN_GAMELIST_COLUMN_TIME_PLAYED}, {tr("Tags"), &Config::MAIN_GAMELIST_COLUMN_TAGS}}; QActionGroup* column_group = new QActionGroup(this);