Added custom API backend to replace ShaderToy. Fixes #4

This commit is contained in:
Digital Artifex
2025-11-04 05:24:26 -05:00
parent c3c239cd09
commit 9303dbf589
7 changed files with 1512 additions and 15 deletions

View File

@@ -16,7 +16,7 @@ Item
signal accepted signal accepted
Komplex.ShaderToySearchModel Komplex.KomplexSearchModel
{ {
id: searchModel id: searchModel
} }
@@ -174,6 +174,18 @@ Item
} }
} }
RowLayout
{
width: thumbnailImage.width
Text
{
color: palette.text
anchors.fill: parent
text: model.name
}
}
RowLayout RowLayout
{ {
visible: parent.itemIndex === view.currentIndex visible: parent.itemIndex === view.currentIndex
@@ -245,7 +257,7 @@ Item
onClicked: () => onClicked: () =>
{ {
workingThumbnail.source = model.thumbnail workingThumbnail.source = model.thumbnail
searchModel.convert(model.index); searchModel.download(model.index);
downloadDialog.close(); downloadDialog.close();
} }
} }
@@ -333,7 +345,7 @@ Item
width: mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height
visible: searchModel.status === Komplex.ShaderToySearchModel.Searching || searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.status === Komplex.KomplexSearchModel.Searching || searchModel.status === Komplex.KomplexSearchModel.Compiling
RowLayout RowLayout
{ {
@@ -341,7 +353,7 @@ Item
Image Image
{ {
visible: searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.status === Komplex.KomplexSearchModel.Compiling
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@@ -355,7 +367,7 @@ Item
text: searchModel.statusMessage text: searchModel.statusMessage
color: palette.text color: palette.text
elide: Text.ElideRight elide: Text.ElideRight
visible: searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.status === Komplex.KomplexSearchModel.Compiling
} }
ProgressBar ProgressBar
@@ -363,7 +375,7 @@ Item
id: totalProgress id: totalProgress
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 6 Layout.preferredHeight: 6
visible: searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.status === Komplex.KomplexSearchModel.Compiling
} }
Text Text
@@ -372,7 +384,7 @@ Item
text: qsTr(searchModel.downloadText) text: qsTr(searchModel.downloadText)
color: palette.text color: palette.text
elide: Text.ElideRight elide: Text.ElideRight
visible: searchModel.totalDownloads > 0 && searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.totalDownloads > 0 && searchModel.status === Komplex.KomplexSearchModel.Compiling
} }
ProgressBar ProgressBar
@@ -383,7 +395,7 @@ Item
from: 0 from: 0
to: searchModel.totalDownloads to: searchModel.totalDownloads
value: searchModel.completedDownloads value: searchModel.completedDownloads
visible: searchModel.totalDownloads > 0 && searchModel.status === Komplex.ShaderToySearchModel.Compiling visible: searchModel.totalDownloads > 0 && searchModel.status === Komplex.KomplexSearchModel.Compiling
} }
} }
@@ -419,7 +431,7 @@ Item
function onStatusChanged() function onStatusChanged()
{ {
if(searchModel.status === Komplex.ShaderToySearchModel.Compiled) if(searchModel.status === Komplex.KomplexSearchModel.Compiled)
mediaSelectionItem.open() mediaSelectionItem.open()
} }
} }
@@ -586,7 +598,7 @@ Item
{ {
console.log("Search Model Status " + searchModel.status) console.log("Search Model Status " + searchModel.status)
if(searchModel.status === Komplex.ShaderToySearchModel.Error) if(searchModel.status === Komplex.KomplexSearchModel.Error)
{ {
warningDialog.open(); warningDialog.open();
} }

View File

@@ -33,6 +33,8 @@ add_library(
ShaderToySearchModel.cpp ShaderToySearchModel.cpp
ShaderToyAPI.h ShaderToyAPI.h
PexelsAPI.h PexelsAPI.h
KomplexSearchModel.h
KomplexSearchModel.cpp
) )
qt_add_qml_module( qt_add_qml_module(
@@ -66,6 +68,8 @@ qt_add_qml_module(
ShaderToySearchModel.cpp ShaderToySearchModel.cpp
ShaderToyAPI.h ShaderToyAPI.h
PexelsAPI.h PexelsAPI.h
KomplexSearchModel.h
KomplexSearchModel.cpp
NO_GENERATE_PLUGIN_SOURCE NO_GENERATE_PLUGIN_SOURCE
) )

File diff suppressed because it is too large Load Diff

274
plugin/KomplexSearchModel.h Normal file
View File

@@ -0,0 +1,274 @@
#ifndef KomplexSearchModel_H
#define KomplexSearchModel_H
#include <QObject>
#include <QCache>
#include <QStandardPaths>
#include <QQuickImageProvider>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QAbstractItemModel>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QThread>
#include <QFile>
#include "ShaderToyMetadata.h"
#include "Komplex_global.h"
class KOMPLEX_EXPORT KomplexSearchModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum DataRoles
{
Date = Qt::UserRole + 1,
Description,
EmbedUrl,
Flags,
HasLiked,
Id,
Likes,
Name,
Published,
State,
Tags,
Thumbnail,
UsePreview,
Username,
Version,
Views
};
Q_ENUM(DataRoles)
enum Status
{
Idle,
Loading,
Searching,
Compiling,
Compiled,
Finalizing,
Error
};
Q_ENUM(Status)
KomplexSearchModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QString lastSavedFile() const;
void setLastSavedFile(const QString &lastSavedFile);
Status status() const;
void setStatus(const Status &status, const QString &message = QString());
QString query() const;
void setQuery(const QString &query);
quint64 resultsPerPage() const;
void setResultsPerPage(quint64 resultsPerPage);
quint64 totalResults() const;
void setTotalResults(quint64 totalResults);
quint64 currentPage() const;
void setCurrentPage(quint64 currentPage);
quint64 totalPages() const;
void setTotalPages(quint64 totalPages);
Q_INVOKABLE void next();
Q_INVOKABLE void previous();
Q_INVOKABLE void convert(qsizetype index);
Q_INVOKABLE ShaderToyEntry entry(qsizetype index);
Q_INVOKABLE void finalize(qsizetype index);
Q_INVOKABLE void replaceSource(qsizetype index, QString uuid, QString source);
QString compilerOutput() const;
void setCompilerOutput(const QString &compilerOutput);
QString compilerErrorOutput() const;
void setCompilerErrorOutput(const QString &compilerErrorOutput);
quint64 totalDownloads() const;
void setTotalDownloads(quint64 totalDownloads);
quint64 completedDownloads() const;
void setCompletedDownloads(quint64 completedDownloads);
QString downloadText() const;
void setDownloadText(const QString &downloadText);
QString statusMessage() const;
void setStatusMessage(const QString &statusMessage);
QStringList videoSelections() const;
void setVideoSelections(const QStringList &videoSelections);
Q_INVOKABLE void download(quint64 index);
Q_SIGNALS:
void shaderInstalled();
void lastSavedFileChanged();
void statusChanged();
void queryChanged();
void resultsPerPageChanged();
void totalResultsChanged();
void currentPageChanged();
void totalPagesChanged();
void compilerOutputChanged();
void compilerErrorOutputChanged();
void totalDownloadsChanged();
void completedDownloadsChanged();
void downloadTextChanged();
void statusMessageChanged();
void videoSelectionsChanged();
protected:
QHash<int, QByteArray> roleNames() const override;
private:
void downloadMedia(QString fileLocation, QString fileUrl);
void compile(quint64 index);
void save(quint64 index);
void install(quint64 index);
void resetModel();
void getSearchResults(QString url);
quint64 getFileSize(QUrl url);
QString sizeText(quint64 size);
QNetworkAccessManager m_networkManager;
QString m_query;
QList<ShaderToyEntry> m_data;
QString m_lastSavedFile;
qreal m_downloadProgress = 0;
Status m_status = Status::Idle;
quint64 m_resultsPerPage = 12;
quint64 m_totalResults = 0;
quint64 m_currentPage = 0;
quint64 m_totalPages = 0;
QString m_compilerOutput;
QString m_compilerErrorOutput;
quint64 m_completedDownloads = 0;
quint64 m_totalDownloads = 0;
QString m_downloadText;
QString m_statusMessage;
QStringList m_videoSelections;
QNetworkAccessManager m_manager;
// multiple possible connections to replaceSource
QMutex m_selectionMutex;
static inline const QHash<int, QByteArray> m_dataRoles =
{
{
static_cast<int>(Date),
QByteArray("date")
},
{
static_cast<int>(Description),
QByteArray("description")
},
{
static_cast<int>(EmbedUrl),
QByteArray("embedUrl")
},
{
static_cast<int>(Flags),
QByteArray("flags")
},
{
static_cast<int>(HasLiked),
QByteArray("hasLiked")
},
{
static_cast<int>(Id),
QByteArray("id")
},
{
static_cast<int>(Likes),
QByteArray("likes")
},
{
static_cast<int>(Name),
QByteArray("name")
},
{
static_cast<int>(Published),
QByteArray("published")
},
{
static_cast<int>(State),
QByteArray("state")
},
{
static_cast<int>(Tags),
QByteArray("tags")
},
{
static_cast<int>(Thumbnail),
QByteArray("thumbnail")
},
{
static_cast<int>(UsePreview),
QByteArray("usePreview")
},
{
static_cast<int>(Username),
QByteArray("username")
},
{
static_cast<int>(Version),
QByteArray("version")
},
{
static_cast<int>(Views),
QByteArray("views")
}
};
const static inline QStringList m_supportedChannelTypes =
{
QStringLiteral("buffer"),
QStringLiteral("image"),
QStringLiteral("video"),
QStringLiteral("audio"),
QStringLiteral("texture")
};
Q_PROPERTY(QString lastSavedFile READ lastSavedFile WRITE setLastSavedFile NOTIFY lastSavedFileChanged FINAL)
Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged FINAL)
Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged FINAL)
Q_PROPERTY(quint64 resultsPerPage READ resultsPerPage WRITE setResultsPerPage NOTIFY resultsPerPageChanged FINAL)
Q_PROPERTY(quint64 totalResults READ totalResults WRITE setTotalResults NOTIFY totalResultsChanged FINAL)
Q_PROPERTY(quint64 currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged FINAL)
Q_PROPERTY(quint64 totalPages READ totalPages WRITE setTotalPages NOTIFY totalPagesChanged FINAL)
Q_PROPERTY(QString compilerOutput READ compilerOutput WRITE setCompilerOutput NOTIFY compilerOutputChanged FINAL)
Q_PROPERTY(QString compilerErrorOutput READ compilerErrorOutput WRITE setCompilerErrorOutput NOTIFY compilerErrorOutputChanged FINAL)
Q_PROPERTY(quint64 totalDownloads READ totalDownloads WRITE setTotalDownloads NOTIFY totalDownloadsChanged FINAL)
Q_PROPERTY(quint64 completedDownloads READ completedDownloads WRITE setCompletedDownloads NOTIFY completedDownloadsChanged FINAL)
Q_PROPERTY(QString downloadText READ downloadText WRITE setDownloadText NOTIFY downloadTextChanged FINAL)
Q_PROPERTY(QString statusMessage READ statusMessage WRITE setStatusMessage NOTIFY statusMessageChanged FINAL)
Q_PROPERTY(QStringList videoSelections READ videoSelections WRITE setVideoSelections NOTIFY videoSelectionsChanged FINAL)
};
Q_DECLARE_METATYPE(KomplexSearchModel)
#endif // KomplexSearchModel_H

