File indexing completed on 2024-11-24 03:56:27
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "palette_settings.hpp" 0008 0009 #include <QSet> 0010 #include <QApplication> 0011 #include <QMetaEnum> 0012 #include <QStyleFactory> 0013 0014 #include "app/widgets/widget_palette_editor.hpp" 0015 #include "app/utils/string_view.hpp" 0016 0017 app::settings::PaletteSettings::PaletteSettings() 0018 : default_palette(QGuiApplication::palette(), true) 0019 { 0020 } 0021 0022 0023 QString app::settings::PaletteSettings::slug() const 0024 { 0025 return "palette"; 0026 } 0027 0028 QIcon app::settings::PaletteSettings::icon() const 0029 { 0030 return QIcon::fromTheme("preferences-desktop-theme-global"); 0031 } 0032 0033 QString app::settings::PaletteSettings::label() const 0034 { 0035 return QObject::tr("Widget Theme"); 0036 } 0037 0038 void app::settings::PaletteSettings::save ( QSettings& settings ) 0039 { 0040 settings.setValue("theme", selected); 0041 settings.setValue("style", style); 0042 0043 settings.beginWriteArray("themes"); 0044 0045 int i = 0; 0046 for ( auto it = palettes.begin(); it != palettes.end(); ++it ) 0047 { 0048 if ( !it->built_in ) 0049 { 0050 settings.setArrayIndex(i); 0051 write_palette(settings, it.key(), *it); 0052 ++i; 0053 } 0054 0055 } 0056 0057 settings.endArray(); 0058 } 0059 0060 void app::settings::PaletteSettings::write_palette ( QSettings& settings, const QString& name, const QPalette& palette ) 0061 { 0062 settings.setValue("name", name); 0063 for ( const auto& p : roles() ) 0064 { 0065 settings.setValue(p.first + "_active", color_to_string(palette.color(QPalette::Active, p.second))); 0066 settings.setValue(p.first + "_inactive", color_to_string(palette.color(QPalette::Inactive, p.second))); 0067 settings.setValue(p.first + "_disabled", color_to_string(palette.color(QPalette::Disabled, p.second))); 0068 } 0069 } 0070 0071 0072 void app::settings::PaletteSettings::load_palette ( const QSettings& settings, bool mark_built_in ) 0073 { 0074 QString name = settings.value("name").toString(); 0075 if ( name.isEmpty() ) 0076 return; 0077 0078 auto it = palettes.find(name); 0079 if ( it != palettes.end() && it->built_in && !mark_built_in ) 0080 return; 0081 0082 Palette palette; 0083 palette.built_in = mark_built_in; 0084 0085 for ( const auto& p : roles() ) 0086 { 0087 palette.setColor(QPalette::Active, p.second, string_to_color(settings.value(p.first + "_active").toString())); 0088 palette.setColor(QPalette::Inactive, p.second, string_to_color(settings.value(p.first + "_inactive").toString())); 0089 palette.setColor(QPalette::Disabled, p.second, string_to_color(settings.value(p.first + "_disabled").toString())); 0090 } 0091 0092 palettes.insert(name, palette); 0093 } 0094 0095 0096 void app::settings::PaletteSettings::load ( QSettings& settings ) 0097 { 0098 selected = settings.value("theme").toString(); 0099 style = settings.value("style").toString(); 0100 if ( !style.isEmpty() ) 0101 set_style(style); 0102 0103 int n = settings.beginReadArray("themes"); 0104 0105 for ( int i = 0; i < n; i++ ) 0106 { 0107 settings.setArrayIndex(i); 0108 load_palette(settings); 0109 } 0110 0111 settings.endArray(); 0112 0113 apply_palette(palette()); 0114 } 0115 0116 const QPalette& app::settings::PaletteSettings::palette() const 0117 { 0118 auto it = palettes.find(selected); 0119 if ( it == palettes.end() ) 0120 return default_palette; 0121 0122 return *it; 0123 } 0124 0125 0126 const std::vector<std::pair<QString, QPalette::ColorRole> > & app::settings::PaletteSettings::roles() 0127 { 0128 static std::vector<std::pair<QString, QPalette::ColorRole> > roles; 0129 if ( roles.empty() ) 0130 { 0131 QSet<QString> blacklisted = { 0132 "Background", "Foreground", "NColorRoles" 0133 }; 0134 QMetaEnum me = QMetaEnum::fromType<QPalette::ColorRole>(); 0135 for ( int i = 0; i < me.keyCount(); i++ ) 0136 { 0137 if ( blacklisted.contains(me.key(i)) ) 0138 continue; 0139 0140 roles.emplace_back( 0141 me.key(i), 0142 QPalette::ColorRole(me.value(i)) 0143 ); 0144 } 0145 } 0146 0147 return roles; 0148 } 0149 0150 void app::settings::PaletteSettings::set_selected ( const QString& name ) 0151 { 0152 selected = name; 0153 apply_palette(palette()); 0154 } 0155 0156 QWidget * app::settings::PaletteSettings::make_widget ( QWidget* parent ) 0157 { 0158 return new WidgetPaletteEditor(this, parent); 0159 } 0160 0161 void app::settings::PaletteSettings::apply_palette(const QPalette& palette) 0162 { 0163 QGuiApplication::setPalette(palette); 0164 QApplication::setPalette(palette); 0165 0166 for ( auto window : QApplication::topLevelWidgets() ) 0167 window->setPalette(palette); 0168 } 0169 0170 QString app::settings::PaletteSettings::color_to_string(const QColor& c) 0171 { 0172 QString s = c.name(); 0173 if ( c.alpha() < 255 ) 0174 s += utils::right_ref(QString::number(0x100|c.alpha(), 16), 2); 0175 return s; 0176 } 0177 0178 QColor app::settings::PaletteSettings::string_to_color(const QString& s) 0179 { 0180 if ( s.startsWith('#') && s.length() == 9 ) 0181 { 0182 QColor c(utils::left_ref(s, 7)); 0183 c.setAlpha(s.right(2).toInt(nullptr, 16)); 0184 return c; 0185 } 0186 0187 return QColor(s); 0188 } 0189 0190 void app::settings::PaletteSettings::set_style(const QString& name) 0191 { 0192 QApplication::setStyle(QStyleFactory::create(name)); 0193 style = name; 0194 }