Render font awesome icons in color from QPalette

Since theres apparently no API in the Qt Svg module to support
this the change introduced here simply replaces in the SVG
document itself.
This commit is contained in:
Martchus 2019-02-23 13:55:46 +01:00
parent 78d4553104
commit a3a09297f7
6 changed files with 88 additions and 13 deletions

View File

@ -1,10 +1,26 @@
#include "./syncthingicons.h"
#include <QFile>
#include <QPainter>
#include <QStringBuilder>
#include <QSvgRenderer>
namespace Data {
/// \cond
namespace Detail {
template <typename SourceType> QPixmap renderSvgImage(const SourceType &source, const QSize &size)
{
QSvgRenderer renderer(source);
QPixmap pm(size);
pm.fill(QColor(Qt::transparent));
QPainter painter(&pm);
renderer.render(&painter, pm.rect());
return pm;
}
} // namespace Detail
/// \endcond
/*!
* \brief Renders an SVG image to a QPixmap.
* \remarks If instantiating QIcon directly from SVG image the icon is not displayed in the tray under Plasma 5. It works
@ -12,12 +28,30 @@ namespace Data {
*/
QPixmap renderSvgImage(const QString &path, const QSize &size)
{
QSvgRenderer renderer(path);
QPixmap pm(size);
pm.fill(QColor(Qt::transparent));
QPainter painter(&pm);
renderer.render(&painter, pm.rect());
return pm;
return Detail::renderSvgImage(path, size);
}
/*!
* \brief Renders an SVG image to a QPixmap.
*/
QPixmap renderSvgImage(const QByteArray &contents, const QSize &size)
{
return Detail::renderSvgImage(contents, size);
}
/*!
* \brief Returns the font awesome icon with the specified \a iconName and \a color.
*/
QByteArray loadFontAwesomeIcon(const QString &iconName, const QColor &color)
{
QByteArray result;
QFile icon(QStringLiteral(":/icons/hicolor/scalable/fa/") % iconName % QStringLiteral(".svg"));
if (!icon.open(QFile::ReadOnly)) {
return result;
}
result = icon.readAll();
result.replace("currentColor", color.name(QColor::HexRgb).toUtf8());
return result;
}
StatusIcons::StatusIcons()

View File

@ -6,9 +6,14 @@
#include <QIcon>
#include <QSize>
QT_FORWARD_DECLARE_CLASS(QColor)
namespace Data {
QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QString &path, const QSize &size = QSize(128, 128));
QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QByteArray &contents, const QSize &size = QSize(128, 128));
QByteArray LIB_SYNCTHING_MODEL_EXPORT loadFontAwesomeIcon(const QString &iconName, const QColor &color);
struct StatusIcons {
StatusIcons();

View File

@ -30,6 +30,7 @@
#include <QDesktopServices>
#include <QGuiApplication>
#include <QNetworkReply>
#include <QPalette>
#include <QQmlEngine>
#include <QStringBuilder>
@ -238,6 +239,11 @@ void SyncthingApplet::updateStatusIconAndTooltip()
emit connectionStatusChanged();
}
QIcon SyncthingApplet::loadFontAwesomeIcon(const QString &name)
{
return Data::renderSvgImage(Data::loadFontAwesomeIcon(name, QGuiApplication::palette().color(QPalette::Foreground)), QSize(16, 13));
}
void SyncthingApplet::showSettingsDlg()
{
if (!m_settingsDlg) {

View File

@ -115,6 +115,7 @@ public Q_SLOTS:
void showDirectoryErrors(unsigned int directoryIndex);
void copyToClipboard(const QString &text);
void updateStatusIconAndTooltip();
QIcon loadFontAwesomeIcon(const QString &name);
Q_SIGNALS:
/// \remarks Never emitted, just to silence "... depends on non-NOTIFYable ..."

View File

@ -449,7 +449,8 @@ ColumnLayout {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
Layout.leftMargin: 10
source: "://icons/hicolor/scalable/fa/cloud-download-alt-solid.svg"
source: plasmoid.nativeInterface.loadFontAwesomeIcon(
"cloud-download-alt-solid")
opacity: plasmoid.nativeInterface.hasIncomingTraffic ? 1.0 : 0.5
}
PlasmaComponents.Label {
@ -469,7 +470,8 @@ ColumnLayout {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
Layout.leftMargin: 10
source: "://icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg"
source: plasmoid.nativeInterface.loadFontAwesomeIcon(
"cloud-upload-alt-solid")
opacity: plasmoid.nativeInterface.hasOutgoingTraffic ? 1.0 : 0.5
}
PlasmaComponents.Label {

View File

@ -7,6 +7,8 @@
#include "../../widgets/settings/settingsdialog.h"
#include "../../widgets/webview/webviewdialog.h"
#include "../../model/syncthingicons.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
#include "../../connector/syncthingservice.h"
#endif
@ -33,7 +35,9 @@
#include <QDesktopServices>
#include <QDir>
#include <QFontDatabase>
#include <QGuiApplication>
#include <QMessageBox>
#include <QPalette>
#include <QStringBuilder>
#include <QTextBrowser>
@ -132,8 +136,7 @@ TrayWidget::TrayWidget(TrayMenu *parent)
QIcon::fromTheme(QStringLiteral("globe"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/globe.svg"))).pixmap(16));
m_ui->localTextLabel->setPixmap(
QIcon::fromTheme(QStringLiteral("user-home"), QIcon(QStringLiteral(":/icons/hicolor/scalable/places/user-home.svg"))).pixmap(16));
m_ui->trafficInTextLabel->setPixmap(QIcon(QStringLiteral(":/icons/hicolor/scalable/fa/cloud-download-alt-solid.svg")).pixmap(16));
m_ui->trafficOutTextLabel->setPixmap(QIcon(QStringLiteral(":/icons/hicolor/scalable/fa/cloud-upload-alt-solid.svg")).pixmap(16));
updateTraffic();
#ifndef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
delete m_ui->startStopPushButton;
#endif
@ -500,11 +503,35 @@ void TrayWidget::updateTraffic()
if (m_ui->trafficFormWidget->isHidden()) {
return;
}
// render traffic icons the first time the function is called
static const auto trafficIcons = [this]() {
const auto size = QSize(16, 13);
const auto &palette = m_ui->trafficFormWidget->palette(); // FIXME: make this aware of palette changes
const auto colorBackground = palette.color(QPalette::Background);
const auto colorActive = palette.color(QPalette::Foreground);
const auto colorInactive = QColor((colorActive.red() + colorBackground.red()) / 2, (colorActive.green() + colorBackground.green()) / 2,
(colorActive.blue() + colorBackground.blue()) / 2);
const auto renderIcon
= [&size](const QString &name, const QColor &color) { return Data::renderSvgImage(Data::loadFontAwesomeIcon(name, color), size); };
struct {
QPixmap uploadIconActive;
QPixmap uploadIconInactive;
QPixmap downloadIconActive;
QPixmap downloadIconInactive;
} icons;
icons.uploadIconActive = renderIcon(QStringLiteral("cloud-upload-alt-solid"), colorActive);
icons.uploadIconInactive = renderIcon(QStringLiteral("cloud-upload-alt-solid"), colorInactive);
icons.downloadIconActive = renderIcon(QStringLiteral("cloud-download-alt-solid"), colorActive);
icons.downloadIconInactive = renderIcon(QStringLiteral("cloud-download-alt-solid"), colorInactive);
return icons;
}();
// update text and whether to use active/inactive icons
m_ui->inTrafficLabel->setText(trafficString(m_connection.totalIncomingTraffic(), m_connection.totalIncomingRate()));
m_ui->outTrafficLabel->setText(trafficString(m_connection.totalOutgoingTraffic(), m_connection.totalOutgoingRate()));
// FIXME: decrease opacity if rate is zero (the following code doesn't work)
//m_ui->trafficInTextLabel->setStyleSheet(m_connection.totalIncomingRate() > 0.0 ? QString() : QStringLiteral("opacity: 0.5;"));
//m_ui->trafficOutTextLabel->setStyleSheet(m_connection.totalOutgoingRate() > 0.0 ? QString() : QStringLiteral("opacity: 0.5;"));
m_ui->trafficInTextLabel->setPixmap(m_connection.totalIncomingRate() > 0.0 ? trafficIcons.downloadIconActive : trafficIcons.downloadIconInactive);
m_ui->trafficOutTextLabel->setPixmap(m_connection.totalOutgoingRate() > 0.0 ? trafficIcons.uploadIconActive : trafficIcons.uploadIconInactive);
}
void TrayWidget::updateOverallStatistics()