View File

@@ -9,6 +9,7 @@
#include "PexelsImageSearch.h" #include "PexelsImageSearch.h"
#include "ShaderToySearchModel.h" #include "ShaderToySearchModel.h"
#include "GeometryProvider.h" #include "GeometryProvider.h"
#include "KomplexSearchModel.h"
#include "Komplex_global.h" #include "Komplex_global.h"
AudioModel *komplexAudioSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine) AudioModel *komplexAudioSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -47,6 +48,7 @@ public:
qmlRegisterType<ShaderToySearchModel>(uri, 1, 0, "ShaderToySearchModel"); qmlRegisterType<ShaderToySearchModel>(uri, 1, 0, "ShaderToySearchModel");
qmlRegisterType<PexelsVideoSearchModel>(uri, 1, 0, "PexelsVideoSearchModel"); qmlRegisterType<PexelsVideoSearchModel>(uri, 1, 0, "PexelsVideoSearchModel");
qmlRegisterType<PexelsImageSearchModel>(uri, 1, 0, "PexelsImageSearchModel"); qmlRegisterType<PexelsImageSearchModel>(uri, 1, 0, "PexelsImageSearchModel");
qmlRegisterType<KomplexSearchModel>(uri, 1, 0, "KomplexSearchModel");
} }
void unregisterTypes() override void unregisterTypes() override

