From 250f4bf97dd3712e53b7427deef53f3b6cedfe57 Mon Sep 17 00:00:00 2001 From: Martchus Date: Mon, 17 Jun 2024 22:37:34 +0200 Subject: [PATCH] Add option to configure presets with transparent background depending on palette Implements https://github.com/Martchus/syncthingtray/issues/270 --- plasmoid/lib/syncthingapplet.cpp | 2 +- syncthingmodel/syncthingicons.cpp | 44 +++++++++- syncthingmodel/syncthingicons.h | 22 ++--- syncthingwidgets/settings/iconsoptionpage.ui | 89 ++++++++++---------- syncthingwidgets/settings/settings.cpp | 4 + syncthingwidgets/settings/settings.h | 2 + syncthingwidgets/settings/settingsdialog.cpp | 15 ++++ syncthingwidgets/settings/settingsdialog.h | 2 + tray/gui/traywidget.cpp | 4 +- 9 files changed, 120 insertions(+), 64 deletions(-) diff --git a/plasmoid/lib/syncthingapplet.cpp b/plasmoid/lib/syncthingapplet.cpp index a86f90a..f69f5b2 100644 --- a/plasmoid/lib/syncthingapplet.cpp +++ b/plasmoid/lib/syncthingapplet.cpp @@ -683,7 +683,7 @@ void SyncthingApplet::applySettings(int changeConnectionIndex) // apply appearance settings setSize(config.readEntry("size", QSize(25, 25))); setShowingTabTexts(config.readEntry("showTabTexts", false)); - IconManager::instance().applySettings(&settings.icons.status); + IconManager::instance().applySettings(&settings.icons.status, nullptr, settings.icons.usePaletteForStatus, false); // restore selected states // note: The settings dialog writes this to the Plasmoid's config like the other settings. However, it diff --git a/syncthingmodel/syncthingicons.cpp b/syncthingmodel/syncthingicons.cpp index 2cf6429..ad676a6 100644 --- a/syncthingmodel/syncthingicons.cpp +++ b/syncthingmodel/syncthingicons.cpp @@ -6,6 +6,7 @@ #include "resources/../../tray/resources/config.h" #include +#include #include @@ -278,7 +279,7 @@ QString StatusIconSettings::toString() const StatusIcons::StatusIcons(const StatusIconSettings &settings) : disconnected( - QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize))) + QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize))) , idling(QIcon(renderSvgImage(makeSyncthingIcon(settings.idleColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize))) , scanninig(QIcon(renderSvgImage(makeSyncthingIcon(settings.scanningColor, StatusEmblem::Scanning, settings.strokeWidth), settings.renderSize))) , notify(QIcon(renderSvgImage(makeSyncthingIcon(settings.warningColor, StatusEmblem::Alert, settings.strokeWidth), settings.renderSize))) @@ -323,6 +324,9 @@ IconManager::IconManager(const QPalette *palette) , m_trayIcons(m_statusIcons) , m_commonForkAwesomeIcons( m_forkAwesomeRenderer, (palette ? *palette : QGuiApplication::palette()).color(QPalette::Normal, QPalette::Text), QSize(64, 64)) + , m_distinguishTrayIcons(false) + , m_usePaletteForStatus(false) + , m_usePaletteForTray(false) { #ifdef __GNUC__ #pragma GCC diagnostic push @@ -336,8 +340,46 @@ IconManager::IconManager(const QPalette *palette) #endif } +void IconManager::applySettings( + const StatusIconSettings *statusIconSettings, const StatusIconSettings *trayIconSettings, bool usePaletteForStatus, bool usePaletteForTray) +{ + m_distinguishTrayIcons = trayIconSettings != nullptr; + if (usePaletteForStatus || usePaletteForTray) { + m_settingsForPalette = QtUtilities::isPaletteDark(m_palette) ? StatusIconSettings(StatusIconSettings::DarkTheme{}) + : StatusIconSettings(StatusIconSettings::BrightTheme{}); + } + if ((m_usePaletteForStatus = usePaletteForStatus)) { + m_statusIcons = StatusIcons(m_settingsForPalette); + } else if (statusIconSettings) { + m_statusIcons = StatusIcons(*statusIconSettings); + } else { + m_statusIcons = StatusIcons(StatusIconSettings()); + } + if ((m_usePaletteForTray = usePaletteForTray) || (!m_distinguishTrayIcons && usePaletteForStatus)) { + m_trayIcons = m_distinguishTrayIcons ? StatusIcons(m_settingsForPalette) : m_statusIcons; + } else if (trayIconSettings) { + m_trayIcons = StatusIcons(*trayIconSettings); + } else { + m_trayIcons = m_statusIcons; + } + emit statusIconsChanged(m_statusIcons, m_trayIcons); +} + void IconManager::setPalette(const QPalette &palette) { + if (m_usePaletteForStatus || m_usePaletteForTray) { + if (const auto wasDark = QtUtilities::isPaletteDark(m_palette), isDark = QtUtilities::isPaletteDark(palette); wasDark != isDark) { + m_settingsForPalette + = isDark ? StatusIconSettings(StatusIconSettings::DarkTheme{}) : StatusIconSettings(StatusIconSettings::BrightTheme{}); + if (m_usePaletteForStatus) { + m_statusIcons = StatusIcons(m_settingsForPalette); + } + if (m_usePaletteForTray || (!m_distinguishTrayIcons && m_usePaletteForStatus)) { + m_trayIcons = m_distinguishTrayIcons ? StatusIcons(m_settingsForPalette) : m_statusIcons; + } + emit statusIconsChanged(m_statusIcons, m_trayIcons); + } + } m_palette = palette; emit forkAwesomeIconsChanged( m_commonForkAwesomeIcons = ForkAwesomeIcons(m_forkAwesomeRenderer, palette.color(QPalette::Normal, QPalette::Text), QSize(64, 64))); diff --git a/syncthingmodel/syncthingicons.h b/syncthingmodel/syncthingicons.h index f58068e..380e1a0 100644 --- a/syncthingmodel/syncthingicons.h +++ b/syncthingmodel/syncthingicons.h @@ -155,7 +155,8 @@ class LIB_SYNCTHING_MODEL_EXPORT IconManager : public QObject { public: static IconManager &instance(const QPalette *palette = nullptr); - void applySettings(const StatusIconSettings *statusIconSettings = nullptr, const StatusIconSettings *trayIconSettings = nullptr); + void applySettings(const StatusIconSettings *statusIconSettings = nullptr, const StatusIconSettings *trayIconSettings = nullptr, + bool usePaletteForStatus = false, bool usePaletteForTray = false); const StatusIcons &statusIcons() const; const StatusIcons &trayIcons() const; QtForkAwesome::Renderer &forkAwesomeRenderer(); @@ -178,23 +179,12 @@ private: QtForkAwesome::Renderer m_forkAwesomeRenderer; ForkAwesomeIcons m_commonForkAwesomeIcons; QPalette m_palette; + StatusIconSettings m_settingsForPalette; + bool m_distinguishTrayIcons; + bool m_usePaletteForStatus; + bool m_usePaletteForTray; }; -inline void IconManager::applySettings(const StatusIconSettings *statusIconSettings, const StatusIconSettings *trayIconSettings) -{ - if (statusIconSettings) { - m_statusIcons = StatusIcons(*statusIconSettings); - } else { - m_statusIcons = StatusIcons(StatusIconSettings()); - } - if (trayIconSettings) { - m_trayIcons = StatusIcons(*trayIconSettings); - } else { - m_trayIcons = m_statusIcons; - } - emit statusIconsChanged(m_statusIcons, m_trayIcons); -} - inline const StatusIcons &IconManager::statusIcons() const { return m_statusIcons; diff --git a/syncthingwidgets/settings/iconsoptionpage.ui b/syncthingwidgets/settings/iconsoptionpage.ui index f118aa6..ce93132 100644 --- a/syncthingwidgets/settings/iconsoptionpage.ui +++ b/syncthingwidgets/settings/iconsoptionpage.ui @@ -124,51 +124,50 @@ - - - - - Background color 1 - - - Qt::AlignCenter - - - - - - - Background color 2 - - - Qt::AlignCenter - - - - - - - Preview - - - Qt::AlignCenter - - - - - - - - - - Foreground color - - - Qt::AlignCenter - - - - + + + + + + Background color 1 + + + Qt::AlignmentFlag::AlignCenter + + + + + + + Background color 2 + + + Qt::AlignmentFlag::AlignCenter + + + + + + + Foreground color + + + Qt::AlignmentFlag::AlignCenter + + + + + + + Preview + + + Qt::AlignmentFlag::AlignCenter + + + + + diff --git a/syncthingwidgets/settings/settings.cpp b/syncthingwidgets/settings/settings.cpp index 91afe4d..279846c 100644 --- a/syncthingwidgets/settings/settings.cpp +++ b/syncthingwidgets/settings/settings.cpp @@ -372,6 +372,8 @@ bool restore() settings.value(QStringLiteral("trayIconsStrokeWidth"), static_cast(v.icons.tray.strokeWidth)).toInt()); v.icons.distinguishTrayIcons = settings.value(QStringLiteral("distinguishTrayIcons")).toBool(); v.icons.preferIconsFromTheme = settings.value(QStringLiteral("preferIconsFromTheme")).toBool(); + v.icons.usePaletteForStatus = settings.value(QStringLiteral("usePaletteForStatusIcons")).toBool(); + v.icons.usePaletteForTray = settings.value(QStringLiteral("usePaletteForTrayIcons")).toBool(); settings.beginGroup(QStringLiteral("positioning")); auto &positioning = appearance.positioning; positioning.useCursorPosition = settings.value(QStringLiteral("useCursorPos"), positioning.useCursorPosition).toBool(); @@ -508,6 +510,8 @@ bool save() settings.setValue(QStringLiteral("trayIconsStrokeWidth"), static_cast(v.icons.tray.strokeWidth)); settings.setValue(QStringLiteral("distinguishTrayIcons"), v.icons.distinguishTrayIcons); settings.setValue(QStringLiteral("preferIconsFromTheme"), v.icons.preferIconsFromTheme); + settings.setValue(QStringLiteral("usePaletteForStatusIcons"), v.icons.usePaletteForStatus); + settings.setValue(QStringLiteral("usePaletteForTrayIcons"), v.icons.usePaletteForTray); settings.beginGroup(QStringLiteral("positioning")); settings.setValue(QStringLiteral("useCursorPos"), appearance.positioning.useCursorPosition); settings.setValue(QStringLiteral("useAssumedIconPosition"), appearance.positioning.useAssumedIconPosition); diff --git a/syncthingwidgets/settings/settings.h b/syncthingwidgets/settings/settings.h index abe3d71..665ba94 100644 --- a/syncthingwidgets/settings/settings.h +++ b/syncthingwidgets/settings/settings.h @@ -174,6 +174,8 @@ struct SYNCTHINGWIDGETS_EXPORT Settings { Data::StatusIconSettings tray; bool distinguishTrayIcons = false; bool preferIconsFromTheme = false; + bool usePaletteForStatus = false; + bool usePaletteForTray = false; } icons; Launcher launcher; #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD diff --git a/syncthingwidgets/settings/settingsdialog.cpp b/syncthingwidgets/settings/settingsdialog.cpp index 335412b..b6b7836 100644 --- a/syncthingwidgets/settings/settingsdialog.cpp +++ b/syncthingwidgets/settings/settingsdialog.cpp @@ -714,18 +714,25 @@ QWidget *IconsOptionPage::setupWidget() auto *const presetsMenu = new QMenu(widget); presetsMenu->addAction(QCoreApplication::translate("QtGui::IconsOptionPageBase", "Colorful background with gradient (default)"), widget, [this] { m_settings = Data::StatusIconSettings(); + m_usePalette = false; update(true); }); presetsMenu->addAction( QCoreApplication::translate("QtGui::IconsOptionPageBase", "Transparent background and dark foreground (for bright themes)"), widget, [this] { m_settings = Data::StatusIconSettings(Data::StatusIconSettings::BrightTheme{}); + m_usePalette = false; update(true); }); presetsMenu->addAction( QCoreApplication::translate("QtGui::IconsOptionPageBase", "Transparent background and bright foreground (for dark themes)"), widget, [this] { m_settings = Data::StatusIconSettings(Data::StatusIconSettings::DarkTheme{}); + m_usePalette = false; update(true); }); + m_paletteAction = presetsMenu->addAction(QString(), widget, [this] { + m_usePalette = !m_usePalette; + update(true); + }); // setup additional buttons ui()->restoreDefaultsPushButton->setMenu(presetsMenu); @@ -760,9 +767,11 @@ bool IconsOptionPage::apply() case Context::Combined: case Context::UI: iconSettings.status = m_settings; + iconSettings.usePaletteForStatus = m_usePalette; break; case Context::System: iconSettings.tray = m_settings; + iconSettings.usePaletteForTray = m_usePalette; iconSettings.distinguishTrayIcons = !ui()->contextCheckBox->isChecked(); break; } @@ -777,6 +786,10 @@ void IconsOptionPage::update(bool preserveSize) } else { ui()->renderingSizeSlider->setValue(std::max(m_settings.renderSize.width(), m_settings.renderSize.height())); } + m_paletteAction->setText(m_usePalette + ? QCoreApplication::translate("QtGui::IconsOptionPageBase", "Select colors manually (no longer follow system palette)") + : QCoreApplication::translate("QtGui::IconsOptionPageBase", "Transparent background and foreground depending on system palette")); + ui()->gridWidget->setDisabled(m_usePalette); ui()->thickStrokeWidthCheckBox->setChecked(m_settings.strokeWidth == StatusIconStrokeWidth::Thick); for (auto &widgetsForColor : m_widgets) { widgetsForColor.colorButtons[0]->setColor(widgetsForColor.setting->backgroundStart); @@ -792,9 +805,11 @@ void IconsOptionPage::reset() case Context::Combined: case Context::UI: m_settings = iconSettings.status; + m_usePalette = iconSettings.usePaletteForStatus; break; case Context::System: m_settings = iconSettings.tray; + m_usePalette = iconSettings.usePaletteForTray; ui()->contextCheckBox->setChecked(!iconSettings.distinguishTrayIcons); break; } diff --git a/syncthingwidgets/settings/settingsdialog.h b/syncthingwidgets/settings/settingsdialog.h index c7b929e..59bf87b 100644 --- a/syncthingwidgets/settings/settingsdialog.h +++ b/syncthingwidgets/settings/settingsdialog.h @@ -105,6 +105,8 @@ private: void update(bool preserveSize = false); Context m_context; Data::StatusIconSettings m_settings; +QAction *m_paletteAction = nullptr; +bool m_usePalette = false; struct { QtUtilities::ColorButton *colorButtons[3] = {}; QLabel *previewLabel = nullptr; diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp index 29d688f..e044c0f 100644 --- a/tray/gui/traywidget.cpp +++ b/tray/gui/traywidget.cpp @@ -589,7 +589,9 @@ void TrayWidget::applySettings(const QString &connectionConfig) if (settings.appearance.tabPosition >= QTabWidget::North && settings.appearance.tabPosition <= QTabWidget::East) { m_ui->tabWidget->setTabPosition(static_cast(settings.appearance.tabPosition)); } - IconManager::instance().applySettings(&settings.icons.status, settings.icons.distinguishTrayIcons ? &settings.icons.tray : nullptr); + const auto &iconSettings = settings.icons; + IconManager::instance().applySettings(&iconSettings.status, iconSettings.distinguishTrayIcons ? &iconSettings.tray : nullptr, + iconSettings.usePaletteForStatus, iconSettings.usePaletteForTray); if (m_tabTextsShown != settings.appearance.showTabTexts) { const auto tabCount = m_ui->tabWidget->count(); if ((m_tabTextsShown = settings.appearance.showTabTexts)) {