#pragma once #include #include #include "settings/layerregistry.hpp" #include "settings/rootnode.hpp" #include "appearance.hpp" #include "background.hpp" #include "bar.hpp" #include "clipboard.hpp" #include "colors.hpp" #include "common.hpp" #include "dashboard.hpp" #include "display.hpp" #include "dock.hpp" #include "general.hpp" #include "launcher.hpp" #include "llm.hpp" #include "lock.hpp" #include "notifs.hpp" #include "osd.hpp" #include "screenshot.hpp" #include "services.hpp" #include "sidebar.hpp" #include "tokens.hpp" #include "utilities.hpp" namespace ZShell::config { class ConfigRoot : public settings::RootNode { CONFIG_NODE_NO_CTOR(ConfigRoot, settings::RootNode) QML_ANONYMOUS CONFIG_PROPERTY(bool, enabled, true) CONFIG_SUBOBJECT(Appearance, appearance) CONFIG_SUBOBJECT(Background, background) CONFIG_SUBOBJECT(Bar, bar) CONFIG_SUBOBJECT(Clipboard, clipboard) CONFIG_SUBOBJECT(Colors, colors) CONFIG_SUBOBJECT(Dashboard, dashboard) CONFIG_SUBOBJECT(Display, display) CONFIG_SUBOBJECT(Dock, dock) CONFIG_SUBOBJECT(General, general) CONFIG_SUBOBJECT(Launcher, launcher) CONFIG_SUBOBJECT(Llm, llm) CONFIG_SUBOBJECT(Lock, lock) CONFIG_SUBOBJECT(Notifs, notifs) CONFIG_SUBOBJECT(Osd, osd) CONFIG_SUBOBJECT(Screenshot, screenshot) CONFIG_SUBOBJECT(Services, services) CONFIG_SUBOBJECT(Sidebar, sidebar) CONFIG_SUBOBJECT(Utilities, utilities) public: explicit ConfigRoot( const QString& path, ConfigRoot* fallback = nullptr, QObject* parent = nullptr); private: // Binds the computed appearance values to the global token base values void bindTokens(); // Applies ConfigMigrations to the file before the first load void migrateFile(const QString& path); }; class TokensRoot : public settings::RootNode { CONFIG_NODE_NO_CTOR(TokensRoot, settings::RootNode) QML_ANONYMOUS CONFIG_SUBOBJECT(AppearanceTokens, appearance) CONFIG_SUBOBJECT(SizeTokens, sizes) public: explicit TokensRoot( const QString& path, TokensRoot* fallback = nullptr, QObject* parent = nullptr); }; namespace detail { enum class ConfigKind : quint8 { Shell, Tokens }; void loaded(ConfigKind kind, settings::RootNode* layer, const QString& screen); void loadFailed(ConfigKind kind, const QString& error, const QString& screen); void saveFailed(ConfigKind kind, const QString& error, const QString& screen); } // namespace detail #define SINGLETON_DECL(Type, Root, QmlName) \ class Type : public Root { \ Q_OBJECT \ QML_NAMED_ELEMENT(QmlName) \ QML_SINGLETON \ \ public: \ static Type* instance(); \ static Type* create(QQmlEngine*, QJSEngine*); \ \ [[nodiscard]] Q_INVOKABLE Root* forScreen(const QString& screen); \ \ private: \ explicit Type(QObject* parent = nullptr); \ \ void onTreeLoaded(settings::RootNode* layer); \ void onTreeLoadFailed(settings::RootNode* layer, const QString& error); \ void onTreeSaveFailed(settings::RootNode* layer, const QString& error); \ \ void initLayer(Root* layer); \ \ settings::LayerRegistry m_layers; \ }; SINGLETON_DECL(ConfigSingleton, ConfigRoot, Config) SINGLETON_DECL(TokensSingleton, TokensRoot, TokenConfig) #undef SINGLETON_DECL class Tokens : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON Q_PROPERTY( ZShell::config::AppearanceRounding* rounding READ rounding CONSTANT) Q_PROPERTY(ZShell::config::AppearanceSpacing* spacing READ spacing CONSTANT) Q_PROPERTY(ZShell::config::AppearancePadding* padding READ padding CONSTANT) Q_PROPERTY(ZShell::config::SizeTokens* sizes READ sizes CONSTANT) Q_PROPERTY(ZShell::config::FontTokens* font READ font CONSTANT) Q_PROPERTY(ZShell::config::AnimTokens* anim READ anim CONSTANT) public: explicit Tokens(QObject* parent = nullptr) : QObject(parent) , m_font(new FontTokens(this)) , m_anim(new AnimTokens(this)) { m_anim->bindCurves(TokensSingleton::instance()->appearance()->curves()); m_anim->bindDurations( ConfigSingleton::instance()->appearance()->anim()->durations()); m_font->bindFont(ConfigSingleton::instance()->appearance()->font()); } [[nodiscard]] AppearanceRounding* rounding() const { return ConfigSingleton::instance()->appearance()->rounding(); } [[nodiscard]] AppearancePadding* padding() const { return ConfigSingleton::instance()->appearance()->padding(); } [[nodiscard]] AppearanceSpacing* spacing() const { return ConfigSingleton::instance()->appearance()->spacing(); } [[nodiscard]] SizeTokens* sizes() const { return TokensSingleton::instance()->sizes(); } [[nodiscard]] FontTokens* font() const { return m_font; } [[nodiscard]] AnimTokens* anim() const { return m_anim; } static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); } private: FontTokens* m_font; AnimTokens* m_anim; }; } // namespace ZShell::config