support forced styles, custom alt. palette and force palette for skins

This commit is contained in:
Martin Rotter 2022-03-08 12:58:36 +01:00
parent 8902594059
commit 900c8fa0d6
5 changed files with 221 additions and 113 deletions

View File

@ -2,6 +2,7 @@
#include "gui/settings/settingsgui.h" #include "gui/settings/settingsgui.h"
#include "3rd-party/boolinq/boolinq.h"
#include "core/feedsmodel.h" #include "core/feedsmodel.h"
#include "gui/dialogs/formmain.h" #include "gui/dialogs/formmain.h"
#include "gui/feedmessageviewer.h" #include "gui/feedmessageviewer.h"
@ -27,12 +28,9 @@ SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(se
m_ui->m_editorFeedsToolbar->activeItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorFeedsToolbar->activeItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_editorMessagesToolbar->availableItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorMessagesToolbar->availableItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_editorFeedsToolbar->availableItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorFeedsToolbar->availableItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_treeSkins->setColumnCount(3); m_ui->m_treeSkins->setColumnCount(5);
m_ui->m_treeSkins->setHeaderHidden(false); m_ui->m_treeSkins->setHeaderHidden(false);
m_ui->m_treeSkins->setHeaderLabels(QStringList() m_ui->m_treeSkins->setHeaderLabels({ tr("Name"), tr("Version"), tr("Author"), tr("Forced styles"), tr("Forced alternative palette") });
<< /*: Skin list name column. */ tr("Name")
<< /*: Version column of skin list. */ tr("Version")
<< tr("Author"));
m_ui->m_tabUi->setTabVisible(m_ui->m_tabUi->indexOf(m_ui->m_tabTaskBar), m_ui->m_tabUi->setTabVisible(m_ui->m_tabUi->indexOf(m_ui->m_tabTaskBar),
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) || defined(Q_OS_WIN) #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) || defined(Q_OS_WIN)
@ -48,20 +46,21 @@ SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(se
m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeMode::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(3, QHeaderView::ResizeMode::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(4, QHeaderView::ResizeMode::ResizeToContents);
connect(m_ui->m_cmbStyles, &QComboBox::currentTextChanged, this, [this](const QString& txt) { connect(m_ui->m_cmbStyles, &QComboBox::currentTextChanged, this, &SettingsGui::updateSkinOptions);
m_ui->m_checkForceDarkFusion->setVisible(qApp->skins()->isStyleGoodForDarkVariant(txt));
});
connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &SettingsGui::requireRestart); this, &SettingsGui::requireRestart);
connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&SettingsGui::dirtifySettings); &SettingsGui::dirtifySettings);
connect(m_ui->m_treeSkins, &QTreeWidget::currentItemChanged, this, &SettingsGui::dirtifySettings); connect(m_ui->m_treeSkins, &QTreeWidget::currentItemChanged, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_treeSkins, &QTreeWidget::currentItemChanged, this, &SettingsGui::updateSkinOptions);
connect(m_ui->m_grpTray, &QGroupBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_grpTray, &QGroupBox::toggled, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_checkHidden, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_checkHidden, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_checkForceDarkFusion, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_checkForceAlternativePalette, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_checkForceDarkFusion, &QCheckBox::toggled, this, &SettingsGui::requireRestart); connect(m_ui->m_checkForceAlternativePalette, &QCheckBox::toggled, this, &SettingsGui::requireRestart);
connect(m_ui->m_checkMonochromeIcons, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_checkMonochromeIcons, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_checkCountUnreadMessages, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_checkCountUnreadMessages, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_checkHideWhenMinimized, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings); connect(m_ui->m_checkHideWhenMinimized, &QCheckBox::toggled, this, &SettingsGui::dirtifySettings);
@ -116,6 +115,24 @@ bool SettingsGui::eventFilter(QObject* obj, QEvent* e) {
return false; return false;
} }
void SettingsGui::updateSkinOptions() {
auto* it = m_ui->m_treeSkins->currentItem();
if (it == nullptr) {
return;
}
const Skin skin = it->data(0, Qt::ItemDataRole::UserRole).value<Skin>();
const bool skin_has_palette = !skin.m_stylePalette.isEmpty();
const bool skin_forces_palette = skin.m_forcedStylePalette;
const bool skin_forces_style = skin.m_forcedStyles.isEmpty();
m_ui->m_cmbStyles->setEnabled(!qApp->skins()->styleIsFrozen() && skin_forces_style);
m_ui->m_checkForceAlternativePalette->setEnabled(skin_has_palette
? !skin_forces_palette
: qApp->skins()->isStyleGoodForAlternativeStylePalette(m_ui->m_cmbStyles->currentText()));
}
void SettingsGui::loadSettings() { void SettingsGui::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
@ -130,9 +147,6 @@ void SettingsGui::loadSettings() {
m_ui->m_checkHidden->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::MainWindowStartsHidden)).toBool()); m_ui->m_checkHidden->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::MainWindowStartsHidden)).toBool());
m_ui->m_checkHideWhenMinimized->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool()); m_ui->m_checkHideWhenMinimized->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool());
m_ui->m_checkForceDarkFusion->setChecked(settings()->value(GROUP(GUI),
SETTING(GUI::ForceDarkFusion)).toBool());
// Load settings of icon theme. // Load settings of icon theme.
const QString current_theme = qApp->icons()->currentIconTheme(); const QString current_theme = qApp->icons()->currentIconTheme();
auto icons = qApp->icons()->installedIconThemes(); auto icons = qApp->icons()->installedIconThemes();
@ -159,7 +173,7 @@ void SettingsGui::loadSettings() {
m_ui->m_displayUnreadMessageCountOnTaskBar->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::UnreadNumbersOnTaskBar)).toBool()); m_ui->m_displayUnreadMessageCountOnTaskBar->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::UnreadNumbersOnTaskBar)).toBool());
#endif #endif
// Mark active theme. // Mark active icon theme.
if (current_theme == QL1S(APP_NO_THEME)) { if (current_theme == QL1S(APP_NO_THEME)) {
// Because "no icon theme" lies at the index 0. // Because "no icon theme" lies at the index 0.
m_ui->m_cmbIconTheme->setCurrentIndex(0); m_ui->m_cmbIconTheme->setCurrentIndex(0);
@ -168,15 +182,32 @@ void SettingsGui::loadSettings() {
m_ui->m_cmbIconTheme->setCurrentText(current_theme); m_ui->m_cmbIconTheme->setCurrentText(current_theme);
} }
// Load styles.
auto styles = QStyleFactory::keys();
for (const QString& style_name : qAsConst(styles)) {
m_ui->m_cmbStyles->addItem(style_name);
}
int item_style = m_ui->m_cmbStyles->findText(qApp->skins()->currentStyle(), Qt::MatchFlag::MatchFixedString);
if (item_style >= 0) {
m_ui->m_cmbStyles->setCurrentIndex(item_style);
}
m_ui->m_checkForceAlternativePalette->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::ForceDarkFusion)).toBool());
// Load skin. // Load skin.
const QString selected_skin = qApp->skins()->selectedSkinName(); const QString selected_skin = qApp->skins()->selectedSkinName();
auto skins = qApp->skins()->installedSkins(); auto skins = qApp->skins()->installedSkins();
for (const Skin& skin : qAsConst(skins)) { for (const Skin& skin : qAsConst(skins)) {
QTreeWidgetItem* new_item = new QTreeWidgetItem(QStringList() << QTreeWidgetItem* new_item = new QTreeWidgetItem({
skin.m_visibleName << skin.m_visibleName,
skin.m_version << skin.m_version,
skin.m_author); skin.m_author,
skin.m_forcedStyles.isEmpty() ? QChar(10007) : skin.m_forcedStyles.join(QSL(", ")),
skin.m_forcedStylePalette ? QChar(10003) : QChar(10007) });
new_item->setData(0, Qt::UserRole, QVariant::fromValue(skin)); new_item->setData(0, Qt::UserRole, QVariant::fromValue(skin));
@ -195,25 +226,6 @@ void SettingsGui::loadSettings() {
m_ui->m_treeSkins->setCurrentItem(m_ui->m_treeSkins->topLevelItem(0)); m_ui->m_treeSkins->setCurrentItem(m_ui->m_treeSkins->topLevelItem(0));
} }
// Load styles.
auto styles = QStyleFactory::keys();
for (const QString& style_name : qAsConst(styles)) {
m_ui->m_cmbStyles->addItem(style_name);
}
int item_style = m_ui->m_cmbStyles->findText(qApp->skins()->currentStyle(), Qt::MatchFlag::MatchFixedString);
if (item_style >= 0) {
m_ui->m_cmbStyles->setCurrentIndex(item_style);
}
if (qApp->skins()->styleIsFrozen()) {
m_ui->m_cmbStyles->setEnabled(false);
m_ui->m_cmbStyles->setToolTip(tr("You cannot change style because it was explicitly selected in your OS settings.\n"
"Perhaps it is set with 'QT_STYLE_OVERRIDE' environment variable?"));
}
// Load tab settings. // Load tab settings.
m_ui->m_checkCloseTabsMiddleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseMiddleClick)).toBool()); m_ui->m_checkCloseTabsMiddleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseMiddleClick)).toBool());
m_ui->m_checkCloseTabsDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool()); m_ui->m_checkCloseTabsDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool());
@ -336,8 +348,6 @@ void SettingsGui::saveSettings() {
settings()->setValue(GROUP(GUI), GUI::MainWindowStartsHidden, m_ui->m_checkHidden->isChecked()); settings()->setValue(GROUP(GUI), GUI::MainWindowStartsHidden, m_ui->m_checkHidden->isChecked());
settings()->setValue(GROUP(GUI), GUI::HideMainWindowWhenMinimized, m_ui->m_checkHideWhenMinimized->isChecked()); settings()->setValue(GROUP(GUI), GUI::HideMainWindowWhenMinimized, m_ui->m_checkHideWhenMinimized->isChecked());
settings()->setValue(GROUP(GUI), GUI::ForceDarkFusion, m_ui->m_checkForceDarkFusion->isChecked());
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) || defined(Q_OS_WIN) #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) || defined(Q_OS_WIN)
settings()->setValue(GROUP(GUI), GUI::UnreadNumbersOnTaskBar, m_ui->m_displayUnreadMessageCountOnTaskBar->isChecked()); settings()->setValue(GROUP(GUI), GUI::UnreadNumbersOnTaskBar, m_ui->m_displayUnreadMessageCountOnTaskBar->isChecked());
#endif #endif
@ -378,6 +388,10 @@ void SettingsGui::saveSettings() {
qApp->settings()->setValue(GROUP(GUI), GUI::Style, new_style); qApp->settings()->setValue(GROUP(GUI), GUI::Style, new_style);
} }
if (m_ui->m_checkForceAlternativePalette->isEnabled()) {
settings()->setValue(GROUP(GUI), GUI::ForceDarkFusion, m_ui->m_checkForceAlternativePalette->isChecked());
}
// Save tab settings. // Save tab settings.
settings()->setValue(GROUP(GUI), GUI::TabCloseMiddleClick, m_ui->m_checkCloseTabsMiddleClick->isChecked()); settings()->setValue(GROUP(GUI), GUI::TabCloseMiddleClick, m_ui->m_checkCloseTabsMiddleClick->isChecked());
settings()->setValue(GROUP(GUI), GUI::TabCloseDoubleClick, m_ui->m_checkCloseTabsDoubleClick->isChecked()); settings()->setValue(GROUP(GUI), GUI::TabCloseDoubleClick, m_ui->m_checkCloseTabsDoubleClick->isChecked());

