Qt: Improve shortcuts

- CTRL/+, CTRL/- no longer show in menu for zooming, but still activate.
- CTRL+O will open a new disc/game from file.
- F5 will refresh the game list (i.e. scan for new games).
- F3/CTRL+F will send focus to the game list search box.
- Pressing Enter in the search box will send focus to the first game
  list row.
- ALT+ENTER in the game list will open Game Properties.
This commit is contained in:
Stenzek 2024-12-01 13:32:24 +10:00
parent 145ad2db27
commit 67041d217b
No known key found for this signature in database
7 changed files with 95 additions and 33 deletions

View File

@ -138,8 +138,14 @@ bool AutoUpdaterDialog::warnAboutUnofficialBuild()
#if !__has_include("scmversion/tag.h") && !defined(_DEBUG)
constexpr const char* CONFIG_SECTION = "UI";
constexpr const char* CONFIG_KEY = "UnofficialBuildWarningConfirmed";
if (Host::GetBaseBoolSettingValue(CONFIG_SECTION, CONFIG_KEY, false))
if (
#ifndef _WIN32
!StringUtil::StartsWithNoCase(EmuFolders::AppRoot, "/usr") &&
#endif
Host::GetBaseBoolSettingValue(CONFIG_SECTION, CONFIG_KEY, false))
{
return true;
}
constexpr int DELAY_SECONDS = 5;
@ -155,6 +161,8 @@ bool AutoUpdaterDialog::warnAboutUnofficialBuild()
mbox.setIcon(QMessageBox::Warning);
mbox.setWindowTitle(QStringLiteral("Unofficial Build Warning"));
mbox.setWindowIcon(QtHost::GetAppIcon());
mbox.setWindowFlag(Qt::CustomizeWindowHint, true);
mbox.setWindowFlag(Qt::WindowCloseButtonHint, false);
mbox.setTextFormat(Qt::RichText);
mbox.setText(message);

View File

