Qt: Add placeholder for when no games are in list

This commit is contained in:
Connor McLaughlin 2022-05-07 16:32:44 +10:00 committed by refractionpcsx2
parent 90707c453d
commit 81cd2d9be9
7 changed files with 179 additions and 2 deletions

View File

@ -30,6 +30,7 @@ target_sources(pcsx2-qt PRIVATE
QtUtils.cpp QtUtils.cpp
QtUtils.h QtUtils.h
SettingWidgetBinder.h SettingWidgetBinder.h
GameList/EmptyGameListWidget.ui
GameList/GameListModel.cpp GameList/GameListModel.cpp
GameList/GameListModel.h GameList/GameListModel.h
GameList/GameListRefreshThread.cpp GameList/GameListRefreshThread.cpp

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EmptyGameListWidget</class>
<widget class="QWidget" name="EmptyGameListWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>687</width>
<height>470</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;No games in supported formats were found.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Please add a directory with games to begin.&lt;/p&gt;&lt;p&gt;Game dumps in the following formats will be scanned and listed:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="supportedFormats">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="addGameDirectory">
<property name="text">
<string>Add Game Directory...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="scanForNewGames">
<property name="text">
<string>Scan For New Games</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -32,6 +32,12 @@
#include "QtHost.h" #include "QtHost.h"
#include "QtUtils.h" #include "QtUtils.h"
static const char* SUPPORTED_FORMATS_STRING = QT_TRANSLATE_NOOP(GameListWidget,
".bin/.iso (ISO Disc Images)\n"
".chd (Compressed Hunks of Data)\n"
".cso (Compressed ISO)\n"
".gz (Gzip Compressed ISO)");
class GameListSortModel final : public QSortFilterProxyModel class GameListSortModel final : public QSortFilterProxyModel
{ {
public: public:
@ -124,6 +130,13 @@ void GameListWidget::initialize()
insertWidget(1, m_list_view); insertWidget(1, m_list_view);
m_empty_widget = new QWidget(this);
m_empty_ui.setupUi(m_empty_widget);
m_empty_ui.supportedFormats->setText(qApp->translate("GameListWidget", SUPPORTED_FORMATS_STRING));
connect(m_empty_ui.addGameDirectory, &QPushButton::clicked, this, [this]() { emit addGameDirectoryRequested(); });
connect(m_empty_ui.scanForNewGames, &QPushButton::clicked, this, [this]() { refresh(false); });
insertWidget(2, m_empty_widget);
if (QtHost::GetBaseBoolSettingValue("UI", "GameListGridView", false)) if (QtHost::GetBaseBoolSettingValue("UI", "GameListGridView", false))
setCurrentIndex(1); setCurrentIndex(1);
else else
@ -167,6 +180,10 @@ void GameListWidget::refresh(bool invalidate_cache)
void GameListWidget::onRefreshProgress(const QString& status, int current, int total) void GameListWidget::onRefreshProgress(const QString& status, int current, int total)
{ {
// switch away from the placeholder while we scan, in case we find anything
if (currentIndex() == 2)
setCurrentIndex(QtHost::GetBaseBoolSettingValue("UI", "GameListGridView", false) ? 1 : 0);
m_model->refresh(); m_model->refresh();
emit refreshProgress(status, current, total); emit refreshProgress(status, current, total);
} }
@ -180,6 +197,10 @@ void GameListWidget::onRefreshComplete()
m_refresh_thread->wait(); m_refresh_thread->wait();
delete m_refresh_thread; delete m_refresh_thread;
m_refresh_thread = nullptr; m_refresh_thread = nullptr;
// if we still had no games, switch to the helper widget
if (m_model->rowCount() == 0)
setCurrentIndex(2);
} }
void GameListWidget::onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous) void GameListWidget::onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous)
@ -276,7 +297,7 @@ void GameListWidget::refreshGridCovers()
void GameListWidget::showGameList() void GameListWidget::showGameList()
{ {
if (currentIndex() == 0) if (currentIndex() == 0 || m_model->rowCount() == 0)
return; return;
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", false); QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", false);
@ -286,7 +307,7 @@ void GameListWidget::showGameList()
void GameListWidget::showGameGrid() void GameListWidget::showGameGrid()
{ {
if (currentIndex() == 1) if (currentIndex() == 1 || m_model->rowCount() == 0)
return; return;
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", true); QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", true);

View File

@ -15,6 +15,7 @@
#pragma once #pragma once
#include "pcsx2/Frontend/GameList.h" #include "pcsx2/Frontend/GameList.h"
#include "ui_EmptyGameListWidget.h"
#include <QtWidgets/QListView> #include <QtWidgets/QListView>
#include <QtWidgets/QStackedWidget> #include <QtWidgets/QStackedWidget>
#include <QtWidgets/QTableView> #include <QtWidgets/QTableView>
@ -69,6 +70,8 @@ Q_SIGNALS:
void entryActivated(); void entryActivated();
void entryContextMenuRequested(const QPoint& point); void entryContextMenuRequested(const QPoint& point);
void addGameDirectoryRequested();
private Q_SLOTS: private Q_SLOTS:
void onRefreshProgress(const QString& status, int current, int total); void onRefreshProgress(const QString& status, int current, int total);
void onRefreshComplete(); void onRefreshComplete();
@ -107,5 +110,8 @@ private:
QTableView* m_table_view = nullptr; QTableView* m_table_view = nullptr;
GameListGridListView* m_list_view = nullptr; GameListGridListView* m_list_view = nullptr;
QWidget* m_empty_widget = nullptr;
Ui::EmptyGameListWidget m_empty_ui;
GameListRefreshThread* m_refresh_thread = nullptr; GameListRefreshThread* m_refresh_thread = nullptr;
}; };

