diff --git a/rpcs3/rpcs3qt/game_list.h b/rpcs3/rpcs3qt/game_list.h index ca739b7455..82bf11dca8 100644 --- a/rpcs3/rpcs3qt/game_list.h +++ b/rpcs3/rpcs3qt/game_list.h @@ -15,6 +15,7 @@ private: if (!indexAt(event->pos()).isValid() || itemAt(event->pos())->data(Qt::UserRole) < 0) { clearSelection(); + setCurrentItem(nullptr); // Needed for currentItemChanged } QTableWidget::mousePressEvent(event); } diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 79f1582b6a..f450ed6650 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -126,6 +126,7 @@ game_list_frame::game_list_frame(std::shared_ptr guiSettings, std: // Events connect(m_gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); + connect(m_gameList, &QTableWidget::currentItemChanged, this, &game_list_frame::itemSelectedSlot); connect(m_gameList, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked); @@ -136,8 +137,9 @@ game_list_frame::game_list_frame(std::shared_ptr guiSettings, std: configure->exec(m_gameList->horizontalHeader()->viewport()->mapToGlobal(pos)); }); - connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); + connect(m_xgrid, &QTableWidget::currentItemChanged, this, &game_list_frame::itemSelectedSlot); + connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_game_compat.get(), &game_compatibility::DownloadStarted, [this]() { @@ -812,8 +814,9 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter) const int scroll_position = m_xgrid->verticalScrollBar()->value(); PopulateGameGrid(games_per_row, m_Icon_Size, m_Icon_Color); - connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); + connect(m_xgrid, &QTableWidget::currentItemChanged, this, &game_list_frame::itemSelectedSlot); + connect(m_xgrid, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot); m_Central_Widget->addWidget(m_xgrid); m_Central_Widget->setCurrentWidget(m_xgrid); m_xgrid->verticalScrollBar()->setValue(scroll_position); @@ -875,21 +878,12 @@ static void open_dir(const std::string& spath) void game_list_frame::doubleClickedSlot(QTableWidgetItem *item) { - if (item == nullptr) + if (!item) { return; } - game_info game; - - if (m_isListLayout) - { - game = GetGameInfoFromItem(m_gameList->item(item->row(), gui::column_icon)); - } - else - { - game = GetGameInfoFromItem(item); - } + const game_info game = GetGameInfoByMode(item); if (!game) { @@ -900,6 +894,18 @@ void game_list_frame::doubleClickedSlot(QTableWidgetItem *item) Q_EMIT RequestBoot(game); } +void game_list_frame::itemSelectedSlot(QTableWidgetItem* current, QTableWidgetItem* /*previous*/) +{ + if (current) + { + Q_EMIT NotifyGameSelection(GetGameInfoByMode(current)); + } + else + { + Q_EMIT NotifyGameSelection(nullptr); + } +} + void game_list_frame::ShowContextMenu(const QPoint &pos) { QPoint globalPos; @@ -2257,9 +2263,24 @@ std::string game_list_frame::GetStringFromU32(const u32& key, const std::mapitem(item->row(), gui::column_icon)); + } + + return GetGameInfoFromItem(item); +} + +game_info game_list_frame::GetGameInfoFromItem(const QTableWidgetItem* item) +{ + if (!item) { return nullptr; } diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index 1eb34f91a2..6a49b6a72b 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -83,8 +83,10 @@ private Q_SLOTS: void OnColClicked(int col); void ShowContextMenu(const QPoint &pos); void doubleClickedSlot(QTableWidgetItem *item); + void itemSelectedSlot(QTableWidgetItem* current, QTableWidgetItem* previous); Q_SIGNALS: void GameListFrameClosed(); + void NotifyGameSelection(const game_info& game); void RequestBoot(const game_info& game, bool force_global_config = false); void RequestIconSizeChange(const int& val); void NotifyEmuSettingsChange(); @@ -117,7 +119,8 @@ private: std::string CurrentSelectionIconPath(); std::string GetStringFromU32(const u32& key, const std::map& map, bool combined = false); - game_info GetGameInfoFromItem(QTableWidgetItem* item); + game_info GetGameInfoByMode(const QTableWidgetItem* item); + game_info GetGameInfoFromItem(const QTableWidgetItem* item); // Which widget we are displaying depends on if we are in grid or list mode. QMainWindow* m_Game_Dock; diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index fa5cf4e61e..4cb12e8a2a 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -128,12 +128,12 @@ void main_window::Init() // enable play options if a recent game exists const bool enable_play_last = !m_recentGameActs.isEmpty() && m_recentGameActs.first(); - const QString start_toolip = enable_play_last ? tr("Start %0").arg(m_recentGameActs.first()->text()) : tr("Start emulation"); + const QString start_toolip = enable_play_last ? tr("Play %0").arg(m_recentGameActs.first()->text()) : tr("Play"); if (enable_play_last) { ui->sysPauseAct->setEnabled(true); - ui->sysPauseAct->setText(tr("&Start last played game\tCtrl+E")); + ui->sysPauseAct->setText(tr("&Play last played game\tCtrl+E")); ui->sysPauseAct->setIcon(m_icon_play); ui->toolbar_start->setToolTip(start_toolip); ui->toolbar_start->setEnabled(true); @@ -231,17 +231,24 @@ void main_window::OnPlayOrPause() { Emu.Pause(); } - else if (const auto path = Emu.GetBoot(); !path.empty()) + else if (Emu.IsStopped()) { - if (const auto error = Emu.Load(); error != game_boot_result::no_errors) + if (m_selected_game) { - gui_log.error("Boot failed: reason: %s, path: %s", error, path); - show_boot_error(error); + Boot(m_selected_game->info.path, m_selected_game->info.serial, false, false, false); + } + else if (const auto path = Emu.GetBoot(); !path.empty()) + { + if (const auto error = Emu.Load(); error != game_boot_result::no_errors) + { + gui_log.error("Boot failed: reason: %s, path: %s", error, path); + show_boot_error(error); + } + } + else if (!m_recentGameActs.isEmpty()) + { + BootRecentAction(m_recentGameActs.first()); } - } - else if (Emu.IsStopped() && !m_recentGameActs.isEmpty()) - { - BootRecentAction(m_recentGameActs.first()); } } @@ -974,13 +981,13 @@ void main_window::OnEmuPause() void main_window::OnEmuStop() { const QString title = GetCurrentTitle(); - const QString play_tooltip = Emu.IsReady() ? tr("Start %0").arg(title) : tr("Resume %0").arg(title); + const QString play_tooltip = Emu.IsReady() ? tr("Play %0").arg(title) : tr("Resume %0").arg(title); const QString restart_tooltip = tr("Restart %0").arg(title); m_debuggerFrame->EnableButtons(false); m_debuggerFrame->ClearBreakpoints(); - ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Start\tCtrl+E") : tr("&Resume\tCtrl+E")); + ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Play\tCtrl+E") : tr("&Resume\tCtrl+E")); ui->sysPauseAct->setIcon(m_icon_play); #ifdef _WIN32 m_thumb_playPause->setToolTip(play_tooltip); @@ -1019,14 +1026,14 @@ void main_window::OnEmuStop() void main_window::OnEmuReady() { const QString title = GetCurrentTitle(); - const QString play_tooltip = Emu.IsReady() ? tr("Start %0").arg(title) : tr("Resume %0").arg(title); + const QString play_tooltip = Emu.IsReady() ? tr("Play %0").arg(title) : tr("Resume %0").arg(title); m_debuggerFrame->EnableButtons(true); #ifdef _WIN32 m_thumb_playPause->setToolTip(play_tooltip); m_thumb_playPause->setIcon(m_icon_thumb_play); #endif - ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Start\tCtrl+E") : tr("&Resume\tCtrl+E")); + ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Play\tCtrl+E") : tr("&Resume\tCtrl+E")); ui->sysPauseAct->setIcon(m_icon_play); ui->toolbar_start->setIcon(m_icon_play); ui->toolbar_start->setText(tr("Play")); @@ -1754,6 +1761,69 @@ void main_window::CreateDockWindows() } }); + connect(m_gameListFrame, &game_list_frame::NotifyGameSelection, [this](const game_info& game) + { + // Only change the button logic while the emulator is stopped. + if (Emu.IsStopped()) + { + QString tooltip; + + if (game) // A game was selected + { + const std::string title_and_title_id = game->info.name + " [" + game->info.serial + "]"; + + if (title_and_title_id == Emu.GetTitleAndTitleID()) // This should usually not cause trouble, but feel free to improve. + { + tooltip = tr("Restart %0").arg(qstr(title_and_title_id)); + + ui->toolbar_start->setIcon(m_icon_restart); + ui->toolbar_start->setText(tr("Restart")); + } + else + { + tooltip = tr("Play %0").arg(qstr(title_and_title_id)); + + ui->toolbar_start->setIcon(m_icon_play); + ui->toolbar_start->setText(tr("Play")); + } + } + else if (m_selected_game) // No game was selected. Check if a game was selected before. + { + if (Emu.IsReady()) // Prefer games that are about to be booted ("Automatically start games" was set to off) + { + tooltip = tr("Play %0").arg(GetCurrentTitle()); + + ui->toolbar_start->setIcon(m_icon_play); + } + else if (const auto path = Emu.GetBoot(); !path.empty()) // Restartable games + { + tooltip = tr("Restart %0").arg(GetCurrentTitle()); + + ui->toolbar_start->setIcon(m_icon_restart); + ui->toolbar_start->setText(tr("Restart")); + } + else if (!m_recentGameActs.isEmpty()) // Get last played game + { + tooltip = tr("Play %0").arg(m_recentGameActs.first()->text()); + } + else + { + ui->toolbar_start->setEnabled(false); + } + } + + if (!tooltip.isEmpty()) + { + ui->toolbar_start->setToolTip(tooltip); +#ifdef _WIN32 + m_thumb_playPause->setToolTip(tooltip); +#endif + } + } + + m_selected_game = game; + }); + connect(m_gameListFrame, &game_list_frame::RequestBoot, [this](const game_info& game, bool force_global_config) { Boot(game->info.path, game->info.serial, false, false, force_global_config); diff --git a/rpcs3/rpcs3qt/main_window.h b/rpcs3/rpcs3qt/main_window.h index eacfe9ebce..29149752b6 100644 --- a/rpcs3/rpcs3qt/main_window.h +++ b/rpcs3/rpcs3qt/main_window.h @@ -21,6 +21,8 @@ class gui_settings; class emu_settings; class persistent_settings; +struct gui_game_info; + enum class game_boot_result : u32; namespace Ui @@ -146,6 +148,8 @@ private: q_pair_list m_rg_entries; QList m_recentGameActs; + std::shared_ptr m_selected_game; + QActionGroup* m_iconSizeActGroup = nullptr; QActionGroup* m_listModeActGroup = nullptr; QActionGroup* m_categoryVisibleActGroup = nullptr;