config moved to c++ plugin, removed old qml + fileview implementation
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QMetaProperty>
|
||||
#include <QMetaMethod>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CFG_PROPERTY / CFG_SECTION
|
||||
//
|
||||
// These generate exactly the boilerplate you'd write by hand for a
|
||||
// Q_PROPERTY with a backing member, getter, setter and NOTIFY signal - just
|
||||
// in one line instead of ~8. Because everything they generate is a normal
|
||||
// compiled getter/setter, there is *zero* extra runtime cost vs hand-written
|
||||
// code: reading Config.appearance.anim.sessionGifSpeed from QML calls a
|
||||
// plain inline getter. Reflection (QMetaObject) is only walked at load time,
|
||||
// save time, and once at construction time to wire change signals - never
|
||||
// on the read/write path itself.
|
||||
//
|
||||
// CFG_PROPERTY(type, name, Name)
|
||||
// - type: C++ type (bool, int, qreal, QString, QVariantList, ...)
|
||||
// - name: property name as it must appear in the JSON file (camelCase,
|
||||
// or whatever the JSON actually uses - it MUST match exactly)
|
||||
// - Name: same name, capitalized, used to build setName()/NameChanged()
|
||||
//
|
||||
// CFG_SECTION(Type, name, Name)
|
||||
// - Declares a child ConfigSection* property (e.g. Anim inside Appearance)
|
||||
// - The pointer itself is CONSTANT (never reassigned); the object it
|
||||
// points to is what actually changes.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#define CFG_PROPERTY(type, name, Name) \
|
||||
Q_PROPERTY(type name READ name WRITE set##Name NOTIFY Name##Changed) \
|
||||
public: \
|
||||
type name() const { return m_##name; } \
|
||||
void set##Name(const type &value) { \
|
||||
if (m_##name == value) return; \
|
||||
m_##name = value; \
|
||||
Q_EMIT Name##Changed(); \
|
||||
} \
|
||||
Q_SIGNALS: \
|
||||
void Name##Changed(); \
|
||||
private: \
|
||||
type m_##name{};
|
||||
|
||||
#define CFG_SECTION(Type, name, Name) \
|
||||
public: \
|
||||
Q_PROPERTY(Type *name READ name CONSTANT) \
|
||||
Type *name() const { return m_##name; } \
|
||||
private: \
|
||||
Type *m_##name = nullptr;
|
||||
|
||||
class ConfigSection : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConfigSection(QObject *parent = nullptr);
|
||||
|
||||
// Populate this section (and all child sections) from JSON. Unknown
|
||||
// keys in obj are ignored; missing keys keep their current value.
|
||||
void fromJson(const QJsonObject &obj);
|
||||
// Serialize this section (and all child sections) to JSON.
|
||||
QJsonObject toJson() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
// Emitted whenever any property in this section, or any nested section,
|
||||
// changes. Config listens on the root section to know a save is needed,
|
||||
// without every leaf class needing to know about Config.
|
||||
void changed();
|
||||
|
||||
protected:
|
||||
// Call once, at the end of every subclass constructor, after all child
|
||||
// ConfigSection* members have been constructed (new'd with `this` as
|
||||
// parent). Sets up the reflection-based signal forwarding.
|
||||
void wireSignals();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onPropertyChanged();
|
||||
|
||||
private:
|
||||
bool m_wired = false;
|
||||
};
|
||||
Reference in New Issue
Block a user