View File

@@ -1,8 +1,8 @@
{ {
"Id" : "komplex", "Id" : "komplex",
"Name" : "Komplex Wallpaper Plugin", "Name" : "Komplex Wallpaper Plugin",
"Version" : "1.0.0", "Version" : "1.0.7",
"CompatVersion" : "1.0.0", "CompatVersion" : "1.0.7",
"VendorId" : "digitalartifex", "VendorId" : "digitalartifex",
"Vendor" : "Digital Artifex", "Vendor" : "Digital Artifex",
"Copyright" : "(C) 2025 Digital Artifex", "Copyright" : "(C) 2025 Digital Artifex",
@@ -13,6 +13,6 @@
"Description" : [ "Description" : [
"This plugin enables functionality for the Komplex wallpaper, allowing users to set and manage complex shader arrangements as wallpapers in their KDE environment." "This plugin enables functionality for the Komplex wallpaper, allowing users to set and manage complex shader arrangements as wallpapers in their KDE environment."
], ],
"Url" : "http://www.github.com/digitalartifex/komplex", "Url" : "https://github.com/DigitalArtifex/kde-komplex-wallpaper-engine",
"DocumentationUrl" : "http://www.github.com/digitalartifex/komplex/wiki" "DocumentationUrl" : "https://github.com/DigitalArtifex/kde-komplex-wallpaper-engine/wiki"
} }

View File

@@ -4,4 +4,5 @@ classname AudioModel
classname ShaderPackModel classname ShaderPackModel
classname PexelsImageSearchModel classname PexelsImageSearchModel
classname PexelsVideoSearchModel classname PexelsVideoSearchModel
classname ShaderToySearchModel classname ShaderToySearchModel
classname KomplexSearchModel