@ -6,6 +6,7 @@
#include "gamelistrefreshthread.h"
#include "qthost.h"
#include "qtutils.h"
#include "settingswindow.h"
#include "core/game_list.h"
#include "core/host.h"
@ -181,6 +182,7 @@ void GameListWidget::initialize()
});
connect(m_ui.searchText, &QLineEdit::textChanged, this,
[this](const QString& text) { m_sort_model->setFilterName(text); });
connect(m_ui.searchText, &QLineEdit::returnPressed, this, &GameListWidget::onSearchReturnPressed);
m_table_view = new QTableView(m_ui.stack);
m_table_view->setModel(m_sort_model);
@ -368,7 +370,17 @@ void GameListWidget::onTableViewItemActivated(const QModelIndex& index)
if (!source_index.isValid() || source_index.row() >= static_cast<int>(GameList::GetEntryCount()))
return;
emit entryActivated();
if (qApp->keyboardModifiers().testFlag(Qt::AltModifier))
{
const auto lock = GameList::GetLock();
const GameList::Entry* entry = GameList::GetEntryByIndex(static_cast<u32>(source_index.row()));
if (entry)
SettingsWindow::openGamePropertiesDialog(entry->path, entry->title, entry->serial, entry->hash, entry->region);
}
else
{
emit entryActivated();
}
}
void GameListWidget::onTableViewContextMenuRequested(const QPoint& point)
@ -466,6 +478,25 @@ void GameListWidget::refreshGridCovers()
m_model->refreshCovers();
}
void GameListWidget::focusSearchWidget()
{
m_ui.searchText->setFocus(Qt::ShortcutFocusReason);
}
void GameListWidget::onSearchReturnPressed()
{
// Anything to switch focus to?
const int rows = m_sort_model->rowCount();
if (rows == 0)
return;
QAbstractItemView* const target =
isShowingGameGrid() ? static_cast<QAbstractItemView*>(m_list_view) : static_cast<QAbstractItemView*>(m_table_view);
target->selectionModel()->select(m_sort_model->index(0, 0),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
target->setFocus(Qt::ShortcutFocusReason);
}
void GameListWidget::showGameList()
{
if (m_ui.stack->currentIndex() == 0 || m_model->rowCount() == 0)

View File

@ -80,6 +80,7 @@ private Q_SLOTS:
void onListViewItemActivated(const QModelIndex& index);
void onListViewContextMenuRequested(const QPoint& point);
void onCoverScaleChanged();
void onSearchReturnPressed();
public Q_SLOTS:
void showGameList();
@ -91,6 +92,7 @@ public Q_SLOTS:
void gridZoomOut();
void gridIntScale(int int_scale);
void refreshGridCovers();
void focusSearchWidget();
protected:
void resizeEvent(QResizeEvent* event);

View File

@ -44,6 +44,7 @@
#include <QtCore/QUrl>
#include <QtGui/QActionGroup>
#include <QtGui/QCursor>
#include <QtGui/QShortcut>
#include <QtGui/QWindowStateChangeEvent>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QInputDialog>
@ -1263,6 +1264,11 @@ void MainWindow::onRemoveDiscActionTriggered()
g_emu_thread->changeDisc(QString(), false, true);
}
void MainWindow::onScanForNewGamesTriggered()
{
refreshGameList(false);
}
void MainWindow::onViewToolbarActionToggled(bool checked)
{
Host::SetBaseBoolSettingValue("UI", "ShowToolbar", checked);
@ -1302,6 +1308,18 @@ void MainWindow::onViewSystemDisplayTriggered()
switchToEmulationView();
}
void MainWindow::onViewGameGridZoomInActionTriggered()
{
if (isShowingGameList())
m_game_list_widget->gridZoomIn();
}
void MainWindow::onViewGameGridZoomOutActionTriggered()
{
if (isShowingGameList())
m_game_list_widget->gridZoomOut();
}
void MainWindow::onGitHubRepositoryActionTriggered()
{
QtUtils::OpenURL(this, "https://github.com/stenzek/duckstation/");
@ -1626,6 +1644,17 @@ void MainWindow::setupAdditionalUi()
updateDebugMenuVisibility();
m_shortcuts.open_file =
new QShortcut(Qt::ControlModifier | Qt::Key_O, this, this, &MainWindow::onStartFileActionTriggered);
m_shortcuts.game_list_refresh = new QShortcut(Qt::Key_F5, this, this, &MainWindow::onScanForNewGamesTriggered);
m_shortcuts.game_list_search = new QShortcut(this);
m_shortcuts.game_list_search->setKeys({Qt::ControlModifier | Qt::Key_F, Qt::Key_F3});
connect(m_shortcuts.game_list_search, &QShortcut::activated, m_game_list_widget, &GameListWidget::focusSearchWidget);
m_shortcuts.game_grid_zoom_in =
new QShortcut(Qt::ControlModifier | Qt::Key_Plus, this, this, &MainWindow::onViewGameGridZoomInActionTriggered);
m_shortcuts.game_grid_zoom_out =
new QShortcut(Qt::ControlModifier | Qt::Key_Minus, this, this, &MainWindow::onViewGameGridZoomOutActionTriggered);
#ifdef ENABLE_RAINTEGRATION
if (Achievements::IsUsingRAIntegration())
{
@ -1691,6 +1720,12 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool cheevo
m_ui.actionViewGameProperties->setDisabled(starting_or_not_running);
m_shortcuts.open_file->setEnabled(!starting_or_running);
m_shortcuts.game_list_refresh->setEnabled(!starting_or_running);
m_shortcuts.game_list_search->setEnabled(!starting_or_running);
m_shortcuts.game_grid_zoom_in->setEnabled(!starting_or_running);
m_shortcuts.game_grid_zoom_out->setEnabled(!starting_or_running);
if (starting_or_running)
{
if (!m_ui.toolBar->actions().contains(m_ui.actionPowerOff))
@ -1916,7 +1951,7 @@ void MainWindow::connectSignals()
connect(m_ui.actionReset, &QAction::triggered, this, []() { g_emu_thread->resetSystem(true); });
connect(m_ui.actionPause, &QAction::toggled, this, [](bool active) { g_emu_thread->setSystemPaused(active); });
connect(m_ui.actionScreenshot, &QAction::triggered, g_emu_thread, &EmuThread::saveScreenshot);
connect(m_ui.actionScanForNewGames, &QAction::triggered, this, [this]() { refreshGameList(false); });
connect(m_ui.actionScanForNewGames, &QAction::triggered, this, &MainWindow::onScanForNewGamesTriggered);
connect(m_ui.actionRescanAllGames, &QAction::triggered, this, [this]() { refreshGameList(true); });
connect(m_ui.actionLoadState, &QAction::triggered, this, [this]() { m_ui.menuLoadState->exec(QCursor::pos()); });
connect(m_ui.actionSaveState, &QAction::triggered, this, [this]() { m_ui.menuSaveState->exec(QCursor::pos()); });
@ -1968,14 +2003,8 @@ void MainWindow::connectSignals()
connect(m_ui.actionMergeDiscSets, &QAction::triggered, m_game_list_widget, &GameListWidget::setMergeDiscSets);
connect(m_ui.actionShowGameIcons, &QAction::triggered, m_game_list_widget, &GameListWidget::setShowGameIcons);
connect(m_ui.actionGridViewShowTitles, &QAction::triggered, m_game_list_widget, &GameListWidget::setShowCoverTitles);
connect(m_ui.actionGridViewZoomIn, &QAction::triggered, m_game_list_widget, [this]() {
if (isShowingGameList())
m_game_list_widget->gridZoomIn();
});
connect(m_ui.actionGridViewZoomOut, &QAction::triggered, m_game_list_widget, [this]() {
if (isShowingGameList())
m_game_list_widget->gridZoomOut();
});
connect(m_ui.actionGridViewZoomIn, &QAction::triggered, this, &MainWindow::onViewGameGridZoomInActionTriggered);
connect(m_ui.actionGridViewZoomOut, &QAction::triggered, this, &MainWindow::onViewGameGridZoomOutActionTriggered);
connect(m_ui.actionGridViewRefreshCovers, &QAction::triggered, m_game_list_widget,
&GameListWidget::refreshGridCovers);

View File

@ -24,6 +24,7 @@
class QLabel;
class QThread;
class QProgressBar;
class QShortcut;
class MainWindow;
class GameListWidget;
@ -169,12 +170,15 @@ private Q_SLOTS:
void onStartFullscreenUITriggered();
void onFullscreenUIStateChange(bool running);
void onRemoveDiscActionTriggered();
void onScanForNewGamesTriggered();
void onViewToolbarActionToggled(bool checked);
void onViewLockToolbarActionToggled(bool checked);
void onViewStatusBarActionToggled(bool checked);
void onViewGameListActionTriggered();
void onViewGameGridActionTriggered();
void onViewSystemDisplayTriggered();
void onViewGameGridZoomInActionTriggered();
void onViewGameGridZoomOutActionTriggered();
void onGitHubRepositoryActionTriggered();
void onIssueTrackerActionTriggered();
void onDiscordServerActionTriggered();
@ -296,6 +300,15 @@ private:
QMenu* m_settings_toolbar_menu = nullptr;
struct
{
QShortcut* open_file = nullptr;
QShortcut* game_list_refresh = nullptr;
QShortcut* game_list_search = nullptr;
QShortcut* game_grid_zoom_in = nullptr;
QShortcut* game_grid_zoom_out = nullptr;
} m_shortcuts;
SettingsWindow* m_settings_window = nullptr;
ControllerSettingsWindow* m_controller_settings_window = nullptr;

View File

@ -836,17 +836,11 @@
<property name="text">
<string>Zoom &amp;In (Grid View)</string>
</property>
<property name="shortcut">
<string>Ctrl++</string>
</property>
</action>
<action name="actionGridViewZoomOut">
<property name="text">
<string>Zoom &amp;Out (Grid View)</string>
</property>
<property name="shortcut">
<string>Ctrl+-</string>
</property>
</action>
<action name="actionGridViewRefreshCovers">
<property name="text">
@ -931,16 +925,6 @@
<string>Capture GPU Frame</string>
</property>
</action>
<action name="actionasdf">
<property name="text">
<string>asdf</string>
</property>
</action>
<action name="actionaaa">
<property name="text">
<string>aaa</string>
</property>
</action>
</widget>
<resources>
<include location="resources/duckstation-qt.qrc"/>

View File

@ -501,12 +501,7 @@ bool QtHost::SetCriticalFolders()
// the resources directory should exist, bail out if not
const std::string rcc_path = Path::Combine(EmuFolders::Resources, "duckstation-qt.rcc");
if (!FileSystem::FileExists(rcc_path.c_str()) || !QResource::registerResource(QString::fromStdString(rcc_path)) ||
#if defined(_WIN32) || defined(__APPLE__)
!FileSystem::DirectoryExists(EmuFolders::Resources.c_str())
#else
!FileSystem::IsRealDirectory(EmuFolders::Resources.c_str())
#endif
)
!FileSystem::DirectoryExists(EmuFolders::Resources.c_str()))
{
QMessageBox::critical(nullptr, QStringLiteral("Error"),
QStringLiteral("Resources are missing, your installation is incomplete."));