diff --git a/model/syncthingicons.cpp b/model/syncthingicons.cpp index 339cfde..a8498b2 100644 --- a/model/syncthingicons.cpp +++ b/model/syncthingicons.cpp @@ -8,10 +8,28 @@ namespace Data { /*! - * \brief Generates the SVG code for the Syncthing icon with the specified colors and status emblem. + * \brief Generates the SVG code for the Syncthing icon with the specified \a colors and status emblem. */ -QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem statusEmblem) +QByteArray makeSyncthingIcon(const StatusIconColorSet &colors, StatusEmblem statusEmblem) { + // serialize colors + auto gradientStartColor = colors.backgroundStart.name(QColor::HexRgb); + auto gradientEndColor = colors.backgroundEnd.name(QColor::HexRgb); + if (colors.backgroundStart.alphaF() < 1.0) { + gradientStartColor += QStringLiteral(";stop-opacity:") + QString::number(colors.backgroundStart.alphaF()); + } + if (colors.backgroundEnd.alphaF() < 1.0) { + gradientEndColor += QStringLiteral(";stop-opacity:") + QString::number(colors.backgroundEnd.alphaF()); + } + auto fillColor = colors.foreground.name(QColor::HexRgb); + auto strokeColor = fillColor; + if (colors.foreground.alphaF() < 1.0) { + const auto alpha = QString::number(colors.foreground.alphaF()); + fillColor += QStringLiteral(";fill-opacity:") + alpha; + strokeColor += QStringLiteral(";stroke-opacity:") + alpha; + } + + // make SVG document // clang-format off static const QString emblems[] = { QString(), @@ -60,21 +78,13 @@ QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem st ), }; const auto &emblemData = emblems[static_cast(statusEmblem)]; - auto gradientStart = gradientColor.start.name(QColor::HexRgb); - auto gradientEnd = gradientColor.end.name(QColor::HexRgb); - if (gradientColor.start.alphaF() < 1.0) { - gradientStart += QStringLiteral(";stop-opacity:") + QString::number(gradientColor.start.alphaF()); - } - if (gradientColor.end.alphaF() < 1.0) { - gradientEnd += QStringLiteral(";stop-opacity:") + QString::number(gradientColor.end.alphaF()); - } return (QStringLiteral( "" "" "" "" - "" - "" + "" + "" "" "" "" @@ -85,14 +95,14 @@ QByteArray makeSyncthingIcon(const GradientColor &gradientColor, StatusEmblem st "" "" "" - "" - "" - "" - "" - "" - "" - "" - "" + "" + "" + "" + "" + "" + "" + "" + "" "") % (emblemData.isEmpty() ? QString() : emblemData) % QStringLiteral( "" @@ -165,14 +175,14 @@ QByteArray loadFontAwesomeIcon(const QString &iconName, const QColor &color, boo } StatusIconSettings::StatusIconSettings() - : defaultColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") }) - , errorColor({ QStringLiteral("#DB3C26"), QStringLiteral("#C80828") }) - , warningColor({ QStringLiteral("#c9ce3b"), QStringLiteral("#ebb83b") }) - , idleColor({ QStringLiteral("#2D9D69"), QStringLiteral("#2D9D69") }) - , scanningColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") }) - , synchronizingColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") }) - , pausedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C") }) - , disconnectedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C") }) + : defaultColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") }) + , errorColor({ QStringLiteral("#DB3C26"), QStringLiteral("#C80828"), QStringLiteral("#FFFFFF") }) + , warningColor({ QStringLiteral("#c9ce3b"), QStringLiteral("#ebb83b"), QStringLiteral("#FFFFFF") }) + , idleColor({ QStringLiteral("#2D9D69"), QStringLiteral("#2D9D69"), QStringLiteral("#FFFFFF") }) + , scanningColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") }) + , synchronizingColor({ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") }) + , pausedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C"), QStringLiteral("#FFFFFF") }) + , disconnectedColor({ QStringLiteral("#A9A9A9"), QStringLiteral("#58656C"), QStringLiteral("#FFFFFF") }) { } @@ -202,8 +212,11 @@ StatusIconSettings::StatusIconSettings(const QString &str) } const auto colors = parts[index].split(QChar(',')); if (colors.size() >= 2) { - field->start = colors[0].toString(); - field->end = colors[1].toString(); + field->backgroundStart = colors[0].toString(); + field->backgroundEnd = colors[1].toString(); + } + if (colors.size() >= 3) { + field->foreground = colors[2].toString(); } ++index; } @@ -218,7 +231,8 @@ QString StatusIconSettings::toString() const if (!res.isEmpty()) { res += QChar(';'); } - res += field->start.name(QColor::HexArgb) % QChar(',') % field->end.name(QColor::HexArgb); + res += field->backgroundStart.name(QColor::HexArgb) % QChar(',') % field->backgroundEnd.name(QColor::HexArgb) % QChar(',') + % field->foreground.name(QColor::HexArgb); } return res; } diff --git a/model/syncthingicons.h b/model/syncthingicons.h index 43213e7..e8d9561 100644 --- a/model/syncthingicons.h +++ b/model/syncthingicons.h @@ -22,35 +22,39 @@ enum class StatusEmblem { Add, }; -struct GradientColor { - GradientColor(const QColor &start, const QColor &end); - GradientColor(QColor &&start, QColor &&end); - GradientColor(const QString &start, const QString &end); +struct StatusIconColorSet { + StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground); + StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground); + StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground); - QColor start; - QColor end; + QColor backgroundStart; + QColor backgroundEnd; + QColor foreground; }; -inline GradientColor::GradientColor(const QColor &start, const QColor &end) - : start(start) - , end(end) +inline StatusIconColorSet::StatusIconColorSet(const QColor &backgroundStart, const QColor &backgroundEnd, const QColor &foreground) + : backgroundStart(backgroundStart) + , backgroundEnd(backgroundEnd) + , foreground(foreground) { } -inline GradientColor::GradientColor(QColor &&start, QColor &&end) - : start(start) - , end(end) +inline StatusIconColorSet::StatusIconColorSet(QColor &&backgroundStart, QColor &&backgroundEnd, QColor &&foreground) + : backgroundStart(backgroundStart) + , backgroundEnd(backgroundEnd) + , foreground(foreground) { } -inline GradientColor::GradientColor(const QString &start, const QString &end) - : start(start) - , end(end) +inline StatusIconColorSet::StatusIconColorSet(const QString &backgroundStart, const QString &backgroundEnd, const QString &foreground) + : backgroundStart(backgroundStart) + , backgroundEnd(backgroundEnd) + , foreground(foreground) { } QByteArray LIB_SYNCTHING_MODEL_EXPORT makeSyncthingIcon( - const GradientColor &gradientColor = GradientColor{ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8") }, + const StatusIconColorSet &colors = StatusIconColorSet{ QStringLiteral("#26B6DB"), QStringLiteral("#0882C8"), QStringLiteral("#FFFFFF") }, StatusEmblem statusEmblem = StatusEmblem::None); QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QString &path, const QSize &size = QSize(128, 128), int margin = 0); QPixmap LIB_SYNCTHING_MODEL_EXPORT renderSvgImage(const QByteArray &contents, const QSize &size = QSize(128, 128), int margin = 0); @@ -60,21 +64,21 @@ struct LIB_SYNCTHING_MODEL_EXPORT StatusIconSettings { explicit StatusIconSettings(); explicit StatusIconSettings(const QString &str); - GradientColor defaultColor; - GradientColor errorColor; - GradientColor warningColor; - GradientColor idleColor; - GradientColor scanningColor; - GradientColor synchronizingColor; - GradientColor pausedColor; - GradientColor disconnectedColor; + StatusIconColorSet defaultColor; + StatusIconColorSet errorColor; + StatusIconColorSet warningColor; + StatusIconColorSet idleColor; + StatusIconColorSet scanningColor; + StatusIconColorSet synchronizingColor; + StatusIconColorSet pausedColor; + StatusIconColorSet disconnectedColor; static constexpr auto distinguishableColorCount = 8; struct ColorMapping { QString colorName; StatusEmblem defaultEmblem; - GradientColor &setting; + StatusIconColorSet &setting; }; std::vector colorMapping(); QString toString() const; diff --git a/widgets/settings/iconsoptionpage.ui b/widgets/settings/iconsoptionpage.ui index efde843..c032457 100644 --- a/widgets/settings/iconsoptionpage.ui +++ b/widgets/settings/iconsoptionpage.ui @@ -2,14 +2,6 @@ QtGui::IconsOptionPage - - - 0 - 0 - 538 - 167 - - Icons @@ -19,17 +11,17 @@ - + - Status colors + Status icons - + - Color 1 + Background color 1 Qt::AlignCenter @@ -37,16 +29,16 @@ - + - Color 2 + Background color 2 Qt::AlignCenter - + Preview @@ -59,6 +51,16 @@ + + + + Foreground color + + + Qt::AlignCenter + + + diff --git a/widgets/settings/settingsdialog.cpp b/widgets/settings/settingsdialog.cpp index 543bb17..3e89c50 100644 --- a/widgets/settings/settingsdialog.cpp +++ b/widgets/settings/settingsdialog.cpp @@ -508,40 +508,47 @@ QWidget *IconsOptionPage::setupWidget() // populate form for status icon colors auto *const gridLayout = ui()->gridLayout; - auto *const statusColorsGroupBox = ui()->statusColorsGroupBox; + auto *const statusIconsGroupBox = ui()->statusIconsGroupBox; int index = 0; for (auto &colorMapping : m_settings.colorMapping()) { // populate widgets array auto &widgetsForColor = m_widgets[index++] = { { - new Widgets::ColorButton(statusColorsGroupBox), - new Widgets::ColorButton(statusColorsGroupBox), + new Widgets::ColorButton(statusIconsGroupBox), + new Widgets::ColorButton(statusIconsGroupBox), + new Widgets::ColorButton(statusIconsGroupBox), }, - new QLabel(statusColorsGroupBox), + new QLabel(statusIconsGroupBox), &colorMapping.setting, colorMapping.defaultEmblem, }; // add label for color name - gridLayout->addWidget(new QLabel(colorMapping.colorName, statusColorsGroupBox), index, 0, Qt::AlignRight | Qt::AlignVCenter); + gridLayout->addWidget(new QLabel(colorMapping.colorName, statusIconsGroupBox), index, 0, Qt::AlignRight | Qt::AlignVCenter); // setup preview - gridLayout->addWidget(widgetsForColor.previewLabel, index, 3, Qt::AlignCenter); + gridLayout->addWidget(widgetsForColor.previewLabel, index, 4, Qt::AlignCenter); const auto updatePreview = [&widgetsForColor] { - widgetsForColor.previewLabel->setPixmap( - renderSvgImage(makeSyncthingIcon(GradientColor{ widgetsForColor.colorButtons[0]->color(), widgetsForColor.colorButtons[1]->color() }, - widgetsForColor.statusEmblem), - QSize(32, 32))); + widgetsForColor.previewLabel->setPixmap(renderSvgImage(makeSyncthingIcon( + StatusIconColorSet{ + widgetsForColor.colorButtons[0]->color(), + widgetsForColor.colorButtons[1]->color(), + widgetsForColor.colorButtons[2]->color(), + }, + widgetsForColor.statusEmblem), + QSize(32, 32))); }; for (const auto &colorButton : widgetsForColor.colorButtons) { QObject::connect(colorButton, &Widgets::ColorButton::colorChanged, updatePreview); } // setup color buttons - widgetsForColor.colorButtons[0]->setColor(colorMapping.setting.start); - widgetsForColor.colorButtons[1]->setColor(colorMapping.setting.end); + widgetsForColor.colorButtons[0]->setColor(colorMapping.setting.backgroundStart); + widgetsForColor.colorButtons[1]->setColor(colorMapping.setting.backgroundEnd); + widgetsForColor.colorButtons[2]->setColor(colorMapping.setting.foreground); gridLayout->addWidget(widgetsForColor.colorButtons[0], index, 1); gridLayout->addWidget(widgetsForColor.colorButtons[1], index, 2); + gridLayout->addWidget(widgetsForColor.colorButtons[2], index, 3); if (index >= StatusIconSettings::distinguishableColorCount) { break; @@ -561,7 +568,11 @@ QWidget *IconsOptionPage::setupWidget() bool IconsOptionPage::apply() { for (auto &widgetsForColor : m_widgets) { - *widgetsForColor.setting = GradientColor{ widgetsForColor.colorButtons[0]->color(), widgetsForColor.colorButtons[1]->color() }; + *widgetsForColor.setting = StatusIconColorSet{ + widgetsForColor.colorButtons[0]->color(), + widgetsForColor.colorButtons[1]->color(), + widgetsForColor.colorButtons[2]->color(), + }; } values().statusIcons = m_settings; return true; @@ -570,8 +581,9 @@ bool IconsOptionPage::apply() void IconsOptionPage::update() { for (auto &widgetsForColor : m_widgets) { - widgetsForColor.colorButtons[0]->setColor(widgetsForColor.setting->start); - widgetsForColor.colorButtons[1]->setColor(widgetsForColor.setting->end); + widgetsForColor.colorButtons[0]->setColor(widgetsForColor.setting->backgroundStart); + widgetsForColor.colorButtons[1]->setColor(widgetsForColor.setting->backgroundEnd); + widgetsForColor.colorButtons[2]->setColor(widgetsForColor.setting->foreground); } } diff --git a/widgets/settings/settingsdialog.h b/widgets/settings/settingsdialog.h index 30c2b99..055c437 100644 --- a/widgets/settings/settingsdialog.h +++ b/widgets/settings/settingsdialog.h @@ -84,9 +84,9 @@ private: void update(); Data::StatusIconSettings m_settings; struct { - Widgets::ColorButton *colorButtons[2] = {}; + Widgets::ColorButton *colorButtons[3] = {}; QLabel *previewLabel = nullptr; - Data::GradientColor *setting = nullptr; + Data::StatusIconColorSet *setting = nullptr; Data::StatusEmblem statusEmblem = Data::StatusEmblem::None; } m_widgets[Data::StatusIconSettings::distinguishableColorCount]; END_DECLARE_OPTION_PAGE