Add experimental theme override

See https://github.com/Martchus/syncthingtray/issues/121
This commit is contained in:
Martchus 2022-09-18 15:26:21 +02:00
parent 65b3838b81
commit 855b3af38b
2 changed files with 55 additions and 10 deletions

View File

@ -4,6 +4,8 @@
#include <QFontDatabase>
#include <QGuiApplication>
#include <QHash>
#include <QIcon>
#include <QPainter>
/// \brief Contains classes provided by the QtForkAwesome library.
@ -17,6 +19,7 @@ struct Renderer::InternalData {
int id;
QStringList fontFamilies;
QHash<QChar, QString> themeOverrides;
};
Renderer::InternalData::InternalData(int id)
@ -69,15 +72,9 @@ Renderer::operator bool() const
return !m_d->fontFamilies.empty();
}
/*!
* \brief Renders the specified \a icon using the specified \a painter.
*/
void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
/// \cond
static void renderInternally(QChar character, QPainter *painter, QFont &&font, const QRect &rect, const QColor &color)
{
if (!*this) {
return;
}
auto font = QFont(m_d->fontFamilies.front());
font.setPixelSize(rect.height());
painter->save();
painter->setFont(font);
@ -85,12 +82,39 @@ void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const Q
painter->drawText(rect, QString(character), QTextOption(Qt::AlignCenter));
painter->restore();
}
/// \endcond
/*!
* \brief Renders the specified \a icon using the specified \a painter.
*/
void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
{
auto themeOverride = m_d->themeOverrides.find(character);
if (themeOverride != m_d->themeOverrides.end()) {
const auto icon = QIcon::fromTheme(*themeOverride);
if (!icon.isNull()) {
painter->drawPixmap(rect, icon.pixmap(rect.size(), QIcon::Normal, QIcon::On));
return;
}
}
if (*this) {
renderInternally(character, painter, QFont(m_d->fontFamilies.front()), rect, color);
}
}
/*!
* \brief Renders the specified \a character as pixmap of the specified \a size.
*/
QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QColor &color) const
{
auto themeOverride = m_d->themeOverrides.find(icon);
if (themeOverride != m_d->themeOverrides.end()) {
const auto icon = QIcon::fromTheme(*themeOverride);
if (!icon.isNull()) {
return icon.pixmap(size, QIcon::Normal, QIcon::On);
}
}
const auto scaleFactor =
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
!QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1.0 :
@ -99,8 +123,10 @@ QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QCo
const auto scaledSize = QSize(size * scaleFactor);
auto pm = QPixmap(scaledSize);
pm.fill(QColor(Qt::transparent));
auto painter = QPainter(&pm);
render(icon, &painter, QRect(QPoint(), scaledSize), color);
if (*this) {
auto painter = QPainter(&pm);
renderInternally(icon, &painter, QFont(m_d->fontFamilies.front()), QRect(QPoint(), scaledSize), color);
}
pm.setDevicePixelRatio(scaleFactor);
return pm;
}
@ -113,6 +139,14 @@ QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color) cons
return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color);
}
/*!
* \brief Uses the icon from the current icon theme obtained via QIcon::fromTheme() for \a character if it exists.
*/
void Renderer::addThemeOverride(QChar character, const QString &iconNameInTheme)
{
m_d->themeOverrides.insert(character, iconNameInTheme);
}
/*!
* \brief Returns the global instance (which is so far only used by the icon engine plugin).
*/

View File

@ -33,6 +33,9 @@ public:
QPixmap pixmap(QChar icon, const QSize &size, const QColor &color) const;
QPixmap pixmap(Icon icon, const QSize &size, const QColor &color) const;
void addThemeOverride(QChar character, const QString &iconNameInTheme);
void addThemeOverride(Icon icon, const QString &iconNameInTheme);
static Renderer &global();
private:
@ -47,6 +50,14 @@ inline void Renderer::render(Icon icon, QPainter *painter, const QRect &rect, co
render(QChar(static_cast<IconBaseType>(icon)), painter, rect, color);
}
/*!
* \brief Uses the icon from the current icon theme obtained via QIcon::fromTheme() for \a icon if it exists.
*/
inline void Renderer::addThemeOverride(Icon icon, const QString &iconNameInTheme)
{
addThemeOverride(QChar(static_cast<IconBaseType>(icon)), iconNameInTheme);
}
} // namespace QtForkAwesome
#endif // QT_FORK_AWESOME_RENDERER