duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

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 };