aboutsummaryrefslogtreecommitdiff
path: root/libs/preview_dds_native/src/ddspreview.cpp
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-12 07:08:09 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-12 07:08:09 -0500
commit755698f1adceef55f52c8e44c9746537885c9bf7 (patch)
tree23d1a9fea936805708eeccf2ac2684620565d328 /libs/preview_dds_native/src/ddspreview.cpp
parent019870ffd8308d94289d72d45abeb3db39ccde92 (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.cpp126
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;
+}