core/icon: ability to specify a fallback or check if an icon exists

This commit is contained in:
outfoxxed 2024-11-17 14:38:29 -08:00
parent d2667369e1
commit 68ba5005ce
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
4 changed files with 42 additions and 4 deletions

View file

@ -11,7 +11,9 @@
QPixmap QPixmap
IconImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) { IconImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
QString iconName; QString iconName;
QString fallbackName;
QString path; QString path;
auto splitIdx = id.indexOf("?path="); auto splitIdx = id.indexOf("?path=");
if (splitIdx != -1) { if (splitIdx != -1) {
iconName = id.sliced(0, splitIdx); iconName = id.sliced(0, splitIdx);
@ -19,10 +21,17 @@ IconImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& re
qWarning() << "Searching custom icon paths is not yet supported. Icon path will be ignored for" qWarning() << "Searching custom icon paths is not yet supported. Icon path will be ignored for"
<< id; << id;
} else { } else {
iconName = id; splitIdx = id.indexOf("?fallback=");
if (splitIdx != -1) {
iconName = id.sliced(0, splitIdx);
fallbackName = id.sliced(splitIdx + 10);
} else {
iconName = id;
}
} }
auto icon = QIcon::fromTheme(iconName); auto icon = QIcon::fromTheme(iconName);
if (icon.isNull()) icon = QIcon::fromTheme(fallbackName);
auto targetSize = requestedSize.isValid() ? requestedSize : QSize(100, 100); auto targetSize = requestedSize.isValid() ? requestedSize : QSize(100, 100);
if (targetSize.width() == 0 || targetSize.height() == 0) targetSize = QSize(2, 2); if (targetSize.width() == 0 || targetSize.height() == 0) targetSize = QSize(2, 2);
@ -55,12 +64,20 @@ QPixmap IconImageProvider::missingPixmap(const QSize& size) {
return pixmap; return pixmap;
} }
QString IconImageProvider::requestString(const QString& icon, const QString& path) { QString IconImageProvider::requestString(
const QString& icon,
const QString& path,
const QString& fallback
) {
auto req = "image://icon/" + icon; auto req = "image://icon/" + icon;
if (!path.isEmpty()) { if (!path.isEmpty()) {
req += "?path=" + path; req += "?path=" + path;
} }
if (!fallback.isEmpty()) {
req += "?fallback=" + fallback;
}
return req; return req;
} }

View file

@ -10,5 +10,10 @@ public:
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override; QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
static QPixmap missingPixmap(const QSize& size); static QPixmap missingPixmap(const QSize& size);
static QString requestString(const QString& icon, const QString& path);
static QString requestString(
const QString& icon,
const QString& path = QString(),
const QString& fallback = QString()
);
}; };

View file

@ -5,6 +5,7 @@
#include <qcoreapplication.h> #include <qcoreapplication.h>
#include <qdir.h> #include <qdir.h>
#include <qguiapplication.h> #include <qguiapplication.h>
#include <qicon.h>
#include <qjsengine.h> #include <qjsengine.h>
#include <qlogging.h> #include <qlogging.h>
#include <qobject.h> #include <qobject.h>
@ -196,7 +197,16 @@ QVariant QuickshellGlobal::env(const QString& variable) { // NOLINT
} }
QString QuickshellGlobal::iconPath(const QString& icon) { QString QuickshellGlobal::iconPath(const QString& icon) {
return IconImageProvider::requestString(icon, ""); return IconImageProvider::requestString(icon);
}
QString QuickshellGlobal::iconPath(const QString& icon, bool check) {
if (check && QIcon::fromTheme(icon).isNull()) return "";
return IconImageProvider::requestString(icon);
}
QString QuickshellGlobal::iconPath(const QString& icon, const QString& fallback) {
return IconImageProvider::requestString(icon, "", fallback);
} }
QuickshellGlobal* QuickshellGlobal::create(QQmlEngine* engine, QJSEngine* /*unused*/) { QuickshellGlobal* QuickshellGlobal::create(QQmlEngine* engine, QJSEngine* /*unused*/) {

View file

@ -137,6 +137,12 @@ public:
/// > at the top of your root config file or set the `QS_ICON_THEME` variable to the name /// > at the top of your root config file or set the `QS_ICON_THEME` variable to the name
/// > of your icon theme. /// > of your icon theme.
Q_INVOKABLE static QString iconPath(const QString& icon); Q_INVOKABLE static QString iconPath(const QString& icon);
/// Setting the `check` parameter of `iconPath` to true will return an empty string
/// if the icon does not exist, instead of an image showing a missing texture.
Q_INVOKABLE static QString iconPath(const QString& icon, bool check);
/// Setting the `fallback` parameter of `iconPath` will attempt to load the fallback
/// icon if the requested one could not be loaded.
Q_INVOKABLE static QString iconPath(const QString& icon, const QString& fallback);
[[nodiscard]] QString shellRoot() const; [[nodiscard]] QString shellRoot() const;