diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-12 07:08:09 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-12 07:08:09 -0500 |
| commit | 755698f1adceef55f52c8e44c9746537885c9bf7 (patch) | |
| tree | 23d1a9fea936805708eeccf2ac2684620565d328 /libs/preview_dds_native/src/ddspreview.cpp | |
| parent | 019870ffd8308d94289d72d45abeb3db39ccde92 (diff) | |
Replace Python plugins with native C++ .so, remove bundled Python (~95MB)
- Add native plugins: form43_checker, script_extender_checker, preview_dds,
basic_games (75 game defs via IPluginProxy pattern with Steam/GOG detection)
- Remove portable Python from Dockerfile and build-inner.sh
- Add Python settings tab with venv support (system python3 + PyQt6)
- Skip loading plugin_python.so when Python disabled (default: off)
- Update pythonrunner.cpp to use venv at ~/.local/share/fluorine/python-venv/
- Preserve real file permissions in FUSE VFS (fixes native executable +x bits)
- Add FUSE_SET_ATTR_MODE handler so chmod works through VFS
- Fix desktop shortcut Exec= to use fluorine-manager launcher, not bare binary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/preview_dds_native/src/ddspreview.cpp')
| -rw-r--r-- | libs/preview_dds_native/src/ddspreview.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/libs/preview_dds_native/src/ddspreview.cpp b/libs/preview_dds_native/src/ddspreview.cpp new file mode 100644 index 0000000..2bb95be --- /dev/null +++ b/libs/preview_dds_native/src/ddspreview.cpp @@ -0,0 +1,126 @@ +#include "ddspreview.h" +#include "ddsfile.h" +#include "ddswidget.h" + +#include <QLabel> +#include <QVBoxLayout> +#include <QWidget> + +using namespace MOBase; + +DDSPreview::DDSPreview() {} + +bool DDSPreview::init(IOrganizer* moInfo) +{ + m_organizer = moInfo; + return true; +} + +QString DDSPreview::name() const +{ + return "DDS Preview (Native)"; +} + +QString DDSPreview::localizedName() const +{ + return tr("DDS Preview (Native)"); +} + +QString DDSPreview::author() const +{ + return "AnyOldName3"; +} + +QString DDSPreview::description() const +{ + return tr("Displays DDS texture files using OpenGL."); +} + +VersionInfo DDSPreview::version() const +{ + return VersionInfo(1, 0, 0, VersionInfo::RELEASE_FINAL); +} + +QList<PluginSetting> DDSPreview::settings() const +{ + return {}; +} + +std::set<QString> DDSPreview::supportedExtensions() const +{ + return {"dds"}; +} + +bool DDSPreview::supportsArchives() const +{ + return true; +} + +QWidget* DDSPreview::genFilePreview(const QString& fileName, + const QSize& maxSize) const +{ + DDSFile dds; + if (!dds.loadFromFile(fileName)) { + QLabel* label = new QLabel(tr("Failed to load DDS file.")); + label->setAlignment(Qt::AlignCenter); + return label; + } + return buildPreview(dds, maxSize); +} + +QWidget* DDSPreview::genDataPreview(const QByteArray& fileData, + const QString& fileName, + const QSize& maxSize) const +{ + DDSFile dds; + if (!dds.loadFromData(fileData)) { + QLabel* label = new QLabel(tr("Failed to load DDS data.")); + label->setAlignment(Qt::AlignCenter); + return label; + } + return buildPreview(dds, maxSize); +} + +QWidget* DDSPreview::buildPreview(DDSFile& dds, const QSize& maxSize) const +{ + QWidget* container = new QWidget(); + QVBoxLayout* layout = new QVBoxLayout(container); + + // Description label + QLabel* descLabel = new QLabel(dds.description()); + descLabel->setAlignment(Qt::AlignCenter); + layout->addWidget(descLabel); + + // OpenGL preview widget — we need to keep the DDSFile alive, so store + // it in the container. We use a shared_ptr stored as a property. + auto* ddsPtr = new DDSFile(std::move(dds)); + DDSWidget* widget = new DDSWidget(*ddsPtr, container); + + // Clean up DDSFile when container is destroyed + QObject::connect(container, &QObject::destroyed, [ddsPtr]() { + delete ddsPtr; + }); + + // Size the widget proportionally + int previewW = maxSize.width(); + int previewH = maxSize.height() - 30; // leave room for label + if (ddsPtr->width() > 0 && ddsPtr->height() > 0) { + float texAspect = + static_cast<float>(ddsPtr->width()) / ddsPtr->height(); + float availAspect = + static_cast<float>(previewW) / std::max(1, previewH); + if (texAspect > availAspect) { + previewH = static_cast<int>(previewW / texAspect); + } else { + previewW = static_cast<int>(previewH * texAspect); + } + } + widget->setMinimumSize(std::min(previewW, static_cast<int>(ddsPtr->width())), + std::min(previewH, static_cast<int>(ddsPtr->height()))); + widget->setMaximumSize(previewW, previewH); + + layout->addWidget(widget); + container->setLayout(layout); + + return container; +} |
