1414#include < QGuiApplication>
1515#include < QIcon>
1616#include < QLocale>
17+ #include < QStyleHints>
18+ #include < optional>
19+
20+ namespace {
21+
22+ QVariantList wrapSection (const QString &title, const QVariantList &items) {
23+ QVariantMap section;
24+ section[QStringLiteral (" title" )] = title;
25+ section[QStringLiteral (" items" )] = items;
26+ return {section};
27+ }
28+
29+ QVariant themeDropdownItem (const std::string &id) {
30+ const auto qid = QString::fromStdString (id);
31+ const auto *theme = ThemeService::instance ().findTheme (qid);
32+ if (!theme) return qml::makeDropdownItem (qid, qid);
33+ const auto iconUrl = theme->icon () ? ImageURL::local (QString::fromStdString (theme->icon ()->string ()))
34+ : ImageURL::builtin (BuiltinIcon::Vicinae);
35+ return qml::makeDropdownItem (qid, theme->name (), qml::imageSourceFor (iconUrl));
36+ }
37+
38+ QVariantList themeItemsForVariant (std::optional<ThemeVariant> variant) {
39+ QVariantList items;
40+ for (const auto &theme : ThemeService::instance ().themes ()) {
41+ if (variant && theme->variant () != *variant) continue ;
42+ const auto iconUrl = theme->icon () ? ImageURL::local (QString::fromStdString (theme->icon ()->string ()))
43+ : ImageURL::builtin (BuiltinIcon::Vicinae);
44+ items.append (qml::makeDropdownItem (theme->id (), theme->name (), qml::imageSourceFor (iconUrl)));
45+ }
46+ const QString title = !variant ? GeneralSettingsModel::tr (" Themes" )
47+ : *variant == ThemeVariant::Light ? GeneralSettingsModel::tr (" Light themes" )
48+ : GeneralSettingsModel::tr (" Dark themes" );
49+ return wrapSection (title, items);
50+ }
51+
52+ } // namespace
1753
1854GeneralSettingsModel::GeneralSettingsModel (QObject *parent) : QObject(parent) {
1955 m_windowMaterialModel.setSections (windowMaterialItems ());
@@ -34,6 +70,14 @@ void GeneralSettingsModel::refreshDynamicModels() {
3470 m_themeItems = items;
3571 m_themeModel.setSections (items);
3672 }
73+ if (auto items = themeItemsForVariant (ThemeVariant::Light); items != m_lightThemeItems) {
74+ m_lightThemeItems = items;
75+ m_lightThemeModel.setSections (items);
76+ }
77+ if (auto items = themeItemsForVariant (ThemeVariant::Dark); items != m_darkThemeItems) {
78+ m_darkThemeItems = items;
79+ m_darkThemeModel.setSections (items);
80+ }
3781 if (auto items = iconThemeItems (); items != m_iconThemeItems) {
3882 m_iconThemeItems = items;
3983 m_iconThemeModel.setSections (items);
@@ -175,15 +219,22 @@ void GeneralSettingsModel::setFontSize(const QString &v) {
175219 if (ok) cfgManager ().mergeWithUser ({.font = config::Partial<config::FontConfig>{.normal {.size = val}}});
176220}
177221
178- using qml::makeDropdownItem;
222+ bool GeneralSettingsModel::followSystemAppearance () const { return cfg (). followsSystemAppearance (); }
179223
180- static QVariantList wrapSection (const QString &title, const QVariantList &items) {
181- QVariantMap section;
182- section[QStringLiteral (" title" )] = title;
183- section[QStringLiteral (" items" )] = items;
184- return {section};
224+ void GeneralSettingsModel::setFollowSystemAppearance (bool follow) {
225+ if (follow) {
226+ cfgManager ().mergeWithUser (
227+ {.theme = config::Partial<config::ThemeConfig>{.appearance = std::string{" system" }}});
228+ return ;
229+ }
230+
231+ const bool light = QGuiApplication::styleHints ()->colorScheme () == Qt::ColorScheme::Light;
232+ cfgManager ().mergeWithUser ({.theme = config::Partial<config::ThemeConfig>{
233+ .appearance = light ? std::string{" light" } : std::string{" dark" }}});
185234}
186235
236+ using qml::makeDropdownItem;
237+
187238QVariantList GeneralSettingsModel::windowMaterialItems () const {
188239 QVariantList items;
189240 items.append (makeDropdownItem (QStringLiteral (" none" ), tr (" None" )));
@@ -206,24 +257,13 @@ void GeneralSettingsModel::selectWindowMaterial(const QString &id) {
206257 {.launcherWindow = config::Partial<config::WindowConfig>{.material = id.toStdString ()}});
207258}
208259
209- QVariantList GeneralSettingsModel::themeItems () const {
210- QVariantList items;
211- for (const auto &theme : ThemeService::instance ().themes ()) {
212- auto iconUrl = theme->icon () ? ImageURL::local (QString::fromStdString (theme->icon ()->string ()))
213- : ImageURL::builtin (BuiltinIcon::Vicinae);
214- items.append (makeDropdownItem (theme->id (), theme->name (), qml::imageSourceFor (iconUrl)));
215- }
216- return wrapSection (tr (" Themes" ), items);
217- }
260+ QVariantList GeneralSettingsModel::themeItems () const { return themeItemsForVariant (std::nullopt ); }
218261
219- QVariant GeneralSettingsModel::currentTheme () const {
220- auto id = QString::fromStdString (cfg ().systemTheme ().name );
221- auto *theme = ThemeService::instance ().findTheme (id);
222- if (!theme) return makeDropdownItem (id, id);
223- auto iconUrl = theme->icon () ? ImageURL::local (QString::fromStdString (theme->icon ()->string ()))
224- : ImageURL::builtin (BuiltinIcon::Vicinae);
225- return makeDropdownItem (id, theme->name (), qml::imageSourceFor (iconUrl));
226- }
262+ QVariant GeneralSettingsModel::currentTheme () const { return themeDropdownItem (cfg ().systemTheme ().name ); }
263+
264+ QVariant GeneralSettingsModel::currentLightTheme () const { return themeDropdownItem (cfg ().theme .light .name ); }
265+
266+ QVariant GeneralSettingsModel::currentDarkTheme () const { return themeDropdownItem (cfg ().theme .dark .name ); }
227267
228268QVariantList GeneralSettingsModel::fontItems () const {
229269 QVariantList items;
@@ -292,6 +332,20 @@ void GeneralSettingsModel::selectTheme(const QString &id) {
292332 cfgManager ().mergeThemeConfig ({.name = id.toStdString ()});
293333}
294334
335+ void GeneralSettingsModel::selectLightTheme (const QString &id) {
336+ config::Partial<config::ThemeConfig> theme{
337+ .light = config::Partial<config::SystemThemeConfig>{.name = id.toStdString ()}};
338+ if (!followSystemAppearance ()) theme.appearance = " light" ;
339+ cfgManager ().mergeWithUser ({.theme = theme});
340+ }
341+
342+ void GeneralSettingsModel::selectDarkTheme (const QString &id) {
343+ config::Partial<config::ThemeConfig> theme{
344+ .dark = config::Partial<config::SystemThemeConfig>{.name = id.toStdString ()}};
345+ if (!followSystemAppearance ()) theme.appearance = " dark" ;
346+ cfgManager ().mergeWithUser ({.theme = theme});
347+ }
348+
295349void GeneralSettingsModel::selectFont (const QString &id) {
296350 cfgManager ().mergeWithUser (
297351 {.font = config::Partial<config::FontConfig>{.normal = {.family = id.toStdString ()}}});
0 commit comments