mirror of
https://github.com/YACReader/yacreader
synced 2026-04-12 15:49:53 -04:00
Use json file based themes instead of code to create them (theme editor + theme mode settings)
This commit is contained in:
@ -1,14 +1,13 @@
|
||||
#include "theme_manager.h"
|
||||
|
||||
#include "appearance_configuration.h"
|
||||
#include "theme.h"
|
||||
#include "theme_factory.h"
|
||||
#include "theme_repository.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QPalette>
|
||||
#include <QStyleHints>
|
||||
|
||||
// TODO: add API to force color scheme //styleHints->setColorScheme(Qt::ColorScheme::Dark);
|
||||
|
||||
ThemeManager::ThemeManager()
|
||||
{
|
||||
}
|
||||
@ -19,36 +18,106 @@ ThemeManager &ThemeManager::instance()
|
||||
return instance;
|
||||
}
|
||||
|
||||
void ThemeManager::initialize()
|
||||
void ThemeManager::initialize(AppearanceConfiguration *config, ThemeRepository *repository)
|
||||
{
|
||||
this->config = config;
|
||||
this->repository = repository;
|
||||
|
||||
auto *styleHints = qGuiApp->styleHints();
|
||||
|
||||
auto colorScheme = styleHints->colorScheme();
|
||||
// Re-resolve when OS color scheme changes (relevant for FollowSystem mode)
|
||||
connect(styleHints, &QStyleHints::colorSchemeChanged, this, &ThemeManager::resolveTheme, Qt::QueuedConnection);
|
||||
|
||||
// TODO: settings are needed to decide what theme to use
|
||||
auto applyColorScheme = [this](Qt::ColorScheme scheme) {
|
||||
setTheme(scheme == Qt::ColorScheme::Dark ? ThemeId::Dark : ThemeId::Light);
|
||||
};
|
||||
// Re-resolve when the user changes any theme setting
|
||||
connect(config, &AppearanceConfiguration::selectionChanged, this, &ThemeManager::resolveTheme);
|
||||
|
||||
applyColorScheme(colorScheme);
|
||||
|
||||
connect(styleHints, &QStyleHints::colorSchemeChanged, this, applyColorScheme, Qt::QueuedConnection);
|
||||
resolveTheme();
|
||||
}
|
||||
|
||||
void ThemeManager::setTheme(ThemeId themeId)
|
||||
void ThemeManager::setTheme(const Theme &theme)
|
||||
{
|
||||
if (this->themeId == themeId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->themeId = themeId;
|
||||
|
||||
updateCurrentTheme();
|
||||
|
||||
currentTheme = theme;
|
||||
emit themeChanged();
|
||||
}
|
||||
|
||||
void ThemeManager::updateCurrentTheme()
|
||||
Theme ThemeManager::themeFromId(const QString &id, ThemeVariant fallbackVariant)
|
||||
{
|
||||
currentTheme = makeTheme(themeId);
|
||||
// Try the repository first (handles both builtin and user themes via JSON)
|
||||
if (repository && repository->contains(id)) {
|
||||
QJsonObject json = repository->loadThemeJson(id);
|
||||
if (!json.isEmpty())
|
||||
return makeTheme(json);
|
||||
}
|
||||
|
||||
// Fallback to the builtin that matches the current dark/light intent.
|
||||
const QString fallbackId = (fallbackVariant == ThemeVariant::Dark)
|
||||
? QStringLiteral("builtin/dark")
|
||||
: QStringLiteral("builtin/light");
|
||||
if (repository && repository->contains(fallbackId)) {
|
||||
QJsonObject json = repository->loadThemeJson(fallbackId);
|
||||
if (!json.isEmpty())
|
||||
return makeTheme(json);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ThemeManager::resolveTheme()
|
||||
{
|
||||
if (!config)
|
||||
return;
|
||||
|
||||
const auto &sel = config->selection();
|
||||
|
||||
QString id;
|
||||
ThemeVariant fallbackVariant;
|
||||
switch (sel.mode) {
|
||||
case ThemeMode::FollowSystem: {
|
||||
const bool isDark = (qGuiApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark);
|
||||
id = isDark ? sel.darkThemeId : sel.lightThemeId;
|
||||
fallbackVariant = isDark ? ThemeVariant::Dark : ThemeVariant::Light;
|
||||
break;
|
||||
}
|
||||
case ThemeMode::Light:
|
||||
id = sel.lightThemeId;
|
||||
fallbackVariant = ThemeVariant::Light;
|
||||
break;
|
||||
case ThemeMode::Dark:
|
||||
id = sel.darkThemeId;
|
||||
fallbackVariant = ThemeVariant::Dark;
|
||||
break;
|
||||
case ThemeMode::ForcedTheme:
|
||||
id = sel.fixedThemeId;
|
||||
fallbackVariant = (qGuiApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark)
|
||||
? ThemeVariant::Dark
|
||||
: ThemeVariant::Light;
|
||||
break;
|
||||
}
|
||||
|
||||
const Theme theme = themeFromId(id, fallbackVariant);
|
||||
|
||||
// Sync Qt's application-level color scheme so native widgets (menus, scrollbars,
|
||||
// standard dialogs) use the correct palette before themeChanged() is emitted.
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
Qt::ColorScheme scheme;
|
||||
switch (sel.mode) {
|
||||
case ThemeMode::FollowSystem:
|
||||
scheme = Qt::ColorScheme::Unknown; // delegate to OS
|
||||
break;
|
||||
case ThemeMode::Light:
|
||||
scheme = Qt::ColorScheme::Light;
|
||||
break;
|
||||
case ThemeMode::Dark:
|
||||
scheme = Qt::ColorScheme::Dark;
|
||||
break;
|
||||
case ThemeMode::ForcedTheme:
|
||||
scheme = (theme.meta.variant == ThemeVariant::Dark)
|
||||
? Qt::ColorScheme::Dark
|
||||
: Qt::ColorScheme::Light;
|
||||
break;
|
||||
}
|
||||
qGuiApp->styleHints()->setColorScheme(scheme);
|
||||
#endif
|
||||
|
||||
setTheme(theme);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user