View File

@ -215,6 +215,8 @@ void MainWindow::connectSignals()
connect(m_game_list_widget, &GameListWidget::entryActivated, this, &MainWindow::onGameListEntryActivated, Qt::QueuedConnection); connect(m_game_list_widget, &GameListWidget::entryActivated, this, &MainWindow::onGameListEntryActivated, Qt::QueuedConnection);
connect( connect(
m_game_list_widget, &GameListWidget::entryContextMenuRequested, this, &MainWindow::onGameListEntryContextMenuRequested, Qt::QueuedConnection); m_game_list_widget, &GameListWidget::entryContextMenuRequested, this, &MainWindow::onGameListEntryContextMenuRequested, Qt::QueuedConnection);
connect(m_game_list_widget, &GameListWidget::addGameDirectoryRequested, this,
[this]() { getSettingsDialog()->getGameListSettingsWidget()->addSearchDirectory(this); });
} }
void MainWindow::connectVMThreadSignals(EmuThread* thread) void MainWindow::connectVMThreadSignals(EmuThread* thread)

View File

@ -262,6 +262,9 @@
<QtUi Include="MainWindow.ui"> <QtUi Include="MainWindow.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>
<QtUi Include="GameList\EmptyGameListWidget.ui">
<FileType>Document</FileType>
</QtUi>
<QtUi Include="Settings\SettingsDialog.ui"> <QtUi Include="Settings\SettingsDialog.ui">
<FileType>Document</FileType> <FileType>Document</FileType>
</QtUi> </QtUi>

View File

@ -363,5 +363,8 @@
<QtUi Include="Settings\DEV9SettingsWidget.ui"> <QtUi Include="Settings\DEV9SettingsWidget.ui">
<Filter>Settings</Filter> <Filter>Settings</Filter>
</QtUi> </QtUi>
<QtUi Include="GameList\EmptyGameListWidget.ui">
<Filter>GameList</Filter>
</QtUi>
</ItemGroup> </ItemGroup>
</Project> </Project>