aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft
diff options
context:
space:
mode:
authorRachel Powers <508861+Ryex@users.noreply.github.com>2023-05-04 23:46:00 -0700
committerRachel Powers <508861+Ryex@users.noreply.github.com>2023-05-04 23:46:00 -0700
commited185f047fa2efc80cc622165583e57f21ffa560 (patch)
treece8a7e76167afa6c2379d3473d27b0af49eb1afb /launcher/minecraft
parentd384d991fad80cdadf6486d61e5c06a692a0031d (diff)
downloadPrismLauncher-ed185f047fa2efc80cc622165583e57f21ffa560.tar.gz
PrismLauncher-ed185f047fa2efc80cc622165583e57f21ffa560.tar.bz2
PrismLauncher-ed185f047fa2efc80cc622165583e57f21ffa560.zip
feat(resourcePackPage): icon column
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
Diffstat (limited to 'launcher/minecraft')
-rw-r--r--launcher/minecraft/mod/ResourcePack.cpp19
-rw-r--r--launcher/minecraft/mod/ResourcePack.h6
-rw-r--r--launcher/minecraft/mod/ResourcePackFolderModel.cpp21
-rw-r--r--launcher/minecraft/mod/ResourcePackFolderModel.h1
-rw-r--r--launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp67
-rw-r--r--launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h5
6 files changed, 103 insertions, 16 deletions
diff --git a/launcher/minecraft/mod/ResourcePack.cpp b/launcher/minecraft/mod/ResourcePack.cpp
index 876d5c3e..5fc9d7a6 100644
--- a/launcher/minecraft/mod/ResourcePack.cpp
+++ b/launcher/minecraft/mod/ResourcePack.cpp
@@ -39,7 +39,7 @@ void ResourcePack::setDescription(QString new_description)
m_description = new_description;
}
-void ResourcePack::setImage(QImage new_image)
+void ResourcePack::setImage(QImage new_image) const
{
QMutexLocker locker(&m_data_lock);
@@ -48,7 +48,10 @@ void ResourcePack::setImage(QImage new_image)
if (m_pack_image_cache_key.key.isValid())
PixmapCache::instance().remove(m_pack_image_cache_key.key);
- m_pack_image_cache_key.key = PixmapCache::instance().insert(QPixmap::fromImage(new_image));
+ // scale the image to avoid flooding the pixmapcache
+ auto pixmap = QPixmap::fromImage(new_image.scaled(QSize(128, 128), Qt::AspectRatioMode::KeepAspectRatioByExpanding));
+
+ m_pack_image_cache_key.key = PixmapCache::instance().insert(pixmap);
m_pack_image_cache_key.was_ever_used = true;
// This can happen if the pixmap is too big to fit in the cache :c
@@ -58,21 +61,25 @@ void ResourcePack::setImage(QImage new_image)
}
}
-QPixmap ResourcePack::image(QSize size)
+QPixmap ResourcePack::image(QSize size, Qt::AspectRatioMode mode) const
{
QPixmap cached_image;
if (PixmapCache::instance().find(m_pack_image_cache_key.key, &cached_image)) {
if (size.isNull())
return cached_image;
- return cached_image.scaled(size);
+ return cached_image.scaled(size, mode);
}
// No valid image we can get
- if (!m_pack_image_cache_key.was_ever_used)
+ if (!m_pack_image_cache_key.was_ever_used) {
return {};
+ } else {
+ qDebug() << "Resource Pack" << name() << "Had it's image evicted from the cache. reloading...";
+ PixmapCache::markCacheMissByEviciton();
+ }
// Imaged got evicted from the cache. Re-process it and retry.
- ResourcePackUtils::process(*this);
+ ResourcePackUtils::processPackPNG(*this);
return image(size);
}
diff --git a/launcher/minecraft/mod/ResourcePack.h b/launcher/minecraft/mod/ResourcePack.h
index 7cb414d8..da354bc1 100644
--- a/launcher/minecraft/mod/ResourcePack.h
+++ b/launcher/minecraft/mod/ResourcePack.h
@@ -31,7 +31,7 @@ class ResourcePack : public Resource {
[[nodiscard]] QString description() const { return m_description; }
/** Gets the image of the resource pack, converted to a QPixmap for drawing, and scaled to size. */
- [[nodiscard]] QPixmap image(QSize size);
+ [[nodiscard]] QPixmap image(QSize size, Qt::AspectRatioMode mode = Qt::AspectRatioMode::IgnoreAspectRatio) const;
/** Thread-safe. */
void setPackFormat(int new_format_id);
@@ -40,7 +40,7 @@ class ResourcePack : public Resource {
void setDescription(QString new_description);
/** Thread-safe. */
- void setImage(QImage new_image);
+ void setImage(QImage new_image) const;
bool valid() const override;
@@ -67,5 +67,5 @@ class ResourcePack : public Resource {
struct {
QPixmapCache::Key key;
bool was_ever_used = false;
- } m_pack_image_cache_key;
+ } mutable m_pack_image_cache_key;
};
diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
index 6eba4e2e..c8c0c773 100644
--- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp
+++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp
@@ -35,6 +35,8 @@
*/
#include "ResourcePackFolderModel.h"
+#include <qnamespace.h>
+#include <qsize.h>
#include <QIcon>
#include <QStyle>
@@ -48,7 +50,7 @@
ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, std::shared_ptr<const BaseInstance> instance)
: ResourceFolderModel(QDir(dir), instance)
{
- m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE };
+ m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE, SortType::NAME };
}
QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
@@ -84,9 +86,11 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
return {};
}
case Qt::DecorationRole: {
- if (column == NAME_COLUMN && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink()))
+ if (column == NameColumn && (at(row)->isSymLinkUnder(instDirPath()) || at(row)->isMoreThanOneHardLink()))
return APPLICATION->getThemedIcon("status-yellow");
-
+ if (column == ImageColumn) {
+ return at(row)->image(QSize(64, 64), Qt::AspectRatioMode::KeepAspectRatioByExpanding);
+ }
return {};
}
case Qt::ToolTipRole: {
@@ -94,7 +98,7 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
//: The string being explained by this is in the format: ID (Lower version - Upper version)
return tr("The resource pack format ID, as well as the Minecraft versions it was designed for.");
}
- if (column == NAME_COLUMN) {
+ if (column == NameColumn) {
if (at(row)->isSymLinkUnder(instDirPath())) {
return m_resources[row]->internal_id() +
tr("\nWarning: This resource is symbolically linked from elsewhere. Editing it will also change the original."
@@ -133,6 +137,8 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient
return tr("Pack Format");
case DateColumn:
return tr("Last changed");
+ case ImageColumn:
+ return tr("Image");
default:
return {};
}
@@ -151,6 +157,13 @@ QVariant ResourcePackFolderModel::headerData(int section, Qt::Orientation orient
default:
return {};
}
+ case Qt::SizeHintRole:
+ switch (section) {
+ case ImageColumn:
+ return QSize(64,0);
+ default:
+ return {};
+ }
default:
return {};
}
diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.h b/launcher/minecraft/mod/ResourcePackFolderModel.h
index 66d5a074..71532f30 100644
--- a/launcher/minecraft/mod/ResourcePackFolderModel.h
+++ b/launcher/minecraft/mod/ResourcePackFolderModel.h
@@ -14,6 +14,7 @@ public:
NameColumn,
PackFormatColumn,
DateColumn,
+ ImageColumn,
NUM_COLUMNS
};
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
index 4bf0b80d..a67c56a8 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
@@ -165,15 +165,16 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level)
bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
file.close();
+ zip.close();
if (!pack_png_result) {
return png_invalid(); // pack.png invalid
}
} else {
+ zip.close();
return png_invalid(); // could not set pack.mcmeta as current file.
}
zip.close();
-
return true;
}
@@ -193,7 +194,7 @@ bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data)
return true;
}
-bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data)
+bool processPackPNG(const ResourcePack& pack, QByteArray&& raw_data)
{
auto img = QImage::fromData(raw_data);
if (!img.isNull()) {
@@ -205,6 +206,68 @@ bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data)
return true;
}
+bool processPackPNG(const ResourcePack& pack)
+{
+ auto png_invalid = [&pack]() {
+ qWarning() << "Resource pack at" << pack.fileinfo().filePath() << "does not have a valid pack.png";
+ return false;
+ };
+
+ switch (pack.type()) {
+ case ResourceType::FOLDER:
+ {
+ QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
+ if (image_file_info.exists() && image_file_info.isFile()) {
+ QFile pack_png_file(image_file_info.filePath());
+ if (!pack_png_file.open(QIODevice::ReadOnly))
+ return png_invalid(); // can't open pack.png file
+
+ auto data = pack_png_file.readAll();
+
+ bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
+
+ pack_png_file.close();
+ if (!pack_png_result) {
+ return png_invalid(); // pack.png invalid
+ }
+ } else {
+ return png_invalid(); // pack.png does not exists or is not a valid file.
+ }
+ }
+ case ResourceType::ZIPFILE:
+ {
+ Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
+
+ QuaZip zip(pack.fileinfo().filePath());
+ if (!zip.open(QuaZip::mdUnzip))
+ return false; // can't open zip file
+
+ QuaZipFile file(&zip);
+ if (zip.setCurrentFile("pack.png")) {
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCritical() << "Failed to open file in zip.";
+ zip.close();
+ return png_invalid();
+ }
+
+ auto data = file.readAll();
+
+ bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));
+
+ file.close();
+ if (!pack_png_result) {
+ return png_invalid(); // pack.png invalid
+ }
+ } else {
+ return png_invalid(); // could not set pack.mcmeta as current file.
+ }
+ }
+ default:
+ qWarning() << "Invalid type for resource pack parse task!";
+ return false;
+ }
+}
+
bool validate(QFileInfo file)
{
ResourcePack rp{ file };
diff --git a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
index d0c24c2b..58d90b3b 100644
--- a/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
+++ b/launcher/minecraft/mod/tasks/LocalResourcePackParseTask.h
@@ -35,7 +35,10 @@ bool processZIP(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Ful
bool processFolder(ResourcePack& pack, ProcessingLevel level = ProcessingLevel::Full);
bool processMCMeta(ResourcePack& pack, QByteArray&& raw_data);
-bool processPackPNG(ResourcePack& pack, QByteArray&& raw_data);
+bool processPackPNG(const ResourcePack& pack, QByteArray&& raw_data);
+
+/// processes ONLY the pack.png (rest of the pack may be invalid)
+bool processPackPNG(const ResourcePack& pack);
/** Checks whether a file is valid as a resource pack or not. */
bool validate(QFileInfo file);