diff options
Diffstat (limited to 'src/yuzu/game_list_p.h')
-rw-r--r-- | src/yuzu/game_list_p.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h new file mode 100644 index 000000000..9881296d9 --- /dev/null +++ b/src/yuzu/game_list_p.h @@ -0,0 +1,143 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <atomic> +#include <QImage> +#include <QRunnable> +#include <QStandardItem> +#include <QString> +#include "citra_qt/util/util.h" +#include "common/string_util.h" + +/** + * Gets the default icon (for games without valid SMDH) + * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24) + * @return QPixmap default icon + */ +static QPixmap GetDefaultIcon(bool large) { + int size = large ? 48 : 24; + QPixmap icon(size, size); + icon.fill(Qt::transparent); + return icon; +} + +class GameListItem : public QStandardItem { + +public: + GameListItem() : QStandardItem() {} + GameListItem(const QString& string) : QStandardItem(string) {} + virtual ~GameListItem() override {} +}; + +/** + * A specialization of GameListItem for path values. + * This class ensures that for every full path value it holds, a correct string representation + * of just the filename (with no extension) will be displayed to the user. + * If this class receives valid SMDH data, it will also display game icons and titles. + */ +class GameListItemPath : public GameListItem { + +public: + static const int FullPathRole = Qt::UserRole + 1; + static const int TitleRole = Qt::UserRole + 2; + static const int ProgramIdRole = Qt::UserRole + 3; + + GameListItemPath() : GameListItem() {} + GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) + : GameListItem() { + setData(game_path, FullPathRole); + setData(qulonglong(program_id), ProgramIdRole); + } + + QVariant data(int role) const override { + if (role == Qt::DisplayRole) { + std::string filename; + Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename, + nullptr); + QString title = data(TitleRole).toString(); + return QString::fromStdString(filename) + (title.isEmpty() ? "" : "\n " + title); + } else { + return GameListItem::data(role); + } + } +}; + +/** + * A specialization of GameListItem for size values. + * This class ensures that for every numerical size value it holds (in bytes), a correct + * human-readable string representation will be displayed to the user. + */ +class GameListItemSize : public GameListItem { + +public: + static const int SizeRole = Qt::UserRole + 1; + + GameListItemSize() : GameListItem() {} + GameListItemSize(const qulonglong size_bytes) : GameListItem() { + setData(size_bytes, SizeRole); + } + + void setData(const QVariant& value, int role) override { + // By specializing setData for SizeRole, we can ensure that the numerical and string + // representations of the data are always accurate and in the correct format. + if (role == SizeRole) { + qulonglong size_bytes = value.toULongLong(); + GameListItem::setData(ReadableByteSize(size_bytes), Qt::DisplayRole); + GameListItem::setData(value, SizeRole); + } else { + GameListItem::setData(value, role); + } + } + + /** + * This operator is, in practice, only used by the TreeView sorting systems. + * Override it so that it will correctly sort by numerical value instead of by string + * representation. + */ + bool operator<(const QStandardItem& other) const override { + return data(SizeRole).toULongLong() < other.data(SizeRole).toULongLong(); + } +}; + +/** + * Asynchronous worker object for populating the game list. + * Communicates with other threads through Qt's signal/slot system. + */ +class GameListWorker : public QObject, public QRunnable { + Q_OBJECT + +public: + GameListWorker(QString dir_path, bool deep_scan) + : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} + +public slots: + /// Starts the processing of directory tree information. + void run() override; + /// Tells the worker that it should no longer continue processing. Thread-safe. + void Cancel(); + +signals: + /** + * The `EntryReady` signal is emitted once an entry has been prepared and is ready + * to be added to the game list. + * @param entry_items a list with `QStandardItem`s that make up the columns of the new entry. + */ + void EntryReady(QList<QStandardItem*> entry_items); + + /** + * After the worker has traversed the game directory looking for entries, this signal is emmited + * with a list of folders that should be watched for changes as well. + */ + void Finished(QStringList watch_list); + +private: + QStringList watch_list; + QString dir_path; + bool deep_scan; + std::atomic_bool stop_processing; + + void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0); +}; |