From 1c619c5d7c585d40fc1530d72292cc0e02f2afd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C3=A5ngens?= Date: Sun, 22 Dec 2024 21:59:46 +0100 Subject: [PATCH] improve ListItemData It will lose some sharpness but remove the crusty edges from jpeg compression and alos center the cover if needed. Maybe I will just make them smaller instead of using smoothing. Im not sure it looks better with it, when the cover images gets less sharp. --- src/Data.hpp | 129 ++++++++++++++++++++------------ src/FileManager.cpp | 19 +++-- src/Model.cpp | 2 + src/TombRaiderLinuxLauncher.cpp | 30 ++++---- 4 files changed, 111 insertions(+), 69 deletions(-) diff --git a/src/Data.hpp b/src/Data.hpp index 9e44344..c05a275 100644 --- a/src/Data.hpp +++ b/src/Data.hpp @@ -18,15 +18,18 @@ #include #include #include +#include #include +#include #include #include #include /** * @struct FolderNames - * @brief Folder names game used on windows - * @details These names are used by steam and installed in the common folder on linux. + * @brief Folder names game used on Windows + * These names are used by steam and installed in the common folder on Linux. + * Except for `TombEngine (TEN)` I made that one up. */ struct FolderNames { const QString TR1 = "/Tomb Raider (I)"; @@ -34,6 +37,7 @@ struct FolderNames { const QString TR3 = "/TombRaider (III)"; const QString TR4 = "/Tomb Raider (IV) The Last Revelation"; const QString TR5 = "/Tomb Raider (V) Chronicles"; + const QString TEN = "TombEngine (TEN)"; }; struct ZipData { @@ -45,18 +49,10 @@ struct ZipData { */ ZipData() {} ZipData( - QString zipName, - float zipSize, - QString md5sum, - QString url, - int version, - const QString& release) : - name(zipName), - megabyteSize(zipSize), - md5sum(md5sum), - url(url), - version(version), - release(release) {} + QString zipName, float zipSize, QString md5sum, QString url, + int version, const QString& release) : + name(zipName), megabyteSize(zipSize), md5sum(md5sum), + url(url), version(version), release(release) {} QString name; float megabyteSize; QString md5sum; @@ -65,51 +61,90 @@ struct ZipData { QString release; }; +/** + * @struct ListItemData + * @brief Represents a Tomb Raider Level Entry Card. + * + * This struct is designed to store a single TRLE (Tomb Raider Level Editor) level record. + * Each record contains metadata and a cover image displayed as a card in the application. + * The struct includes properties to facilitate searching, filtering, and sorting. + */ struct ListItemData { /** - * @struct InfoData - * @brief - * @param - * @details + * @brief Default constructor for `ListItemData`. + * + * Initializes an empty instance of `ListItemData`. */ ListItemData() {} + + /** + * @brief Parameterized constructor for `ListItemData`. + * + * This constructor initializes a `ListItemData` object with metadata and a cover image. + * The image is converted from raw `QByteArray` to a `QIcon` after scaling it to + * fit within 640x480 dimensions. The scaling maintains the aspect ratio and + * smooths out pixels using `Qt::SmoothTransformation`. The image is centered + * within a transparent background if its aspect ratio does not perfectly match the target. + * + * @param title The TRLE title. Expected to contain a single name. + * @param author The TRLE author(s). Can be a single name or multiple names separated by commas and spaces. + * @param type The TRLE type, represented by a numeric ID. + * @param classInput The TRLE class, represented by a numeric ID. + * @param releaseDate The release date in the format "DD-MMM-YYYY" (e.g., "01-Jan-2000"). + * @param difficulty The TRLE difficulty, represented by a numeric ID. + * @param duration The TRLE duration, represented by a numeric ID. + * @param imageData The cover image as a `QByteArray`. Supported formats include JPEG, PNG, and WEBP. + */ ListItemData( - QString title, - QString author, - qint64 type, - qint64 classIn, - QString releaseDate, - qint64 difficulty, - qint64 duration, + QString title, QString author, qint64 type, qint64 classInput, + QString releaseDate, qint64 difficulty, qint64 duration, QByteArray imageData): - title(title), - author(author), - type(type), - class_(classIn), - releaseDate(releaseDate), - difficulty(difficulty), - duration(duration) { + m_title(title), m_author(author), m_type(type), + m_class(classInput), m_releaseDate(releaseDate), + m_difficulty(difficulty), m_duration(duration) { + // Load the image from the byte array QPixmap pixmap; pixmap.loadFromData(imageData, "WEBP"); - picture.addPixmap(pixmap); - // Scale the pixmap while maintaining aspect ratio - QSize newSize = pixmap.size().scaled(640, 480, Qt::KeepAspectRatio); - // Resize the pixmap to the scaled size - pixmap = pixmap.scaled( + + // Define target dimensions and maintain aspect ratio + QSize targetSize(640, 480); + QSize newSize = pixmap.size().scaled(targetSize, Qt::KeepAspectRatio); + + // Scale the pixmap + QPixmap scaledPixmap = pixmap.scaled( newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - // Create QIcon and add the scaled pixmap - picture.addPixmap(pixmap); + + // Create a centered pixmap with a transparent background + QPixmap centeredPixmap(targetSize); + // Ensure a transparent background + centeredPixmap.fill(Qt::transparent); + + // Calculate offsets for centering the scaled image + qint64 xOffset = (targetSize.width() - newSize.width()) / 2; + qint64 yOffset = (targetSize.height() - newSize.height()) / 2; + + // Draw the scaled image onto the centered pixmap + QPainter painter(¢eredPixmap); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + painter.drawPixmap(xOffset, yOffset, scaledPixmap); + painter.end(); + + // Store the resulting pixmap in a QIcon + m_picture.addPixmap(centeredPixmap); } - QString title; - QString author; - qint64 type; - qint64 class_; - QString releaseDate; - qint64 difficulty; - qint64 duration; - QIcon picture; + + // Data members + QString m_title; ///< The TRLE level title. + QString m_author; ///< The TRLE author(s), as a string. + qint64 m_type; ///< ID of the type of level. + qint64 m_class; ///< ID of the class of the level. + QString m_releaseDate; ///< The release date in "DD-MMM-YYYY" format. + qint64 m_difficulty; ///< ID of the difficulty of the level. + qint64 m_duration; ///< ID of the estimated duration of the level. + QIcon m_picture; ///< The cover image. }; /** diff --git a/src/FileManager.cpp b/src/FileManager.cpp index 3095cf3..ee02853 100644 --- a/src/FileManager.cpp +++ b/src/FileManager.cpp @@ -248,29 +248,34 @@ bool FileManager::makeRelativeLink( const QString& levelDir, const QString& from, const QString& to) { - const QString& levelPath = m_levelDir.absolutePath() + levelDir; - const QString& fromPath = levelPath + from; - const QString& toPath = levelPath + to; + bool status = false; + const QString levelPath = QString("%1%2") + .arg(m_levelDir.absolutePath(), levelDir); + const QString fromPath = QString("%1%2") + .arg(levelPath, from); + const QString toPath = QString("%1%2") + .arg(levelPath, to); if (QFile::link(fromPath, toPath)) { qDebug() << "Symbolic link created successfully."; - return 0; + status = true; } else { QFileInfo i(toPath); if (i.isSymLink()) { QFile::remove(toPath); if (QFile::link(fromPath, toPath)) { qDebug() << "Symbolic link created successfully."; - return 0; + status = true; } else { qDebug() << "Failed to create symbolic link."; - return 1; + status = false; } } else { qDebug() << "Failed to create symbolic link."; - return 1; + status = false; } } + return status; } qint64 FileManager::removeFileOrDirectory( diff --git a/src/Model.cpp b/src/Model.cpp index d7c5f21..b49b74e 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -14,6 +14,8 @@ #include "Model.hpp" // Those lambda should be in another header file +// I hate this and it should be able to recognize both the directory +// when linking and the game exe to make a symbolic link to automatically Model::Model(QObject *parent) : QObject(parent), checkCommonFilesIndex_m(1) { instructionManager.addInstruction(4, [this](int id) { qDebug() << "Perform Operation A"; diff --git a/src/TombRaiderLinuxLauncher.cpp b/src/TombRaiderLinuxLauncher.cpp index d8d8181..dfaafde 100644 --- a/src/TombRaiderLinuxLauncher.cpp +++ b/src/TombRaiderLinuxLauncher.cpp @@ -195,30 +195,30 @@ void TombRaiderLinuxLauncher::generateList() { const qint64 s = list.size(); for (qint64 i = 0; i < s; i++) { QString tag = QString("%1 by %2\n") - .arg(list[i].title) - .arg(list[i].author); + .arg(list[i].m_title) + .arg(list[i].m_author); tag += QString( "Type: %1\nClass: %2\nDifficulty: %3\nDuration: %4\nDate:%5") - .arg(mapType.at(list[i].type)) - .arg(mapClass.at(list[i].class_)) - .arg(mapDifficulty.at(list[i].difficulty)) - .arg(mapDuration.at(list[i].duration)) - .arg(list[i].releaseDate); + .arg(mapType.at(list[i].m_type)) + .arg(mapClass.at(list[i].m_class)) + .arg(mapDifficulty.at(list[i].m_difficulty)) + .arg(mapDuration.at(list[i].m_duration)) + .arg(list[i].m_releaseDate); QListWidgetItem *wi = - new QListWidgetItem(list[i].picture, tag); + new QListWidgetItem(list[i].m_picture, tag); wi->setData(Qt::UserRole, QVariant(i + 1)); QVariantMap itemData; - itemData["title"] = list[i].title; - itemData["author"] = list[i].author; - itemData["type"] = list[i].type; - itemData["class_"] = list[i].class_; - itemData["releaseDate"] = list[i].releaseDate; - itemData["difficulty"] = list[i].difficulty; - itemData["duration"] = list[i].duration; + itemData["title"] = list[i].m_title; + itemData["author"] = list[i].m_author; + itemData["type"] = list[i].m_type; + itemData["class_"] = list[i].m_class; + itemData["releaseDate"] = list[i].m_releaseDate; + itemData["difficulty"] = list[i].m_difficulty; + itemData["duration"] = list[i].m_duration; // qDebug() << itemData << Qt::endl; wi->setData(Qt::UserRole + 1, itemData); ui->listWidgetModds->addItem(wi);