feat: make tokens separate singleton

This commit is contained in:
2 * r + 2 * t 2026-04-11 15:36:18 +10:00
parent f4b851b5b3
commit 9f8fd7d660
6 changed files with 112 additions and 36 deletions

View file

@ -4,7 +4,7 @@ qml_module(caelestia-config
config.cpp
configobject.cpp
appearanceconfig.cpp
tokensconfig.hpp
tokens.cpp
backgroundconfig.hpp
barconfig.hpp
borderconfig.hpp

View file

@ -1,5 +1,5 @@
#include "appearanceconfig.hpp"
#include "tokensconfig.hpp"
#include "tokens.hpp"
#include <qmetaobject.h>

View file

@ -33,22 +33,11 @@ GlobalConfig::GlobalConfig(QObject* parent)
, m_utilities(new UtilitiesConfig(this))
, m_sidebar(new SidebarConfig(this))
, m_services(new ServiceConfig(this))
, m_paths(new UserPaths(this))
, m_tokens(new TokenConfig(this)) {
, m_paths(new UserPaths(this)) {
// Set global instance
s_instance = this;
// Bind token base values from token config to appearance computed properties
auto* appearance = m_tokens->appearance();
m_appearance->rounding()->bindTokens(appearance->rounding());
m_appearance->spacing()->bindTokens(appearance->spacing());
m_appearance->padding()->bindTokens(appearance->padding());
m_appearance->font()->size()->bindTokens(appearance->fontSize());
m_appearance->anim()->durations()->bindTokens(appearance->animDurations());
// Each has its own file backend
setupFileBackend(configDir() + QStringLiteral("shell.json"));
m_tokens->setupFileBackend(configDir() + QStringLiteral("shell-tokens.json"));
}
GlobalConfig::~GlobalConfig() {

View file

@ -17,7 +17,6 @@
#include "serviceconfig.hpp"
#include "sessionconfig.hpp"
#include "sidebarconfig.hpp"
#include "tokensconfig.hpp"
#include "userpaths.hpp"
#include "utilitiesconfig.hpp"
#include "winfoconfig.hpp"
@ -46,15 +45,11 @@ class GlobalConfig : public ConfigObject {
CONFIG_SUBOBJECT(SidebarConfig, sidebar)
CONFIG_SUBOBJECT(ServiceConfig, services)
CONFIG_SUBOBJECT(UserPaths, paths)
// tokens is NOT a CONFIG_SUBOBJECT — it has its own file backend
Q_PROPERTY(TokenConfig* tokens READ tokens CONSTANT)
public:
static GlobalConfig* instance();
static GlobalConfig* create(QQmlEngine*, QJSEngine*);
[[nodiscard]] TokenConfig* tokens() const { return m_tokens; }
Q_INVOKABLE void save();
Q_INVOKABLE void reload();
@ -62,8 +57,6 @@ public:
private:
explicit GlobalConfig(QObject* parent = nullptr);
TokenConfig* m_tokens = nullptr;
};
class Config : public QQuickItem {

View file

@ -0,0 +1,85 @@
#include "tokens.hpp"
#include "config.hpp"
#include <qqmlengine.h>
#include <qstandardpaths.h>
namespace caelestia::config {
namespace {
TokenConfig* s_instance = nullptr;
QString configDir() {
return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/caelestia/");
}
} // namespace
TokenConfig::TokenConfig(QObject* parent)
: ConfigObject(parent)
, m_appearance(new AppearanceTokens(this))
, m_bar(new BarTokens(this))
, m_dashboard(new DashboardTokens(this))
, m_launcher(new LauncherTokens(this))
, m_notifs(new NotifsTokens(this))
, m_osd(new OsdTokens(this))
, m_session(new SessionTokens(this))
, m_sidebar(new SidebarTokens(this))
, m_utilities(new UtilitiesTokens(this))
, m_lock(new LockTokens(this))
, m_winfo(new WInfoTokens(this))
, m_controlCenter(new ControlCenterTokens(this)) {
s_instance = this;
// Bind token base values to GlobalConfig appearance computed properties
if (auto* global = GlobalConfig::instance()) {
auto* appearanceConfig = global->appearance();
appearanceConfig->rounding()->bindTokens(m_appearance->rounding());
appearanceConfig->spacing()->bindTokens(m_appearance->spacing());
appearanceConfig->padding()->bindTokens(m_appearance->padding());
appearanceConfig->font()->size()->bindTokens(m_appearance->fontSize());
appearanceConfig->anim()->durations()->bindTokens(m_appearance->animDurations());
}
setupFileBackend(configDir() + QStringLiteral("shell-tokens.json"));
}
TokenConfig::~TokenConfig() {
s_instance = nullptr;
}
TokenConfig* TokenConfig::instance() {
return s_instance;
}
TokenConfig* TokenConfig::create(QQmlEngine* engine, QJSEngine*) {
return new TokenConfig(engine);
}
void TokenConfig::save() {
saveToFile();
}
void TokenConfig::reload() {
reloadFromFile();
}
// Tokens (attached type)
Tokens::Tokens(QQuickItem* parent)
: QQuickItem(parent) {}
Tokens* Tokens::qmlAttachedProperties(QObject* object) {
auto* item = qobject_cast<QQuickItem*>(object);
while (item) {
if (auto* tokens = qobject_cast<Tokens*>(item))
return tokens;
item = item->parentItem();
}
return nullptr;
}
} // namespace caelestia::config

View file

@ -3,6 +3,7 @@
#include "configobject.hpp"
#include <qlist.h>
#include <qquickitem.h>
namespace caelestia::config {
@ -288,7 +289,8 @@ public:
class TokenConfig : public ConfigObject {
Q_OBJECT
QML_ANONYMOUS
QML_ELEMENT
QML_SINGLETON
CONFIG_SUBOBJECT(AppearanceTokens, appearance)
CONFIG_SUBOBJECT(BarTokens, bar)
@ -304,20 +306,27 @@ class TokenConfig : public ConfigObject {
CONFIG_SUBOBJECT(ControlCenterTokens, controlCenter)
public:
explicit TokenConfig(QObject* parent = nullptr)
: ConfigObject(parent)
, m_appearance(new AppearanceTokens(this))
, m_bar(new BarTokens(this))
, m_dashboard(new DashboardTokens(this))
, m_launcher(new LauncherTokens(this))
, m_notifs(new NotifsTokens(this))
, m_osd(new OsdTokens(this))
, m_session(new SessionTokens(this))
, m_sidebar(new SidebarTokens(this))
, m_utilities(new UtilitiesTokens(this))
, m_lock(new LockTokens(this))
, m_winfo(new WInfoTokens(this))
, m_controlCenter(new ControlCenterTokens(this)) {}
static TokenConfig* instance();
static TokenConfig* create(QQmlEngine*, QJSEngine*);
Q_INVOKABLE void save();
Q_INVOKABLE void reload();
~TokenConfig() override;
private:
explicit TokenConfig(QObject* parent = nullptr);
};
class Tokens : public QQuickItem {
Q_OBJECT
QML_ELEMENT
QML_ATTACHED(Tokens)
public:
explicit Tokens(QQuickItem* parent = nullptr);
static Tokens* qmlAttachedProperties(QObject* object);
};
} // namespace caelestia::config