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

View File

@@ -33,6 +33,8 @@ add_library(
ShaderToySearchModel.cpp
ShaderToyAPI.h
PexelsAPI.h
KomplexSearchModel.h
KomplexSearchModel.cpp
)
qt_add_qml_module(
@@ -66,6 +68,8 @@ qt_add_qml_module(
ShaderToySearchModel.cpp
ShaderToyAPI.h
PexelsAPI.h
KomplexSearchModel.h
KomplexSearchModel.cpp
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 "ShaderToySearchModel.h"
#include "GeometryProvider.h"
#include "KomplexSearchModel.h"
#include "Komplex_global.h"
AudioModel *komplexAudioSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -47,6 +48,7 @@ public:
qmlRegisterType<ShaderToySearchModel>(uri, 1, 0, "ShaderToySearchModel");
qmlRegisterType<PexelsVideoSearchModel>(uri, 1, 0, "PexelsVideoSearchModel");
qmlRegisterType<PexelsImageSearchModel>(uri, 1, 0, "PexelsImageSearchModel");
qmlRegisterType<KomplexSearchModel>(uri, 1, 0, "KomplexSearchModel");
}
void unregisterTypes() override

View File

@@ -1,8 +1,8 @@
{
"Id" : "komplex",
"Name" : "Komplex Wallpaper Plugin",
"Version" : "1.0.0",
"CompatVersion" : "1.0.0",
"Version" : "1.0.7",
"CompatVersion" : "1.0.7",
"VendorId" : "digitalartifex",
"Vendor" : "Digital Artifex",
"Copyright" : "(C) 2025 Digital Artifex",
@@ -13,6 +13,6 @@
"Description" : [
"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",
"DocumentationUrl" : "http://www.github.com/digitalartifex/komplex/wiki"
"Url" : "https://github.com/DigitalArtifex/kde-komplex-wallpaper-engine",
"DocumentationUrl" : "https://github.com/DigitalArtifex/kde-komplex-wallpaper-engine/wiki"
}

View File

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