gamelistmodel.h (4230B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "core/game_database.h" 7 #include "core/game_list.h" 8 #include "core/types.h" 9 10 #include "common/heterogeneous_containers.h" 11 #include "common/lru_cache.h" 12 13 #include <QtCore/QAbstractTableModel> 14 #include <QtGui/QPixmap> 15 #include <algorithm> 16 #include <array> 17 #include <optional> 18 19 class GameListModel final : public QAbstractTableModel 20 { 21 Q_OBJECT 22 23 public: 24 enum Column : int 25 { 26 Column_Icon, 27 Column_Serial, 28 Column_Title, 29 Column_FileTitle, 30 Column_Developer, 31 Column_Publisher, 32 Column_Genre, 33 Column_Year, 34 Column_Players, 35 Column_TimePlayed, 36 Column_LastPlayed, 37 Column_FileSize, 38 Column_UncompressedSize, 39 Column_Region, 40 Column_Compatibility, 41 Column_Cover, 42 43 Column_Count 44 }; 45 46 static std::optional<Column> getColumnIdForName(std::string_view name); 47 static const char* getColumnName(Column col); 48 49 GameListModel(float cover_scale, bool show_cover_titles, bool show_game_icons, QObject* parent = nullptr); 50 ~GameListModel(); 51 52 int rowCount(const QModelIndex& parent = QModelIndex()) const override; 53 int columnCount(const QModelIndex& parent = QModelIndex()) const override; 54 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; 55 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 56 57 ALWAYS_INLINE const QString& getColumnDisplayName(int column) { return m_column_display_names[column]; } 58 59 bool hasTakenGameList() const; 60 void takeGameList(); 61 62 void refresh(); 63 void reloadThemeSpecificImages(); 64 65 bool titlesLessThan(const GameList::Entry* left, const GameList::Entry* right) const; 66 bool lessThan(const GameList::Entry* left, const GameList::Entry* right, int column) const; 67 68 bool lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const; 69 70 bool getShowCoverTitles() const { return m_show_titles_for_covers; } 71 void setShowCoverTitles(bool enabled) { m_show_titles_for_covers = enabled; } 72 73 bool getShowGameIcons() const { return m_show_game_icons; } 74 void setShowGameIcons(bool enabled); 75 QIcon getIconForGame(const QString& path); 76 77 float getCoverScale() const { return m_cover_scale; } 78 void setCoverScale(float scale); 79 int getCoverArtWidth() const; 80 int getCoverArtHeight() const; 81 int getCoverArtSpacing() const; 82 void refreshCovers(); 83 void updateCacheSize(int width, int height); 84 85 Q_SIGNALS: 86 void coverScaleChanged(); 87 88 private: 89 /// The purpose of this cache is to stop us trying to constantly extract memory card icons, when we know a game 90 /// doesn't have any saves yet. It caches the serial:memcard_timestamp pair, and only tries extraction when the 91 /// timestamp of the memory card has changed. 92 #pragma pack(push, 1) 93 struct MemcardTimestampCacheEntry 94 { 95 enum : u32 96 { 97 MAX_SERIAL_LENGTH = 32, 98 }; 99 100 char serial[MAX_SERIAL_LENGTH]; 101 s64 memcard_timestamp; 102 }; 103 #pragma pack(pop) 104 105 QVariant data(const QModelIndex& index, int role, const GameList::Entry* ge) const; 106 107 void loadCommonImages(); 108 void loadThemeSpecificImages(); 109 void setColumnDisplayNames(); 110 void loadOrGenerateCover(const GameList::Entry* ge); 111 void invalidateCoverForPath(const std::string& path); 112 113 const QPixmap& getIconPixmapForEntry(const GameList::Entry* ge) const; 114 static void fixIconPixmapSize(QPixmap& pm); 115 116 static QString formatTimespan(time_t timespan); 117 118 std::optional<GameList::EntryList> m_taken_entries; 119 120 float m_cover_scale = 0.0f; 121 bool m_show_titles_for_covers = false; 122 bool m_show_game_icons = false; 123 124 std::array<QString, Column_Count> m_column_display_names; 125 std::array<QPixmap, static_cast<int>(GameList::EntryType::Count)> m_type_pixmaps; 126 std::array<QPixmap, static_cast<int>(DiscRegion::Count)> m_region_pixmaps; 127 std::array<QPixmap, static_cast<int>(GameDatabase::CompatibilityRating::Count)> m_compatibility_pixmaps; 128 129 QPixmap m_placeholder_pixmap; 130 QPixmap m_loading_pixmap; 131 132 mutable LRUCache<std::string, QPixmap> m_cover_pixmap_cache; 133 134 mutable LRUCache<std::string, QPixmap> m_memcard_pixmap_cache; 135 };