From 180e0c940eda68962df342f46551e8454a35f167 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 22 Apr 2023 10:45:39 +0300 Subject: [PATCH] Game List: Make Ctrl+F Focus To Search Bar --- rpcs3/rpcs3.vcxproj | 17 ++++++++++++++++- rpcs3/rpcs3.vcxproj.filters | 12 +++++++++--- rpcs3/rpcs3qt/game_list.cpp | 15 +++++++++++++++ rpcs3/rpcs3qt/game_list.h | 7 +++++++ rpcs3/rpcs3qt/game_list_frame.cpp | 20 ++++++++++++++++---- rpcs3/rpcs3qt/game_list_frame.h | 1 + rpcs3/rpcs3qt/main_window.cpp | 1 + 7 files changed, 65 insertions(+), 8 deletions(-) diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index c87940b4ccb7..8228a673b35c 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -236,6 +236,9 @@ true + + true + true @@ -473,6 +476,9 @@ true + + true + true @@ -1394,7 +1400,16 @@ .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" - + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DMINIUPNP_STATICLIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DMINIUPNP_STATICLIB -DHAVE_SDL2 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\libsdl-org\SDL\include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg" + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index de35dad43e45..4d757b4ecd41 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -936,6 +936,12 @@ Generated Files\Release + + Generated Files\Debug + + + Generated Files\Release + @@ -974,9 +980,6 @@ Gui\game window - - Gui\game list - Gui\game list @@ -1384,6 +1387,9 @@ Gui\dev tools + + Gui\game list + diff --git a/rpcs3/rpcs3qt/game_list.cpp b/rpcs3/rpcs3qt/game_list.cpp index 86bc2f5431e5..5e6146ff5095 100644 --- a/rpcs3/rpcs3qt/game_list.cpp +++ b/rpcs3/rpcs3qt/game_list.cpp @@ -1,6 +1,8 @@ #include "game_list.h" #include "movie_item.h" +#include + void game_list::clear_list() { m_last_hover_item = nullptr; @@ -37,6 +39,19 @@ void game_list::mouseMoveEvent(QMouseEvent *event) m_last_hover_item = new_item; } +void game_list::keyPressEvent(QKeyEvent* event) +{ + const auto modifiers = QApplication::keyboardModifiers(); + + if (modifiers == Qt::ControlModifier && event->key() == Qt::Key_F && !event->isAutoRepeat()) + { + Q_EMIT FocusToSearchBar(); + return; + } + + QTableWidget::keyPressEvent(event); +} + void game_list::leaveEvent(QEvent */*event*/) { if (m_last_hover_item) diff --git a/rpcs3/rpcs3qt/game_list.h b/rpcs3/rpcs3qt/game_list.h index b3bf0376de15..ea09b2790db0 100644 --- a/rpcs3/rpcs3qt/game_list.h +++ b/rpcs3/rpcs3qt/game_list.h @@ -2,6 +2,7 @@ #include #include +#include #include #include "game_compatibility.h" @@ -32,16 +33,22 @@ Q_DECLARE_METATYPE(game_info) */ class game_list : public QTableWidget { + Q_OBJECT + public: void clear_list(); // Use this instead of clearContents public Q_SLOTS: void FocusAndSelectFirstEntryIfNoneIs(); +Q_SIGNALS: + void FocusToSearchBar(); + protected: movie_item* m_last_hover_item = nullptr; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; void leaveEvent(QEvent *event) override; }; diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 6869aa4ca729..6bfb46fe22bd 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -201,6 +201,9 @@ game_list_frame::game_list_frame(std::shared_ptr gui_settings, std QMessageBox::warning(this, tr("Warning!"), tr("Failed to retrieve the online compatibility database!\nFalling back to local database.\n\n%0").arg(error)); }); + connect(m_game_grid, &game_list_grid::FocusToSearchBar, this, [this]() { Q_EMIT FocusToSearchBar(); }); + connect(m_game_list, &game_list::FocusToSearchBar, this, [this]() { Q_EMIT FocusToSearchBar(); }); + for (int col = 0; col < m_columnActs.count(); ++col) { m_columnActs[col]->setCheckable(true); @@ -2751,17 +2754,26 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con // Get list of matching apps QList matching_apps; - // Fallback is not needed when at least one entry is visible - const bool use_search_fallback = std::none_of(m_game_data.begin(), m_game_data.end(), [this](auto& game){ return IsEntryVisible(game); }); - for (const auto& app : m_game_data) { - if (IsEntryVisible(app, use_search_fallback)) + if (IsEntryVisible(app)) { matching_apps.push_back(app); } } + // Fallback is not needed when at least one entry is visible + if (matching_apps.isEmpty()) + { + for (const auto& app : m_game_data) + { + if (IsEntryVisible(app, true)) + { + matching_apps.push_back(app); + } + } + } + const int entries = matching_apps.count(); // Edge cases! diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index 9ef5f2f11c26..fd860d670d64 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -92,6 +92,7 @@ private Q_SLOTS: void RequestBoot(const game_info& game, cfg_mode config_mode = cfg_mode::custom, const std::string& config_path = "", const std::string& savestate = ""); void RequestIconSizeChange(const int& val); void NotifyEmuSettingsChange(); + void FocusToSearchBar(); protected: /** Override inherited method from Qt to allow signalling when close happened.*/ void closeEvent(QCloseEvent* event) override; diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 14be8ffa7ccf..56b94ed8266c 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -2788,6 +2788,7 @@ void main_window::CreateConnects() connect(ui->mw_searchbar, &QLineEdit::textChanged, m_game_list_frame, &game_list_frame::SetSearchText); connect(ui->mw_searchbar, &QLineEdit::returnPressed, m_game_list_frame, &game_list_frame::FocusAndSelectFirstEntryIfNoneIs); + connect(m_game_list_frame, &game_list_frame::FocusToSearchBar, this, [this]() { ui->mw_searchbar->setFocus(); }); } void main_window::CreateDockWindows()