View File

@ -24,6 +24,7 @@ class SettingsGui : public SettingsPanel {
bool eventFilter(QObject* obj, QEvent* e); bool eventFilter(QObject* obj, QEvent* e);
private slots: private slots:
void updateSkinOptions();
void resetCustomSkinColor(); void resetCustomSkinColor();
private: private:

View File

@ -101,9 +101,9 @@
</spacer> </spacer>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QCheckBox" name="m_checkForceDarkFusion"> <widget class="QCheckBox" name="m_checkForceAlternativePalette">
<property name="text"> <property name="text">
<string>Force dark look (Fusion only)</string> <string>Force alternative color palette defined in skin</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -458,7 +458,7 @@
<tabstop>m_cmbSelectToolBar</tabstop> <tabstop>m_cmbSelectToolBar</tabstop>
<tabstop>m_cmbIconTheme</tabstop> <tabstop>m_cmbIconTheme</tabstop>
<tabstop>m_cmbStyles</tabstop> <tabstop>m_cmbStyles</tabstop>
<tabstop>m_checkForceDarkFusion</tabstop> <tabstop>m_checkForceAlternativePalette</tabstop>
<tabstop>m_treeSkins</tabstop> <tabstop>m_treeSkins</tabstop>
<tabstop>m_gbCustomSkinColors</tabstop> <tabstop>m_gbCustomSkinColors</tabstop>
</tabstops> </tabstops>

View File

@ -42,7 +42,7 @@ void SkinFactory::loadCurrentSkin() {
qCriticalNN << LOGSEC_GUI << "Failed to load selected or default skin. Quitting!"; qCriticalNN << LOGSEC_GUI << "Failed to load selected or default skin. Quitting!";
} }
bool SkinFactory::isStyleGoodForDarkVariant(const QString& style_name) const { bool SkinFactory::isStyleGoodForAlternativeStylePalette(const QString& style_name) const {
static QRegularExpression re = QRegularExpression("^(fusion)|(qt[56]ct-style)$"); static QRegularExpression re = QRegularExpression("^(fusion)|(qt[56]ct-style)$");
return re.match(style_name.toLower()).hasMatch(); return re.match(style_name.toLower()).hasMatch();
@ -55,13 +55,26 @@ void SkinFactory::loadSkinFromData(const Skin& skin) {
const QString cli_forced_style = qApp->cmdParser()->value(QSL(CLI_STYLE_SHORT)); const QString cli_forced_style = qApp->cmdParser()->value(QSL(CLI_STYLE_SHORT));
if (env_forced_style.isEmpty() && cli_forced_style.isEmpty()) { if (env_forced_style.isEmpty() && cli_forced_style.isEmpty()) {
qApp->setStyle(style_name);
m_styleIsFrozen = false; m_styleIsFrozen = false;
qDebugNN << LOGSEC_GUI << "Setting style:" << QUOTE_W_SPACE_DOT(style_name); if (!skin.m_forcedStyles.isEmpty()) {
qDebugNN << LOGSEC_GUI << "Forcing one of skin's declared styles:"
<< QUOTE_W_SPACE_DOT(skin.m_forcedStyles);
for (const QString& skin_forced_style : skin.m_forcedStyles) {
if (qApp->setStyle(skin_forced_style) != nullptr) {
break;
}
}
}
else {
qDebugNN << LOGSEC_GUI << "Setting style:" << QUOTE_W_SPACE_DOT(style_name);
qApp->setStyle(style_name);
}
} }
else { else {
m_styleIsFrozen = true; m_styleIsFrozen = true;
qWarningNN << LOGSEC_GUI << "Respecting forced style(s):\n" qWarningNN << LOGSEC_GUI << "Respecting forced style(s):\n"
<< " QT_STYLE_OVERRIDE: " QUOTE_NO_SPACE(env_forced_style) << "\n" << " QT_STYLE_OVERRIDE: " QUOTE_NO_SPACE(env_forced_style) << "\n"
<< " CLI (-style): " QUOTE_NO_SPACE(cli_forced_style); << " CLI (-style): " QUOTE_NO_SPACE(cli_forced_style);
@ -71,86 +84,97 @@ void SkinFactory::loadSkinFromData(const Skin& skin) {
// they specifically set object name to style name. // they specifically set object name to style name.
m_currentStyle = qApp->style()->objectName(); m_currentStyle = qApp->style()->objectName();
if (isStyleGoodForDarkVariant(m_currentStyle) && if (isStyleGoodForAlternativeStylePalette(m_currentStyle) &&
qApp->settings()->value(GROUP(GUI), SETTING(GUI::ForceDarkFusion)).toBool()) {
qDebugNN << LOGSEC_GUI << "Activating dark palette for Fusion style.";
QPalette fusion_palette = qApp->palette(); /* Skin has alternative style palette and forces its usage. */
QColor clr_maibg(QSL("#2D2F32")); ((!skin.m_stylePalette.isEmpty() && skin.m_forcedStylePalette) ||
QColor clr_basbg(QSL("#373A3D"));
QColor clr_altbg(QSL("#323437"));
QColor clr_selbg(QSL("#8291AD"));
QColor clr_selfg(QSL("#FFFFFF"));
QColor clr_btnfg(QSL("#E7E7E7"));
QColor clr_dibfg(QSL("#A7A7A7"));
QColor clr_winfg(QSL("#D8D8D8"));
QColor clr_diwfg(QSL("#999999"));
QColor clr_brdbg(QSL("#202224")); // Use colour picker on dark brdr under list header for this one
QColor clr_wlink(QSL("#a1acc1"));
// /* User wants alternative style palette anyway. */
// Normal state. qApp->settings()->value(GROUP(GUI), SETTING(GUI::ForceDarkFusion)).toBool())) {
// qDebugNN << LOGSEC_GUI << "Activating alternative palette.";
// Backgrounds & bases. QPalette pal;
fusion_palette.setColor(QPalette::ColorRole::Window, clr_maibg);
fusion_palette.setColor(QPalette::ColorRole::Base, clr_basbg);
fusion_palette.setColor(QPalette::ColorRole::Dark, clr_brdbg);
fusion_palette.setColor(QPalette::ColorRole::AlternateBase, clr_altbg);
fusion_palette.setColor(QPalette::ColorRole::Button, clr_altbg);
fusion_palette.setColor(QPalette::ColorRole::Light, clr_altbg);
fusion_palette.setColor(QPalette::ColorRole::Highlight, clr_selbg);
// Texts. if (skin.m_stylePalette.isEmpty()) {
fusion_palette.setColor(QPalette::ColorRole::ButtonText, clr_btnfg); QColor clr_maibg(QSL("#2D2F32"));
fusion_palette.setColor(QPalette::ColorRole::WindowText, clr_winfg); QColor clr_basbg(QSL("#373A3D"));
fusion_palette.setColor(QPalette::ColorRole::BrightText, clr_basbg); QColor clr_altbg(QSL("#323437"));
fusion_palette.setColor(QPalette::ColorRole::Text, clr_winfg); QColor clr_selbg(QSL("#8291AD"));
fusion_palette.setColor(QPalette::ColorRole::PlaceholderText, clr_dibfg); QColor clr_selfg(QSL("#FFFFFF"));
fusion_palette.setColor(QPalette::ColorRole::Link, clr_wlink); QColor clr_btnfg(QSL("#E7E7E7"));
fusion_palette.setColor(QPalette::ColorRole::LinkVisited, clr_wlink); QColor clr_dibfg(QSL("#A7A7A7"));
fusion_palette.setColor(QPalette::ColorRole::HighlightedText, clr_selfg); QColor clr_winfg(QSL("#D8D8D8"));
QColor clr_diwfg(QSL("#999999"));
QColor clr_brdbg(QSL("#202224")); // Use color picker on dark brdr under list header for this one
QColor clr_wlink(QSL("#a1acc1"));
// //
// Inactive state. // Normal state.
// //
// Backgrounds & bases. // Backgrounds & bases.
pal.setColor(QPalette::ColorRole::Window, clr_maibg);
pal.setColor(QPalette::ColorRole::Base, clr_basbg);
pal.setColor(QPalette::ColorRole::Dark, clr_brdbg);
pal.setColor(QPalette::ColorRole::AlternateBase, clr_altbg);
pal.setColor(QPalette::ColorRole::Button, clr_altbg);
pal.setColor(QPalette::ColorRole::Light, clr_altbg);
pal.setColor(QPalette::ColorRole::Highlight, clr_selbg);
// Texts. // Texts.
pal.setColor(QPalette::ColorRole::ButtonText, clr_btnfg);
pal.setColor(QPalette::ColorRole::WindowText, clr_winfg);
pal.setColor(QPalette::ColorRole::BrightText, clr_basbg);
pal.setColor(QPalette::ColorRole::Text, clr_winfg);
pal.setColor(QPalette::ColorRole::PlaceholderText, clr_dibfg);
pal.setColor(QPalette::ColorRole::Link, clr_wlink);
pal.setColor(QPalette::ColorRole::LinkVisited, clr_wlink);
pal.setColor(QPalette::ColorRole::HighlightedText, clr_selfg);
// //
// Disabled state. // Inactive state.
// //
// Backgrounds & bases. // Backgrounds & bases.
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Window, clr_maibg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Base, clr_basbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Dark, clr_brdbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::AlternateBase, clr_altbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Button, clr_altbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Light, clr_altbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Highlight, clr_selbg);
// Texts. // Texts.
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::ButtonText, clr_dibfg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::WindowText, clr_diwfg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::BrightText, clr_basbg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Text, clr_diwfg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::PlaceholderText, clr_dibfg);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Link, clr_wlink);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::LinkVisited, clr_wlink);
fusion_palette.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::HighlightedText, clr_selfg);
// //
// Tooltips. // Disabled state.
// //
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipBase, clr_maibg); // Backgrounds & bases.
fusion_palette.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipText, clr_winfg); pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Window, clr_maibg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Base, clr_basbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Dark, clr_brdbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::AlternateBase, clr_altbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Button, clr_altbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Light, clr_altbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Highlight, clr_selbg);
QToolTip::setPalette(fusion_palette); // Texts.
qApp->setPalette(fusion_palette); pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::ButtonText, clr_dibfg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::WindowText, clr_diwfg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::BrightText, clr_basbg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Text, clr_diwfg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::PlaceholderText, clr_dibfg);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::Link, clr_wlink);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::LinkVisited, clr_wlink);
pal.setColor(QPalette::ColorGroup::Disabled, QPalette::ColorRole::HighlightedText, clr_selfg);
//
// Tooltips.
//
pal.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipBase, clr_maibg);
pal.setColor(QPalette::ColorGroup::All, QPalette::ColorRole::ToolTipText, clr_winfg);
}
else {
pal = skin.extractPalette();
}
QToolTip::setPalette(pal);
qApp->setPalette(pal);
} }
if (!skin.m_rawData.isEmpty()) { if (!skin.m_rawData.isEmpty()) {
@ -271,6 +295,49 @@ Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
skin.m_colorPalette = palette; skin.m_colorPalette = palette;
// Obtain alternative style palette.
skin.m_forcedStyles = skin_node
.namedItem(QSL("forced-styles"))
.toElement().text().split(',',
#if QT_VERSION >= 0x050F00 // Qt >= 5.15.0
Qt::SplitBehaviorFlags::SkipEmptyParts);
#else
QString::SplitBehavior::SkipEmptyParts);
#endif
skin.m_forcedStylePalette = skin_node.namedItem(QSL("forced-style-palette")).toElement().text() ==
QVariant(true).toString();
QDomElement style_palette_root = skin_node.namedItem(QSL("style-palette")).toElement();
if (!style_palette_root.isNull()) {
const QMetaObject& mop = QPalette::staticMetaObject;
QMetaEnum enumerp = mop.enumerator(mop.indexOfEnumerator(QSL("ColorGroup").toLocal8Bit().constData()));
QMetaEnum enumerx = mop.enumerator(mop.indexOfEnumerator(QSL("ColorRole").toLocal8Bit().constData()));
QMultiHash<QPalette::ColorGroup, QPair<QPalette::ColorRole, QColor>> groups;
QDomNodeList groups_of_palette = style_palette_root.elementsByTagName(QSL("group"));
for (int i = 0; i < groups_of_palette.size(); i++) {
const QDomNode& group_root_nd = groups_of_palette.at(i);
QPalette::ColorGroup group = QPalette::ColorGroup(enumerp.keyToValue(group_root_nd.toElement().attribute(QSL("id")).toLatin1()));
QDomNodeList colors_of_group = group_root_nd.toElement().elementsByTagName(QSL("color"));
for (int j = 0; j < colors_of_group.size(); j++) {
const QDomNode& color_nd = colors_of_group.at(j);
QColor color(color_nd.toElement().text());
QPalette::ColorRole role = QPalette::ColorRole(enumerx.keyToValue(color_nd.toElement().attribute(QSL("role")).toLatin1()));
groups.insert(group, QPair<QPalette::ColorRole, QColor>(role, color));
}
}
skin.m_stylePalette = groups;
}
// Free resources. // Free resources.
skin_file.close(); skin_file.close();
skin_file.deleteLater(); skin_file.deleteLater();
@ -394,6 +461,27 @@ QVariant Skin::colorForModel(SkinEnums::PaletteColors type, bool ignore_custom_c
: QVariant(); : QVariant();
} }
QPalette Skin::extractPalette() const {
QPalette pal;
QList<QPalette::ColorGroup> groups = m_stylePalette.keys();
if (groups.contains(QPalette::ColorGroup::All)) {
groups.removeAll(QPalette::ColorGroup::All);
groups.insert(0, QPalette::ColorGroup::All);
}
for (QPalette::ColorGroup grp : groups) {
auto roles = m_stylePalette.values(grp);
for (const auto& rl : roles) {
pal.setColor(grp, rl.first, rl.second);
}
}
return pal;
}
QString SkinEnums::palleteColorText(PaletteColors col) { QString SkinEnums::palleteColorText(PaletteColors col) {
switch (col) { switch (col) {
case SkinEnums::PaletteColors::FgInteresting: case SkinEnums::PaletteColors::FgInteresting:

View File

@ -8,6 +8,7 @@
#include <QColor> #include <QColor>
#include <QHash> #include <QHash>
#include <QMetaType> #include <QMetaType>
#include <QPalette>
#include <QStringList> #include <QStringList>
#include <QVariant> #include <QVariant>
@ -49,8 +50,12 @@ struct RSSGUARD_DLLSPEC Skin {
QString m_layoutMarkup; QString m_layoutMarkup;
QString m_enclosureMarkup; QString m_enclosureMarkup;
QHash<SkinEnums::PaletteColors, QColor> m_colorPalette; QHash<SkinEnums::PaletteColors, QColor> m_colorPalette;
QStringList m_forcedStyles;
bool m_forcedStylePalette;
QMultiHash<QPalette::ColorGroup, QPair<QPalette::ColorRole, QColor>> m_stylePalette;
QVariant colorForModel(SkinEnums::PaletteColors type, bool ignore_custom_colors = false) const; QVariant colorForModel(SkinEnums::PaletteColors type, bool ignore_custom_colors = false) const;
QPalette extractPalette() const;
}; };
uint qHash(const SkinEnums::PaletteColors& key); uint qHash(const SkinEnums::PaletteColors& key);
@ -68,7 +73,7 @@ class RSSGUARD_DLLSPEC SkinFactory : public QObject {
void loadCurrentSkin(); void loadCurrentSkin();
Skin currentSkin() const; Skin currentSkin() const;
bool isStyleGoodForDarkVariant(const QString& style_name) const; bool isStyleGoodForAlternativeStylePalette(const QString& style_name) const;
// Returns the name of the skin, that should be activated // Returns the name of the skin, that should be activated
// after application restart. // after application restart.