Qt: Prefer currently selected game when pressing the play button

Also rename Start to Play
This commit is contained in:
Megamouse 2020-03-07 02:04:11 +01:00
parent 7dd36ff829
commit 426643c44d
5 changed files with 129 additions and 30 deletions

View file

@ -15,6 +15,7 @@ private:
if (!indexAt(event->pos()).isValid() || itemAt(event->pos())->data(Qt::UserRole) < 0) if (!indexAt(event->pos()).isValid() || itemAt(event->pos())->data(Qt::UserRole) < 0)
{ {
clearSelection(); clearSelection();
setCurrentItem(nullptr); // Needed for currentItemChanged
} }
QTableWidget::mousePressEvent(event); QTableWidget::mousePressEvent(event);
} }

View file

@ -126,6 +126,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
// Events // Events
connect(m_gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); 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, &QTableWidget::itemDoubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked); connect(m_gameList->horizontalHeader(), &QHeaderView::sectionClicked, this, &game_list_frame::OnColClicked);
@ -136,8 +137,9 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
configure->exec(m_gameList->horizontalHeader()->viewport()->mapToGlobal(pos)); 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::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]() 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(); const int scroll_position = m_xgrid->verticalScrollBar()->value();
PopulateGameGrid(games_per_row, m_Icon_Size, m_Icon_Color); 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::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->addWidget(m_xgrid);
m_Central_Widget->setCurrentWidget(m_xgrid); m_Central_Widget->setCurrentWidget(m_xgrid);
m_xgrid->verticalScrollBar()->setValue(scroll_position); 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) void game_list_frame::doubleClickedSlot(QTableWidgetItem *item)
{ {
if (item == nullptr) if (!item)
{ {
return; return;
} }
game_info game; const game_info game = GetGameInfoByMode(item);
if (m_isListLayout)
{
game = GetGameInfoFromItem(m_gameList->item(item->row(), gui::column_icon));
}
else
{
game = GetGameInfoFromItem(item);
}
if (!game) if (!game)
{ {
@ -900,6 +894,18 @@ void game_list_frame::doubleClickedSlot(QTableWidgetItem *item)
Q_EMIT RequestBoot(game); 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) void game_list_frame::ShowContextMenu(const QPoint &pos)
{ {
QPoint globalPos; QPoint globalPos;
@ -2257,9 +2263,24 @@ std::string game_list_frame::GetStringFromU32(const u32& key, const std::map<u32
return sstr(string.join(", ")); return sstr(string.join(", "));
} }
game_info game_list_frame::GetGameInfoFromItem(QTableWidgetItem* item) game_info game_list_frame::GetGameInfoByMode(const QTableWidgetItem* item)
{ {
if (item == nullptr) if (!item)
{
return nullptr;
}
if (m_isListLayout)
{
return GetGameInfoFromItem(m_gameList->item(item->row(), gui::column_icon));
}
return GetGameInfoFromItem(item);
}
game_info game_list_frame::GetGameInfoFromItem(const QTableWidgetItem* item)
{
if (!item)
{ {
return nullptr; return nullptr;
} }

View file

@ -83,8 +83,10 @@ private Q_SLOTS:
void OnColClicked(int col); void OnColClicked(int col);
void ShowContextMenu(const QPoint &pos); void ShowContextMenu(const QPoint &pos);
void doubleClickedSlot(QTableWidgetItem *item); void doubleClickedSlot(QTableWidgetItem *item);
void itemSelectedSlot(QTableWidgetItem* current, QTableWidgetItem* previous);
Q_SIGNALS: Q_SIGNALS:
void GameListFrameClosed(); void GameListFrameClosed();
void NotifyGameSelection(const game_info& game);
void RequestBoot(const game_info& game, bool force_global_config = false); void RequestBoot(const game_info& game, bool force_global_config = false);
void RequestIconSizeChange(const int& val); void RequestIconSizeChange(const int& val);
void NotifyEmuSettingsChange(); void NotifyEmuSettingsChange();
@ -117,7 +119,8 @@ private:
std::string CurrentSelectionIconPath(); std::string CurrentSelectionIconPath();
std::string GetStringFromU32(const u32& key, const std::map<u32, QString>& map, bool combined = false); std::string GetStringFromU32(const u32& key, const std::map<u32, QString>& 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. // Which widget we are displaying depends on if we are in grid or list mode.
QMainWindow* m_Game_Dock; QMainWindow* m_Game_Dock;

View file

@ -128,12 +128,12 @@ void main_window::Init()
// enable play options if a recent game exists // enable play options if a recent game exists
const bool enable_play_last = !m_recentGameActs.isEmpty() && m_recentGameActs.first(); 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) if (enable_play_last)
{ {
ui->sysPauseAct->setEnabled(true); 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->sysPauseAct->setIcon(m_icon_play);
ui->toolbar_start->setToolTip(start_toolip); ui->toolbar_start->setToolTip(start_toolip);
ui->toolbar_start->setEnabled(true); ui->toolbar_start->setEnabled(true);
@ -231,6 +231,12 @@ void main_window::OnPlayOrPause()
{ {
Emu.Pause(); Emu.Pause();
} }
else if (Emu.IsStopped())
{
if (m_selected_game)
{
Boot(m_selected_game->info.path, m_selected_game->info.serial, false, false, false);
}
else if (const auto path = Emu.GetBoot(); !path.empty()) else if (const auto path = Emu.GetBoot(); !path.empty())
{ {
if (const auto error = Emu.Load(); error != game_boot_result::no_errors) if (const auto error = Emu.Load(); error != game_boot_result::no_errors)
@ -239,10 +245,11 @@ void main_window::OnPlayOrPause()
show_boot_error(error); show_boot_error(error);
} }
} }
else if (Emu.IsStopped() && !m_recentGameActs.isEmpty()) else if (!m_recentGameActs.isEmpty())
{ {
BootRecentAction(m_recentGameActs.first()); BootRecentAction(m_recentGameActs.first());
} }
}
} }
void main_window::show_boot_error(game_boot_result status) void main_window::show_boot_error(game_boot_result status)
@ -974,13 +981,13 @@ void main_window::OnEmuPause()
void main_window::OnEmuStop() void main_window::OnEmuStop()
{ {
const QString title = GetCurrentTitle(); 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); const QString restart_tooltip = tr("Restart %0").arg(title);
m_debuggerFrame->EnableButtons(false); m_debuggerFrame->EnableButtons(false);
m_debuggerFrame->ClearBreakpoints(); 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); ui->sysPauseAct->setIcon(m_icon_play);
#ifdef _WIN32 #ifdef _WIN32
m_thumb_playPause->setToolTip(play_tooltip); m_thumb_playPause->setToolTip(play_tooltip);
@ -1019,14 +1026,14 @@ void main_window::OnEmuStop()
void main_window::OnEmuReady() void main_window::OnEmuReady()
{ {
const QString title = GetCurrentTitle(); 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); m_debuggerFrame->EnableButtons(true);
#ifdef _WIN32 #ifdef _WIN32
m_thumb_playPause->setToolTip(play_tooltip); m_thumb_playPause->setToolTip(play_tooltip);
m_thumb_playPause->setIcon(m_icon_thumb_play); m_thumb_playPause->setIcon(m_icon_thumb_play);
#endif #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->sysPauseAct->setIcon(m_icon_play);
ui->toolbar_start->setIcon(m_icon_play); ui->toolbar_start->setIcon(m_icon_play);
ui->toolbar_start->setText(tr("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) 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); Boot(game->info.path, game->info.serial, false, false, force_global_config);

View file

@ -21,6 +21,8 @@ class gui_settings;
class emu_settings; class emu_settings;
class persistent_settings; class persistent_settings;
struct gui_game_info;
enum class game_boot_result : u32; enum class game_boot_result : u32;
namespace Ui namespace Ui
@ -146,6 +148,8 @@ private:
q_pair_list m_rg_entries; q_pair_list m_rg_entries;
QList<QAction*> m_recentGameActs; QList<QAction*> m_recentGameActs;
std::shared_ptr<gui_game_info> m_selected_game;
QActionGroup* m_iconSizeActGroup = nullptr; QActionGroup* m_iconSizeActGroup = nullptr;
QActionGroup* m_listModeActGroup = nullptr; QActionGroup* m_listModeActGroup = nullptr;
QActionGroup* m_categoryVisibleActGroup = nullptr; QActionGroup* m_categoryVisibleActGroup = nullptr;