changes to config plugin, reduce file amount + code, fix greeter
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
#include "Appearance.hpp"
|
||||
|
||||
Anim::Anim(QObject *parent) : ConfigSection(parent) {
|
||||
m_mediaGifSpeedAdjustment = 300;
|
||||
m_sessionGifSpeed = 0.7;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Deform::Deform(QObject *parent) : ConfigSection(parent) {
|
||||
m_scale = 1;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
FontFamily::FontFamily(QObject *parent) : ConfigSection(parent) {
|
||||
m_clock = QStringLiteral("Rubik");
|
||||
m_material = QStringLiteral("Material Symbols Rounded");
|
||||
m_mono = QStringLiteral("SegoeUI Variable");
|
||||
m_sans = QStringLiteral("SegoeUI Variable");
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Font::Font(QObject *parent) : ConfigSection(parent) {
|
||||
m_family = new FontFamily(this);
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Transparency::Transparency(QObject *parent) : ConfigSection(parent) {
|
||||
m_base = 0.75;
|
||||
m_enabled = true;
|
||||
m_layers = 0.4;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Appearance::Appearance(QObject *parent) : ConfigSection(parent) {
|
||||
m_anim = new Anim(this);
|
||||
m_deform = new Deform(this);
|
||||
m_font = new Font(this);
|
||||
m_transparency = new Transparency(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
// NOTE: multiple classes per file is fine - moc processes every Q_OBJECT
|
||||
// class it finds in a header, regardless of how many. Config.appearance.anim
|
||||
// works purely through object composition (Appearance owns an Anim*), which
|
||||
// has nothing to do with how the files are split.
|
||||
|
||||
class Anim : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, mediaGifSpeedAdjustment, MediaGifSpeedAdjustment)
|
||||
CFG_PROPERTY(qreal, sessionGifSpeed, SessionGifSpeed)
|
||||
|
||||
public:
|
||||
explicit Anim(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Deform : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(qreal, scale, Scale)
|
||||
|
||||
public:
|
||||
explicit Deform(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class FontFamily : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(QString, clock, Clock)
|
||||
CFG_PROPERTY(QString, material, Material)
|
||||
CFG_PROPERTY(QString, mono, Mono)
|
||||
CFG_PROPERTY(QString, sans, Sans)
|
||||
|
||||
public:
|
||||
explicit FontFamily(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Font : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_SECTION(FontFamily, family, Family)
|
||||
|
||||
public:
|
||||
explicit Font(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Transparency : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(qreal, base, Base)
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(qreal, layers, Layers)
|
||||
|
||||
public:
|
||||
explicit Transparency(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Appearance : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_SECTION(Anim, anim, Anim)
|
||||
CFG_SECTION(Deform, deform, Deform)
|
||||
CFG_SECTION(Font, font, Font)
|
||||
CFG_SECTION(Transparency, transparency, Transparency)
|
||||
|
||||
public:
|
||||
explicit Appearance(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "Background.hpp"
|
||||
|
||||
Background::Background(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = true;
|
||||
m_wallFadeDuration = 300;
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class Background : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(int, wallFadeDuration, WallFadeDuration)
|
||||
|
||||
public:
|
||||
explicit Background(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,63 +0,0 @@
|
||||
#include "Bar.hpp"
|
||||
|
||||
namespace {
|
||||
QVariantMap entry(bool enabled, const char *id) {
|
||||
QVariantMap m;
|
||||
m["enabled"] = enabled;
|
||||
m["id"] = QString::fromLatin1(id);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
Popouts::Popouts(QObject *parent) : ConfigSection(parent) {
|
||||
m_statusIcons = true;
|
||||
m_tray = true;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Tray::Tray(QObject *parent) : ConfigSection(parent) {
|
||||
m_recolorIcons = false;
|
||||
m_showOnHover = true;
|
||||
m_statusIcons = {
|
||||
entry(true, "audio"),
|
||||
entry(true, "microphone"),
|
||||
entry(true, "bluetooth"),
|
||||
entry(false, "network"),
|
||||
entry(false, "wifi"),
|
||||
entry(true, "power"),
|
||||
};
|
||||
m_trayIconSize = 24;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Bar::Bar(QObject *parent) : ConfigSection(parent) {
|
||||
m_autoHide = false;
|
||||
m_border = 4;
|
||||
m_entries = {
|
||||
entry(true, "workspaces"),
|
||||
entry(true, "audio"),
|
||||
entry(true, "media"),
|
||||
entry(true, "resources"),
|
||||
entry(true, "updates"),
|
||||
entry(false, "dash"),
|
||||
entry(true, "spacer"),
|
||||
entry(true, "activeWindow"),
|
||||
entry(true, "spacer"),
|
||||
entry(true, "hyprsunset"),
|
||||
entry(true, "tray"),
|
||||
entry(true, "statusIcons"),
|
||||
entry(false, "network"),
|
||||
entry(true, "upower"),
|
||||
entry(true, "clock"),
|
||||
entry(true, "notifBell"),
|
||||
};
|
||||
m_fullscreenReveal = true;
|
||||
m_height = 24;
|
||||
m_hideWhenNotif = true;
|
||||
m_popouts = new Popouts(this);
|
||||
m_revealDelay = 100;
|
||||
m_rounding = 14;
|
||||
m_smoothing = 32;
|
||||
m_tray = new Tray(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class Popouts : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, statusIcons, StatusIcons)
|
||||
CFG_PROPERTY(bool, tray, Tray)
|
||||
|
||||
public:
|
||||
explicit Popouts(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Tray : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, recolorIcons, RecolorIcons)
|
||||
CFG_PROPERTY(bool, showOnHover, ShowOnHover)
|
||||
// Array of { enabled, id } objects. QML can't mutate array elements in
|
||||
// place - assign the whole list back to change it, e.g.
|
||||
// Config.bar.tray.statusIcons = updatedList
|
||||
CFG_PROPERTY(QVariantList, statusIcons, StatusIcons)
|
||||
CFG_PROPERTY(int, trayIconSize, TrayIconSize)
|
||||
|
||||
public:
|
||||
explicit Tray(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Bar : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, autoHide, AutoHide)
|
||||
CFG_PROPERTY(int, border, Border)
|
||||
// Array of { enabled, id } objects, in display order.
|
||||
CFG_PROPERTY(QVariantList, entries, Entries)
|
||||
CFG_PROPERTY(bool, fullscreenReveal, FullscreenReveal)
|
||||
CFG_PROPERTY(int, height, Height)
|
||||
CFG_PROPERTY(bool, hideWhenNotif, HideWhenNotif)
|
||||
CFG_SECTION(Popouts, popouts, Popouts)
|
||||
CFG_PROPERTY(int, revealDelay, RevealDelay)
|
||||
CFG_PROPERTY(int, rounding, Rounding)
|
||||
CFG_PROPERTY(int, smoothing, Smoothing)
|
||||
CFG_SECTION(Tray, tray, Tray)
|
||||
|
||||
public:
|
||||
explicit Bar(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,24 +1,25 @@
|
||||
qml_module(ZShell-config
|
||||
URI ZShell.Config
|
||||
SOURCES
|
||||
ConfigSection.hpp ConfigSection.cpp
|
||||
Config.hpp Config.cpp
|
||||
Tokens.hpp Tokens.cpp
|
||||
Appearance.hpp Appearance.cpp
|
||||
Background.hpp Background.cpp
|
||||
Bar.hpp Bar.cpp
|
||||
Clipboard.hpp Clipboard.cpp
|
||||
Colors.hpp Colors.cpp
|
||||
Dashboard.hpp Dashboard.cpp
|
||||
Dock.hpp Dock.cpp
|
||||
General.hpp General.cpp
|
||||
Launcher.hpp Launcher.cpp
|
||||
Lock.hpp Lock.cpp
|
||||
Notifs.hpp Notifs.cpp
|
||||
Osd.hpp Osd.cpp
|
||||
Overview.hpp Overview.cpp
|
||||
Screenshot.hpp Screenshot.cpp
|
||||
Services.hpp Services.cpp
|
||||
Sidebar.hpp Sidebar.cpp
|
||||
Utilities.hpp Utilities.cpp
|
||||
confignode.hpp confignode.cpp
|
||||
configobject.hpp configobject.cpp
|
||||
configlist.hpp configlist.cpp
|
||||
config.hpp config.cpp
|
||||
tokens.hpp
|
||||
appearance.hpp
|
||||
background.hpp
|
||||
bar.hpp
|
||||
clipboard.hpp
|
||||
colors.hpp
|
||||
dashboard.hpp
|
||||
dock.hpp
|
||||
general.hpp
|
||||
launcher.hpp
|
||||
lock.hpp
|
||||
notifs.hpp
|
||||
osd.hpp
|
||||
screenshot.hpp
|
||||
services.hpp
|
||||
sidebar.hpp
|
||||
utilities.hpp
|
||||
)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include "Clipboard.hpp"
|
||||
|
||||
ClipboardSizes::ClipboardSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_itemHeight = 60;
|
||||
m_minPreviewWidth = 200;
|
||||
m_previewWidth = 800;
|
||||
m_width = 500;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Clipboard::Clipboard(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = true;
|
||||
m_maxEntriesShown = 10;
|
||||
m_sizes = new ClipboardSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class ClipboardSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, itemHeight, ItemHeight)
|
||||
CFG_PROPERTY(int, minPreviewWidth, MinPreviewWidth)
|
||||
CFG_PROPERTY(int, previewWidth, PreviewWidth)
|
||||
CFG_PROPERTY(int, width, Width)
|
||||
|
||||
public:
|
||||
explicit ClipboardSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Clipboard : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(int, maxEntriesShown, MaxEntriesShown)
|
||||
CFG_SECTION(ClipboardSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Clipboard(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
#include "Colors.hpp"
|
||||
|
||||
Presets::Presets(QObject *parent) : ConfigSection(parent) {
|
||||
m_accent = QString();
|
||||
m_name = QStringLiteral("Catppuccin");
|
||||
m_variant = QStringLiteral("latte");
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Colors::Colors(QObject *parent) : ConfigSection(parent) {
|
||||
m_presets = new Presets(this);
|
||||
m_schemeType = QStringLiteral("fidelity");
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class Presets : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(QString, accent, Accent)
|
||||
CFG_PROPERTY(QString, name, Name)
|
||||
CFG_PROPERTY(QString, variant, Variant)
|
||||
|
||||
public:
|
||||
explicit Presets(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Colors : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_SECTION(Presets, presets, Presets)
|
||||
CFG_PROPERTY(QString, schemeType, SchemeType)
|
||||
|
||||
public:
|
||||
explicit Colors(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,86 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QTimer>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QFuture>
|
||||
|
||||
#include "Appearance.hpp"
|
||||
#include "Background.hpp"
|
||||
#include "Bar.hpp"
|
||||
#include "Clipboard.hpp"
|
||||
#include "Colors.hpp"
|
||||
#include "Dashboard.hpp"
|
||||
#include "Dock.hpp"
|
||||
#include "General.hpp"
|
||||
#include "Launcher.hpp"
|
||||
#include "Lock.hpp"
|
||||
#include "Notifs.hpp"
|
||||
#include "Osd.hpp"
|
||||
#include "Overview.hpp"
|
||||
#include "Screenshot.hpp"
|
||||
#include "Services.hpp"
|
||||
#include "Sidebar.hpp"
|
||||
#include "Utilities.hpp"
|
||||
|
||||
class QQmlEngine;
|
||||
class QJSEngine;
|
||||
|
||||
// The central hub. Exposed to QML as a singleton, so `Config.appearance.
|
||||
// anim.sessionGifSpeed` just works from anywhere without an import context
|
||||
// juggle. Every top-level JSON key is a CFG_SECTION child object; the
|
||||
// generic load()/save() logic lives entirely in ConfigSection, this class
|
||||
// only adds: the file path, the debounced/atomic write, and the QML
|
||||
// singleton factory.
|
||||
class Config : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
CFG_SECTION(Appearance, appearance, Appearance)
|
||||
CFG_SECTION(Background, background, Background)
|
||||
CFG_SECTION(Bar, bar, Bar)
|
||||
CFG_SECTION(Clipboard, clipboard, Clipboard)
|
||||
CFG_SECTION(Colors, colors, Colors)
|
||||
CFG_SECTION(Dashboard, dashboard, Dashboard)
|
||||
CFG_SECTION(Dock, dock, Dock)
|
||||
CFG_SECTION(General, general, General)
|
||||
CFG_SECTION(Launcher, launcher, Launcher)
|
||||
CFG_SECTION(Lock, lock, Lock)
|
||||
CFG_SECTION(Notifs, notifs, Notifs)
|
||||
CFG_SECTION(Osd, osd, Osd)
|
||||
CFG_SECTION(Overview, overview, Overview)
|
||||
CFG_SECTION(Screenshot, screenshot, Screenshot)
|
||||
CFG_SECTION(Services, services, Services)
|
||||
CFG_SECTION(Sidebar, sidebar, Sidebar)
|
||||
CFG_SECTION(Utilities, utilities, Utilities)
|
||||
|
||||
public:
|
||||
explicit Config(QObject* parent = nullptr);
|
||||
static Config* create(QQmlEngine*, QJSEngine*);
|
||||
|
||||
// Reload from disk, discarding any unsaved in-memory changes.
|
||||
// Synchronous for first load on startup, async for subsequent reloads.
|
||||
Q_INVOKABLE void load();
|
||||
// Force an immediate synchronous write, bypassing the debounce timer.
|
||||
// Call this from your shell's shutdown handler so nothing gets lost.
|
||||
Q_INVOKABLE void saveNow();
|
||||
// Reload from disk asynchronously (for file change notifications).
|
||||
Q_INVOKABLE void reloadAsync();
|
||||
|
||||
private Q_SLOTS:
|
||||
void scheduleSave();
|
||||
void flushAsync();
|
||||
|
||||
private:
|
||||
QString filePath() const;
|
||||
void writeAtomically(const QByteArray& data);
|
||||
void loadSync();
|
||||
void loadAsync();
|
||||
|
||||
QTimer m_saveTimer;
|
||||
bool m_loading = false;
|
||||
bool m_firstLoadDone = false;
|
||||
QFuture<void> m_loadFuture;
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
#include "ConfigSection.hpp"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
|
||||
namespace {
|
||||
// Property index to start scanning from - skips QObject's own "objectName"
|
||||
// property, which we never want in the JSON.
|
||||
int firstOwnProperty() {
|
||||
return QObject::staticMetaObject.propertyCount();
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSection::ConfigSection(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void ConfigSection::wireSignals() {
|
||||
if (m_wired) return;
|
||||
m_wired = true;
|
||||
|
||||
const QMetaObject *mo = metaObject();
|
||||
const int slotIdx = mo->indexOfSlot("onPropertyChanged()");
|
||||
Q_ASSERT(slotIdx != -1);
|
||||
const QMetaMethod slot = mo->method(slotIdx);
|
||||
|
||||
const int start = firstOwnProperty();
|
||||
for (int i = start; i < mo->propertyCount(); ++i) {
|
||||
const QMetaProperty prop = mo->property(i);
|
||||
|
||||
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
|
||||
// Child sections bubble their changes straight up as our
|
||||
// own changed() - no need to also react to our own notify.
|
||||
connect(child, &ConfigSection::changed, this, &ConfigSection::changed);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.hasNotifySignal())
|
||||
connect(this, prop.notifySignal(), this, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigSection::onPropertyChanged() {
|
||||
Q_EMIT changed();
|
||||
}
|
||||
|
||||
void ConfigSection::fromJson(const QJsonObject &obj) {
|
||||
const QMetaObject *mo = metaObject();
|
||||
const int start = firstOwnProperty();
|
||||
|
||||
for (int i = start; i < mo->propertyCount(); ++i) {
|
||||
const QMetaProperty prop = mo->property(i);
|
||||
const QLatin1String name(prop.name());
|
||||
|
||||
if (!obj.contains(name)) continue;
|
||||
|
||||
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
|
||||
child->fromJson(obj.value(name).toObject());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.isWritable())
|
||||
prop.write(this, obj.value(name).toVariant());
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject ConfigSection::toJson() const {
|
||||
QJsonObject obj;
|
||||
const QMetaObject *mo = metaObject();
|
||||
const int start = firstOwnProperty();
|
||||
|
||||
for (int i = start; i < mo->propertyCount(); ++i) {
|
||||
const QMetaProperty prop = mo->property(i);
|
||||
|
||||
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
if (auto *child = qobject_cast<ConfigSection *>(prop.read(this).value<QObject *>())) {
|
||||
obj.insert(QLatin1String(prop.name()), child->toJson());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
obj.insert(QLatin1String(prop.name()), QJsonValue::fromVariant(prop.read(this)));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
#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;
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
#include "Dashboard.hpp"
|
||||
|
||||
Performance::Performance(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = true;
|
||||
m_showBattery = false;
|
||||
m_showCpu = true;
|
||||
m_showGpu = true;
|
||||
m_showMemory = true;
|
||||
m_showNetwork = true;
|
||||
m_showStorage = true;
|
||||
m_showVram = true;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
DashboardSizes::DashboardSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_dateTimeWidth = 110;
|
||||
m_infoIconSize = 25;
|
||||
m_infoWidth = 200;
|
||||
m_mediaCoverArtSize = 150;
|
||||
m_mediaProgressSweep = 180;
|
||||
m_mediaProgressThickness = 8;
|
||||
m_mediaVisualizerSize = 200;
|
||||
m_mediaWidth = 200;
|
||||
m_resourceProgessThickness = 10;
|
||||
m_resourceSize = 200;
|
||||
m_tabIndicatorHeight = 3;
|
||||
m_tabIndicatorSpacing = 5;
|
||||
m_weatherWidth = 250;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Dashboard::Dashboard(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = true;
|
||||
m_mediaUpdateInterval = 2000;
|
||||
m_performance = new Performance(this);
|
||||
m_resourceUpdateInterval = 1000;
|
||||
m_sizes = new DashboardSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class Performance : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(bool, showBattery, ShowBattery)
|
||||
CFG_PROPERTY(bool, showCpu, ShowCpu)
|
||||
CFG_PROPERTY(bool, showGpu, ShowGpu)
|
||||
CFG_PROPERTY(bool, showMemory, ShowMemory)
|
||||
CFG_PROPERTY(bool, showNetwork, ShowNetwork)
|
||||
CFG_PROPERTY(bool, showStorage, ShowStorage)
|
||||
CFG_PROPERTY(bool, showVram, ShowVram)
|
||||
|
||||
public:
|
||||
explicit Performance(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class DashboardSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, dateTimeWidth, DateTimeWidth)
|
||||
CFG_PROPERTY(int, infoIconSize, InfoIconSize)
|
||||
CFG_PROPERTY(int, infoWidth, InfoWidth)
|
||||
CFG_PROPERTY(int, mediaCoverArtSize, MediaCoverArtSize)
|
||||
CFG_PROPERTY(int, mediaProgressSweep, MediaProgressSweep)
|
||||
CFG_PROPERTY(int, mediaProgressThickness, MediaProgressThickness)
|
||||
CFG_PROPERTY(int, mediaVisualizerSize, MediaVisualizerSize)
|
||||
CFG_PROPERTY(int, mediaWidth, MediaWidth)
|
||||
CFG_PROPERTY(int, resourceProgessThickness, ResourceProgessThickness)
|
||||
CFG_PROPERTY(int, resourceSize, ResourceSize)
|
||||
CFG_PROPERTY(int, tabIndicatorHeight, TabIndicatorHeight)
|
||||
CFG_PROPERTY(int, tabIndicatorSpacing, TabIndicatorSpacing)
|
||||
CFG_PROPERTY(int, weatherWidth, WeatherWidth)
|
||||
|
||||
public:
|
||||
explicit DashboardSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Dashboard : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(int, mediaUpdateInterval, MediaUpdateInterval)
|
||||
CFG_SECTION(Performance, performance, Performance)
|
||||
CFG_PROPERTY(int, resourceUpdateInterval, ResourceUpdateInterval)
|
||||
CFG_SECTION(DashboardSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Dashboard(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "Dock.hpp"
|
||||
|
||||
Dock::Dock(QObject *parent) : ConfigSection(parent) {
|
||||
m_enable = false;
|
||||
m_height = 80;
|
||||
m_hoverToReveal = false;
|
||||
m_ignoredAppRegexes = {};
|
||||
m_pinnedApps = {
|
||||
QStringLiteral("com.ayugram.desktop"),
|
||||
QStringLiteral("com.obsproject.studio"),
|
||||
QStringLiteral("librewolf"),
|
||||
};
|
||||
m_pinnedOnStartup = false;
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class Dock : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enable, Enable)
|
||||
CFG_PROPERTY(int, height, Height)
|
||||
CFG_PROPERTY(bool, hoverToReveal, HoverToReveal)
|
||||
CFG_PROPERTY(QVariantList, ignoredAppRegexes, IgnoredAppRegexes)
|
||||
CFG_PROPERTY(QVariantList, pinnedApps, PinnedApps)
|
||||
CFG_PROPERTY(bool, pinnedOnStartup, PinnedOnStartup)
|
||||
|
||||
public:
|
||||
explicit Dock(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,77 +0,0 @@
|
||||
#include "General.hpp"
|
||||
|
||||
namespace {
|
||||
QVariantList strList(std::initializer_list<const char *> items) {
|
||||
QVariantList list;
|
||||
for (auto *item : items) list << QString::fromLatin1(item);
|
||||
return list;
|
||||
}
|
||||
|
||||
QVariantMap threshold(const char *icon, const char *message, const char *name, int perc) {
|
||||
QVariantMap m;
|
||||
m["icon"] = QString::fromLatin1(icon);
|
||||
m["message"] = QString::fromLatin1(message);
|
||||
m["name"] = QString::fromLatin1(name);
|
||||
m["perc"] = perc;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
Apps::Apps(QObject *parent) : ConfigSection(parent) {
|
||||
m_archiver = strList({"ark"});
|
||||
m_audio = strList({"pavucontrol"});
|
||||
m_document = strList({"libreoffice"});
|
||||
m_editor = strList({"kate"});
|
||||
m_explorer = strList({"dolphin"});
|
||||
m_image = strList({"imv"});
|
||||
m_playback = strList({"vlc"});
|
||||
m_terminal = strList({"wezterm"});
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Battery::Battery(QObject *parent) : ConfigSection(parent) {
|
||||
m_critPerc = 5;
|
||||
m_popupThresholds = {
|
||||
threshold("battery_android_frame_2", "Battery low", "Low battery", 20),
|
||||
threshold("battery_android_frame_2", "Battery lower", "Low battery", 15),
|
||||
threshold("battery_android_frame_2", "Battery lowest", "Low battery", 10),
|
||||
};
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
ColorSettings::ColorSettings(QObject *parent) : ConfigSection(parent) {
|
||||
m_hyprsunsetTemp = 2600;
|
||||
m_mode = QStringLiteral("dark");
|
||||
m_neovimColors = false;
|
||||
m_scheduleDark = false;
|
||||
m_scheduleDarkEnd = 600;
|
||||
m_scheduleDarkStart = 1140;
|
||||
m_scheduleHyprsunset = true;
|
||||
m_scheduleHyprsunsetEnd = 570;
|
||||
m_scheduleHyprsunsetStart = 1200;
|
||||
m_schemeGeneration = true;
|
||||
m_smart = false;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Idle::Idle(QObject *parent) : ConfigSection(parent) {
|
||||
QVariantMap lock;
|
||||
lock["idleAction"] = QStringLiteral("lock");
|
||||
lock["name"] = QStringLiteral("Lock");
|
||||
lock["timeout"] = 180;
|
||||
m_timeouts = { lock };
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
General::General(QObject *parent) : ConfigSection(parent) {
|
||||
m_apps = new Apps(this);
|
||||
m_battery = new Battery(this);
|
||||
m_color = new ColorSettings(this);
|
||||
m_dateFormat = QStringLiteral("ddd d MMM - hh:mm:ss");
|
||||
m_desktopIcons = true;
|
||||
m_idle = new Idle(this);
|
||||
m_logo = QString();
|
||||
m_showOverFullscreen = true;
|
||||
m_wallpaperPath = QStringLiteral("/mnt/IronWolf/SDImages/SWWW_Wals/");
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class Apps : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(QVariantList, archiver, Archiver)
|
||||
CFG_PROPERTY(QVariantList, audio, Audio)
|
||||
CFG_PROPERTY(QVariantList, document, Document)
|
||||
CFG_PROPERTY(QVariantList, editor, Editor)
|
||||
CFG_PROPERTY(QVariantList, explorer, Explorer)
|
||||
CFG_PROPERTY(QVariantList, image, Image)
|
||||
CFG_PROPERTY(QVariantList, playback, Playback)
|
||||
CFG_PROPERTY(QVariantList, terminal, Terminal)
|
||||
|
||||
public:
|
||||
explicit Apps(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Battery : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, critPerc, CritPerc)
|
||||
// Array of { icon, message, name, perc } objects.
|
||||
CFG_PROPERTY(QVariantList, popupThresholds, PopupThresholds)
|
||||
|
||||
public:
|
||||
explicit Battery(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class ColorSettings : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, hyprsunsetTemp, HyprsunsetTemp)
|
||||
CFG_PROPERTY(QString, mode, Mode)
|
||||
CFG_PROPERTY(bool, neovimColors, NeovimColors)
|
||||
CFG_PROPERTY(bool, scheduleDark, ScheduleDark)
|
||||
CFG_PROPERTY(int, scheduleDarkEnd, ScheduleDarkEnd)
|
||||
CFG_PROPERTY(int, scheduleDarkStart, ScheduleDarkStart)
|
||||
CFG_PROPERTY(bool, scheduleHyprsunset, ScheduleHyprsunset)
|
||||
CFG_PROPERTY(int, scheduleHyprsunsetEnd, ScheduleHyprsunsetEnd)
|
||||
CFG_PROPERTY(int, scheduleHyprsunsetStart, ScheduleHyprsunsetStart)
|
||||
CFG_PROPERTY(bool, schemeGeneration, SchemeGeneration)
|
||||
CFG_PROPERTY(bool, smart, Smart)
|
||||
|
||||
public:
|
||||
explicit ColorSettings(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Idle : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
// Array of { idleAction, name, timeout } objects.
|
||||
CFG_PROPERTY(QVariantList, timeouts, Timeouts)
|
||||
|
||||
public:
|
||||
explicit Idle(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class General : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_SECTION(Apps, apps, Apps)
|
||||
CFG_SECTION(Battery, battery, Battery)
|
||||
CFG_SECTION(ColorSettings, color, Color)
|
||||
CFG_PROPERTY(QString, dateFormat, DateFormat)
|
||||
CFG_PROPERTY(bool, desktopIcons, DesktopIcons)
|
||||
CFG_SECTION(Idle, idle, Idle)
|
||||
CFG_PROPERTY(QString, logo, Logo)
|
||||
CFG_PROPERTY(bool, showOverFullscreen, ShowOverFullscreen)
|
||||
CFG_PROPERTY(QString, wallpaperPath, WallpaperPath)
|
||||
|
||||
public:
|
||||
explicit General(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
#include "Launcher.hpp"
|
||||
|
||||
namespace {
|
||||
QVariantList strList(std::initializer_list<const char *> items) {
|
||||
QVariantList list;
|
||||
for (auto *item : items) list << QString::fromLatin1(item);
|
||||
return list;
|
||||
}
|
||||
|
||||
QVariantMap action(QVariantList command, bool dangerous, const char *description,
|
||||
bool enabled, const char *icon, const char *name) {
|
||||
QVariantMap m;
|
||||
m["command"] = std::move(command);
|
||||
m["dangerous"] = dangerous;
|
||||
m["description"] = QString::fromLatin1(description);
|
||||
m["enabled"] = enabled;
|
||||
m["icon"] = QString::fromLatin1(icon);
|
||||
m["name"] = QString::fromLatin1(name);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
LauncherSizes::LauncherSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_itemHeight = 50;
|
||||
m_itemWidth = 600;
|
||||
m_wallpaperHeight = 200;
|
||||
m_wallpaperWidth = 280;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
UseFuzzy::UseFuzzy(QObject *parent) : ConfigSection(parent) {
|
||||
m_actions = true;
|
||||
m_apps = true;
|
||||
m_schemes = true;
|
||||
m_variants = true;
|
||||
m_wallpapers = true;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Launcher::Launcher(QObject *parent) : ConfigSection(parent) {
|
||||
m_actionPrefix = QStringLiteral("<");
|
||||
m_actions = {
|
||||
action(strList({"autocomplete", "calc"}), false, "Do simple math equations", true, "calculate", "Calculator"),
|
||||
action(strList({"setMode", "light"}), false, "Change to light mode", true, "light_mode", "Light"),
|
||||
action(strList({"setMode", "dark"}), false, "Change to dark mode", true, "dark_mode", "Dark"),
|
||||
action(strList({"autocomplete", "wallpaper"}), false, "Change the current wallpaper", true, "image", "Wallpaper"),
|
||||
action(strList({"autocomplete", "variant"}), false, "Change the current scheme variant", true, "colors", "Variant"),
|
||||
action(strList({"systemctl", "poweroff"}), true, "Shutdown the system", true, "power_settings_new", "Shutdown"),
|
||||
action(strList({"systemctl", "reboot"}), true, "Reboot the system", true, "cached", "Reboot"),
|
||||
action(strList({"loginctl", "terminate-user", ""}), true, "Log out of the current session", true, "logout", "Logout"),
|
||||
action(strList({"loginctl", "lock-session"}), false, "Lock the current session", true, "lock", "Lock"),
|
||||
action(strList({"systemctl", "suspend-then-hibernate"}), false, "Suspend then hibernate", true, "bedtime", "Sleep"),
|
||||
};
|
||||
m_dragThreshold = 150;
|
||||
m_enableDangerousActions = true;
|
||||
m_enabled = true;
|
||||
m_favoriteApps = strList({"Balatro", "Slay the Spire 2", "com.obsproject.Studio"});
|
||||
m_hiddenApps = strList({
|
||||
"zellij", "vim", "jshell-java-openjdk", "jconsole-java-openjdk",
|
||||
"jshell-java21-openjdk", "jconsole-java21-openjdk", "jshell-java17-openjdk",
|
||||
"jconsole-java17-openjdk", "org.neovim.nvim", "avahi-discover", "bvnc",
|
||||
"bssh", "nm-connection-editor",
|
||||
});
|
||||
m_maxAppsShown = 18;
|
||||
m_maxWallpapers = 7;
|
||||
m_sizes = new LauncherSizes(this);
|
||||
m_specialPrefix = QStringLiteral("@");
|
||||
m_useFuzzy = new UseFuzzy(this);
|
||||
m_uwsm = true;
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class LauncherSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, itemHeight, ItemHeight)
|
||||
CFG_PROPERTY(int, itemWidth, ItemWidth)
|
||||
CFG_PROPERTY(int, wallpaperHeight, WallpaperHeight)
|
||||
CFG_PROPERTY(int, wallpaperWidth, WallpaperWidth)
|
||||
|
||||
public:
|
||||
explicit LauncherSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class UseFuzzy : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, actions, Actions)
|
||||
CFG_PROPERTY(bool, apps, Apps)
|
||||
CFG_PROPERTY(bool, schemes, Schemes)
|
||||
CFG_PROPERTY(bool, variants, Variants)
|
||||
CFG_PROPERTY(bool, wallpapers, Wallpapers)
|
||||
|
||||
public:
|
||||
explicit UseFuzzy(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Launcher : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(QString, actionPrefix, ActionPrefix)
|
||||
// Array of action-definition objects (command, dangerous, description,
|
||||
// enabled, icon, name).
|
||||
CFG_PROPERTY(QVariantList, actions, Actions)
|
||||
CFG_PROPERTY(int, dragThreshold, DragThreshold)
|
||||
CFG_PROPERTY(bool, enableDangerousActions, EnableDangerousActions)
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(QVariantList, favoriteApps, FavoriteApps)
|
||||
CFG_PROPERTY(QVariantList, hiddenApps, HiddenApps)
|
||||
CFG_PROPERTY(int, maxAppsShown, MaxAppsShown)
|
||||
CFG_PROPERTY(int, maxWallpapers, MaxWallpapers)
|
||||
CFG_SECTION(LauncherSizes, sizes, Sizes)
|
||||
CFG_PROPERTY(QString, specialPrefix, SpecialPrefix)
|
||||
CFG_SECTION(UseFuzzy, useFuzzy, UseFuzzy)
|
||||
CFG_PROPERTY(bool, uwsm, Uwsm)
|
||||
|
||||
public:
|
||||
explicit Launcher(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
#include "Lock.hpp"
|
||||
|
||||
LockSizes::LockSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_centerWidth = 600;
|
||||
m_heightMult = 0.7;
|
||||
m_ratio = 1.78;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Lock::Lock(QObject *parent) : ConfigSection(parent) {
|
||||
m_blurAmount = 10;
|
||||
m_enableFprint = true;
|
||||
m_maxFprintTries = 3;
|
||||
m_recolorLogo = false;
|
||||
m_showNotifContent = true;
|
||||
m_showNotifIcon = true;
|
||||
m_sizes = new LockSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class LockSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, centerWidth, CenterWidth)
|
||||
CFG_PROPERTY(qreal, heightMult, HeightMult)
|
||||
CFG_PROPERTY(qreal, ratio, Ratio)
|
||||
|
||||
public:
|
||||
explicit LockSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Lock : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, blurAmount, BlurAmount)
|
||||
CFG_PROPERTY(bool, enableFprint, EnableFprint)
|
||||
CFG_PROPERTY(int, maxFprintTries, MaxFprintTries)
|
||||
CFG_PROPERTY(bool, recolorLogo, RecolorLogo)
|
||||
CFG_PROPERTY(bool, showNotifContent, ShowNotifContent)
|
||||
CFG_PROPERTY(bool, showNotifIcon, ShowNotifIcon)
|
||||
CFG_SECTION(LockSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Lock(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
#include "Notifs.hpp"
|
||||
|
||||
NotifsSizes::NotifsSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_badge = 20;
|
||||
m_image = 41;
|
||||
m_width = 400;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Notifs::Notifs(QObject *parent) : ConfigSection(parent) {
|
||||
m_actionOnClick = false;
|
||||
m_appNotifCooldown = 0;
|
||||
m_clearThreshold = 0.3;
|
||||
m_defaultExpireTimeout = 5000;
|
||||
m_expandThreshold = 20;
|
||||
m_expire = true;
|
||||
m_groupPreviewNum = 5;
|
||||
m_openExpanded = false;
|
||||
m_showInFullscreen = false;
|
||||
m_sizes = new NotifsSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class NotifsSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, badge, Badge)
|
||||
CFG_PROPERTY(int, image, Image)
|
||||
CFG_PROPERTY(int, width, Width)
|
||||
|
||||
public:
|
||||
explicit NotifsSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Notifs : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, actionOnClick, ActionOnClick)
|
||||
CFG_PROPERTY(int, appNotifCooldown, AppNotifCooldown)
|
||||
CFG_PROPERTY(qreal, clearThreshold, ClearThreshold)
|
||||
CFG_PROPERTY(int, defaultExpireTimeout, DefaultExpireTimeout)
|
||||
CFG_PROPERTY(int, expandThreshold, ExpandThreshold)
|
||||
CFG_PROPERTY(bool, expire, Expire)
|
||||
CFG_PROPERTY(int, groupPreviewNum, GroupPreviewNum)
|
||||
CFG_PROPERTY(bool, openExpanded, OpenExpanded)
|
||||
CFG_PROPERTY(bool, showInFullscreen, ShowInFullscreen)
|
||||
CFG_SECTION(NotifsSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Notifs(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
#include "Osd.hpp"
|
||||
|
||||
OsdSizes::OsdSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_sliderHeight = 150;
|
||||
m_sliderWidth = 30;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Osd::Osd(QObject *parent) : ConfigSection(parent) {
|
||||
m_allMonBrightness = true;
|
||||
m_enableBrightness = true;
|
||||
m_enableMicrophone = true;
|
||||
m_enabled = true;
|
||||
m_hideDelay = 3000;
|
||||
m_sizes = new OsdSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class OsdSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, sliderHeight, SliderHeight)
|
||||
CFG_PROPERTY(int, sliderWidth, SliderWidth)
|
||||
|
||||
public:
|
||||
explicit OsdSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Osd : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, allMonBrightness, AllMonBrightness)
|
||||
CFG_PROPERTY(bool, enableBrightness, EnableBrightness)
|
||||
CFG_PROPERTY(bool, enableMicrophone, EnableMicrophone)
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(int, hideDelay, HideDelay)
|
||||
CFG_SECTION(OsdSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Osd(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "Overview.hpp"
|
||||
|
||||
Overview::Overview(QObject *parent) : ConfigSection(parent) {
|
||||
m_columns = 5;
|
||||
m_enable = false;
|
||||
m_rows = 2;
|
||||
m_scale = 0.16;
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class Overview : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, columns, Columns)
|
||||
CFG_PROPERTY(bool, enable, Enable)
|
||||
CFG_PROPERTY(int, rows, Rows)
|
||||
CFG_PROPERTY(qreal, scale, Scale)
|
||||
|
||||
public:
|
||||
explicit Overview(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "Screenshot.hpp"
|
||||
|
||||
Screenshot::Screenshot(QObject *parent) : ConfigSection(parent) {
|
||||
m_enable_pp = false;
|
||||
m_mode = QStringLiteral("manual");
|
||||
m_radius = 49;
|
||||
m_rounding = false;
|
||||
m_saveOnCopy = false;
|
||||
m_shadow = true;
|
||||
m_shadow_blur = 0;
|
||||
m_shadow_color = { 0, 0, 0, 160 };
|
||||
m_shadow_offset_x = 30;
|
||||
m_shadow_offset_y = 50;
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class Screenshot : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
// Property names below must match the JSON keys exactly (the JSON here
|
||||
// uses snake_case for these particular keys, so we do too).
|
||||
CFG_PROPERTY(bool, enable_pp, EnablePp)
|
||||
CFG_PROPERTY(QString, mode, Mode)
|
||||
CFG_PROPERTY(int, radius, Radius)
|
||||
CFG_PROPERTY(bool, rounding, Rounding)
|
||||
CFG_PROPERTY(bool, saveOnCopy, SaveOnCopy)
|
||||
CFG_PROPERTY(bool, shadow, Shadow)
|
||||
CFG_PROPERTY(int, shadow_blur, ShadowBlur)
|
||||
// [r, g, b, a]
|
||||
CFG_PROPERTY(QVariantList, shadow_color, ShadowColor)
|
||||
CFG_PROPERTY(int, shadow_offset_x, ShadowOffsetX)
|
||||
CFG_PROPERTY(int, shadow_offset_y, ShadowOffsetY)
|
||||
|
||||
public:
|
||||
explicit Screenshot(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
#include "Services.hpp"
|
||||
|
||||
Services::Services(QObject *parent) : ConfigSection(parent) {
|
||||
m_audioIncrement = 0.1;
|
||||
m_brightnessIncrement = 0.1;
|
||||
m_ddcutilService = true;
|
||||
m_defaultPlayer = QStringLiteral("Spotify");
|
||||
m_gpuType = QStringLiteral("NVIDIA");
|
||||
m_maxVolume = 1;
|
||||
m_minBrightness = 0.01;
|
||||
|
||||
QVariantMap alias;
|
||||
alias["from"] = QStringLiteral("com.github.th_ch.youtube_music");
|
||||
alias["to"] = QStringLiteral("YT Music");
|
||||
m_playerAliases = { alias };
|
||||
|
||||
m_updates = true;
|
||||
m_useFahrenheit = false;
|
||||
m_useTwelveHourClock = false;
|
||||
m_visualizerBars = 50;
|
||||
m_weatherLocation = QString();
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class Services : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(qreal, audioIncrement, AudioIncrement)
|
||||
CFG_PROPERTY(qreal, brightnessIncrement, BrightnessIncrement)
|
||||
CFG_PROPERTY(bool, ddcutilService, DdcutilService)
|
||||
CFG_PROPERTY(QString, defaultPlayer, DefaultPlayer)
|
||||
CFG_PROPERTY(QString, gpuType, GpuType)
|
||||
CFG_PROPERTY(qreal, maxVolume, MaxVolume)
|
||||
CFG_PROPERTY(qreal, minBrightness, MinBrightness)
|
||||
// Array of { from, to } objects.
|
||||
CFG_PROPERTY(QVariantList, playerAliases, PlayerAliases)
|
||||
CFG_PROPERTY(bool, updates, Updates)
|
||||
CFG_PROPERTY(bool, useFahrenheit, UseFahrenheit)
|
||||
CFG_PROPERTY(bool, useTwelveHourClock, UseTwelveHourClock)
|
||||
CFG_PROPERTY(int, visualizerBars, VisualizerBars)
|
||||
CFG_PROPERTY(QString, weatherLocation, WeatherLocation)
|
||||
|
||||
public:
|
||||
explicit Services(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
#include "Sidebar.hpp"
|
||||
|
||||
SidebarSizes::SidebarSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_width = 520;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Sidebar::Sidebar(QObject *parent) : ConfigSection(parent) {
|
||||
m_dragThreshold = 30;
|
||||
m_enabled = true;
|
||||
m_sizes = new SidebarSizes(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class SidebarSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, width, Width)
|
||||
|
||||
public:
|
||||
explicit SidebarSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Sidebar : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, dragThreshold, DragThreshold)
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_SECTION(SidebarSizes, sizes, Sizes)
|
||||
|
||||
public:
|
||||
explicit Sidebar(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
#include "Tokens.hpp"
|
||||
|
||||
TokensRounding::TokensRounding(QObject* parent) : QObject(parent) {
|
||||
m_extraSmall = 4;
|
||||
m_full = 1000;
|
||||
m_large = 24;
|
||||
m_medium = 16;
|
||||
m_normal = 18;
|
||||
m_scale = 1;
|
||||
m_small = 12;
|
||||
m_smallest = 8;
|
||||
}
|
||||
|
||||
TokensPadding::TokensPadding(QObject* parent) : QObject(parent) {
|
||||
m_extraLarge = 28;
|
||||
m_extraLargeIncreased = 32;
|
||||
m_extraSmall = 4;
|
||||
m_large = 16;
|
||||
m_largeIncreased = 20;
|
||||
m_larger = 12;
|
||||
m_normal = 8;
|
||||
m_scale = 1;
|
||||
m_small = 5;
|
||||
m_smaller = 7;
|
||||
m_smallest = 2;
|
||||
}
|
||||
|
||||
TokensSpacing::TokensSpacing(QObject* parent) : QObject(parent) {
|
||||
m_extraSmall = 4;
|
||||
m_large = 20;
|
||||
m_larger = 16;
|
||||
m_normal = 12;
|
||||
m_scale = 1;
|
||||
m_small = 8;
|
||||
m_smaller = 10;
|
||||
}
|
||||
|
||||
TokensFontSize::TokensFontSize(QObject* parent) : QObject(parent) {
|
||||
m_extraLarge = 28;
|
||||
m_large = 18;
|
||||
m_larger = 16;
|
||||
m_medium = 14;
|
||||
m_normal = 13;
|
||||
m_scale = 1;
|
||||
m_small = 11;
|
||||
m_smaller = 12;
|
||||
}
|
||||
|
||||
TokensFont::TokensFont(QObject* parent) : QObject(parent) {
|
||||
m_size = new TokensFontSize(this);
|
||||
}
|
||||
|
||||
TokensAnimCurves::TokensAnimCurves(QObject* parent) : QObject(parent) {
|
||||
m_emphasized = {
|
||||
0.05,
|
||||
0,
|
||||
2.0 / 15.0,
|
||||
0.06,
|
||||
1.0 / 6.0,
|
||||
0.4,
|
||||
5.0 / 24.0,
|
||||
0.82,
|
||||
0.25,
|
||||
1,
|
||||
1,
|
||||
1};
|
||||
m_emphasizedAccel = {0.3, 0, 0.8, 0.15, 1, 1};
|
||||
m_emphasizedDecel = {0.05, 0.7, 0.1, 1, 1, 1};
|
||||
m_expressiveDefaultEffects = {0.34, 0.8, 0.34, 1, 1, 1};
|
||||
m_expressiveDefaultSpatial = {0.38, 1.21, 0.22, 1, 1, 1};
|
||||
m_expressiveEffects = {0.34, 0.8, 0.34, 1, 1, 1};
|
||||
m_expressiveFastEffects = {0.31, 0.94, 0.34, 1, 1, 1};
|
||||
m_expressiveFastSpatial = {0.42, 1.67, 0.21, 0.9, 1, 1};
|
||||
m_expressiveSlowEffects = {0.34, 0.88, 0.34, 1, 1, 1};
|
||||
m_expressiveSlowSpatial = {0.39, 1.29, 0.35, 0.98, 1, 1};
|
||||
m_standard = {0.2, 0, 0, 1, 1, 1};
|
||||
m_standardAccel = {0.3, 0, 1, 1, 1, 1};
|
||||
m_standardDecel = {0, 0, 0, 1, 1, 1};
|
||||
}
|
||||
|
||||
TokensAnimDurations::TokensAnimDurations(QObject* parent) : QObject(parent) {
|
||||
m_expressiveDefaultSpatial = 500;
|
||||
m_expressiveEffects = 200;
|
||||
m_expressiveFastEffects = 150;
|
||||
m_expressiveFastSpatial = 350;
|
||||
m_expressiveSlowEffects = 300;
|
||||
m_extraLarge = 1000;
|
||||
m_large = 600;
|
||||
m_normal = 400;
|
||||
m_scale = 1;
|
||||
m_small = 200;
|
||||
}
|
||||
|
||||
TokensAnim::TokensAnim(QObject* parent) : QObject(parent) {
|
||||
m_curves = new TokensAnimCurves(this);
|
||||
m_durations = new TokensAnimDurations(this);
|
||||
}
|
||||
|
||||
Tokens::Tokens(QObject* parent) : QObject(parent) {
|
||||
m_rounding = new TokensRounding(this);
|
||||
m_padding = new TokensPadding(this);
|
||||
m_spacing = new TokensSpacing(this);
|
||||
m_font = new TokensFont(this);
|
||||
m_anim = new TokensAnim(this);
|
||||
}
|
||||
|
||||
Tokens* Tokens::create(QQmlEngine*, QJSEngine*) {
|
||||
return new Tokens();
|
||||
}
|
||||
@@ -1,348 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <qqmlregistration.h>
|
||||
#include <QQmlEngine>
|
||||
#include <QJSEngine>
|
||||
|
||||
class TokensRounding : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
|
||||
Q_PROPERTY(qreal full READ full CONSTANT)
|
||||
Q_PROPERTY(qreal large READ large CONSTANT)
|
||||
Q_PROPERTY(qreal medium READ medium CONSTANT)
|
||||
Q_PROPERTY(qreal normal READ normal CONSTANT)
|
||||
Q_PROPERTY(qreal scale READ scale CONSTANT)
|
||||
Q_PROPERTY(qreal small READ small CONSTANT)
|
||||
Q_PROPERTY(qreal smallest READ smallest CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensRounding(QObject* parent = nullptr);
|
||||
|
||||
qreal extraSmall() const { return m_extraSmall; }
|
||||
qreal full() const { return m_full; }
|
||||
qreal large() const { return m_large; }
|
||||
qreal medium() const { return m_medium; }
|
||||
qreal normal() const { return m_normal; }
|
||||
qreal scale() const { return m_scale; }
|
||||
qreal small() const { return m_small; }
|
||||
qreal smallest() const { return m_smallest; }
|
||||
|
||||
private:
|
||||
qreal m_extraSmall;
|
||||
qreal m_full;
|
||||
qreal m_large;
|
||||
qreal m_medium;
|
||||
qreal m_normal;
|
||||
qreal m_scale;
|
||||
qreal m_small;
|
||||
qreal m_smallest;
|
||||
};
|
||||
|
||||
class TokensPadding : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(qreal extraLarge READ extraLarge CONSTANT)
|
||||
Q_PROPERTY(qreal extraLargeIncreased READ extraLargeIncreased CONSTANT)
|
||||
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
|
||||
Q_PROPERTY(qreal large READ large CONSTANT)
|
||||
Q_PROPERTY(qreal largeIncreased READ largeIncreased CONSTANT)
|
||||
Q_PROPERTY(qreal larger READ larger CONSTANT)
|
||||
Q_PROPERTY(qreal normal READ normal CONSTANT)
|
||||
Q_PROPERTY(qreal scale READ scale CONSTANT)
|
||||
Q_PROPERTY(qreal small READ small CONSTANT)
|
||||
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
|
||||
Q_PROPERTY(qreal smallest READ smallest CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensPadding(QObject* parent = nullptr);
|
||||
|
||||
qreal extraLarge() const { return m_extraLarge; }
|
||||
qreal extraLargeIncreased() const { return m_extraLargeIncreased; }
|
||||
qreal extraSmall() const { return m_extraSmall; }
|
||||
qreal large() const { return m_large; }
|
||||
qreal largeIncreased() const { return m_largeIncreased; }
|
||||
qreal larger() const { return m_larger; }
|
||||
qreal normal() const { return m_normal; }
|
||||
qreal scale() const { return m_scale; }
|
||||
qreal small() const { return m_small; }
|
||||
qreal smaller() const { return m_smaller; }
|
||||
qreal smallest() const { return m_smallest; }
|
||||
|
||||
private:
|
||||
qreal m_extraLarge;
|
||||
qreal m_extraLargeIncreased;
|
||||
qreal m_extraSmall;
|
||||
qreal m_large;
|
||||
qreal m_largeIncreased;
|
||||
qreal m_larger;
|
||||
qreal m_normal;
|
||||
qreal m_scale;
|
||||
qreal m_small;
|
||||
qreal m_smaller;
|
||||
qreal m_smallest;
|
||||
};
|
||||
|
||||
class TokensSpacing : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(qreal extraSmall READ extraSmall CONSTANT)
|
||||
Q_PROPERTY(qreal large READ large CONSTANT)
|
||||
Q_PROPERTY(qreal larger READ larger CONSTANT)
|
||||
Q_PROPERTY(qreal normal READ normal CONSTANT)
|
||||
Q_PROPERTY(qreal scale READ scale CONSTANT)
|
||||
Q_PROPERTY(qreal small READ small CONSTANT)
|
||||
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensSpacing(QObject* parent = nullptr);
|
||||
|
||||
qreal extraSmall() const { return m_extraSmall; }
|
||||
qreal large() const { return m_large; }
|
||||
qreal larger() const { return m_larger; }
|
||||
qreal normal() const { return m_normal; }
|
||||
qreal scale() const { return m_scale; }
|
||||
qreal small() const { return m_small; }
|
||||
qreal smaller() const { return m_smaller; }
|
||||
|
||||
private:
|
||||
qreal m_extraSmall;
|
||||
qreal m_large;
|
||||
qreal m_larger;
|
||||
qreal m_normal;
|
||||
qreal m_scale;
|
||||
qreal m_small;
|
||||
qreal m_smaller;
|
||||
};
|
||||
|
||||
class TokensFontSize : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(qreal extraLarge READ extraLarge CONSTANT)
|
||||
Q_PROPERTY(qreal large READ large CONSTANT)
|
||||
Q_PROPERTY(qreal larger READ larger CONSTANT)
|
||||
Q_PROPERTY(qreal medium READ medium CONSTANT)
|
||||
Q_PROPERTY(qreal normal READ normal CONSTANT)
|
||||
Q_PROPERTY(qreal scale READ scale CONSTANT)
|
||||
Q_PROPERTY(qreal small READ small CONSTANT)
|
||||
Q_PROPERTY(qreal smaller READ smaller CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensFontSize(QObject* parent = nullptr);
|
||||
|
||||
qreal extraLarge() const { return m_extraLarge; }
|
||||
qreal large() const { return m_large; }
|
||||
qreal larger() const { return m_larger; }
|
||||
qreal medium() const { return m_medium; }
|
||||
qreal normal() const { return m_normal; }
|
||||
qreal scale() const { return m_scale; }
|
||||
qreal small() const { return m_small; }
|
||||
qreal smaller() const { return m_smaller; }
|
||||
|
||||
private:
|
||||
qreal m_extraLarge;
|
||||
qreal m_large;
|
||||
qreal m_larger;
|
||||
qreal m_medium;
|
||||
qreal m_normal;
|
||||
qreal m_scale;
|
||||
qreal m_small;
|
||||
qreal m_smaller;
|
||||
};
|
||||
|
||||
class TokensFont : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(TokensFontSize* size READ size CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensFont(QObject* parent = nullptr);
|
||||
|
||||
TokensFontSize* size() const { return m_size; }
|
||||
|
||||
private:
|
||||
TokensFontSize* m_size = nullptr;
|
||||
};
|
||||
|
||||
class TokensAnimCurves : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(QVariantList emphasized READ emphasized CONSTANT)
|
||||
Q_PROPERTY(QVariantList emphasizedAccel READ emphasizedAccel CONSTANT)
|
||||
Q_PROPERTY(QVariantList emphasizedDecel READ emphasizedDecel CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveDefaultEffects READ expressiveDefaultEffects
|
||||
CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveDefaultSpatial READ expressiveDefaultSpatial
|
||||
CONSTANT)
|
||||
Q_PROPERTY(QVariantList expressiveEffects READ expressiveEffects CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveFastEffects READ expressiveFastEffects CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveFastSpatial READ expressiveFastSpatial CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveSlowEffects READ expressiveSlowEffects CONSTANT)
|
||||
Q_PROPERTY(
|
||||
QVariantList expressiveSlowSpatial READ expressiveSlowSpatial CONSTANT)
|
||||
Q_PROPERTY(QVariantList standard READ standard CONSTANT)
|
||||
Q_PROPERTY(QVariantList standardAccel READ standardAccel CONSTANT)
|
||||
Q_PROPERTY(QVariantList standardDecel READ standardDecel CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensAnimCurves(QObject* parent = nullptr);
|
||||
|
||||
QVariantList emphasized() const { return m_emphasized; }
|
||||
QVariantList emphasizedAccel() const { return m_emphasizedAccel; }
|
||||
QVariantList emphasizedDecel() const { return m_emphasizedDecel; }
|
||||
QVariantList expressiveDefaultEffects() const {
|
||||
return m_expressiveDefaultEffects;
|
||||
}
|
||||
QVariantList expressiveDefaultSpatial() const {
|
||||
return m_expressiveDefaultSpatial;
|
||||
}
|
||||
QVariantList expressiveEffects() const { return m_expressiveEffects; }
|
||||
QVariantList expressiveFastEffects() const {
|
||||
return m_expressiveFastEffects;
|
||||
}
|
||||
QVariantList expressiveFastSpatial() const {
|
||||
return m_expressiveFastSpatial;
|
||||
}
|
||||
QVariantList expressiveSlowEffects() const {
|
||||
return m_expressiveSlowEffects;
|
||||
}
|
||||
QVariantList expressiveSlowSpatial() const {
|
||||
return m_expressiveSlowSpatial;
|
||||
}
|
||||
QVariantList standard() const { return m_standard; }
|
||||
QVariantList standardAccel() const { return m_standardAccel; }
|
||||
QVariantList standardDecel() const { return m_standardDecel; }
|
||||
|
||||
private:
|
||||
QVariantList m_emphasized;
|
||||
QVariantList m_emphasizedAccel;
|
||||
QVariantList m_emphasizedDecel;
|
||||
QVariantList m_expressiveDefaultEffects;
|
||||
QVariantList m_expressiveDefaultSpatial;
|
||||
QVariantList m_expressiveEffects;
|
||||
QVariantList m_expressiveFastEffects;
|
||||
QVariantList m_expressiveFastSpatial;
|
||||
QVariantList m_expressiveSlowEffects;
|
||||
QVariantList m_expressiveSlowSpatial;
|
||||
QVariantList m_standard;
|
||||
QVariantList m_standardAccel;
|
||||
QVariantList m_standardDecel;
|
||||
};
|
||||
|
||||
class TokensAnimDurations : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(
|
||||
int expressiveDefaultSpatial READ expressiveDefaultSpatial CONSTANT)
|
||||
Q_PROPERTY(int expressiveEffects READ expressiveEffects CONSTANT)
|
||||
Q_PROPERTY(int expressiveFastEffects READ expressiveFastEffects CONSTANT)
|
||||
Q_PROPERTY(int expressiveFastSpatial READ expressiveFastSpatial CONSTANT)
|
||||
Q_PROPERTY(int expressiveSlowEffects READ expressiveSlowEffects CONSTANT)
|
||||
Q_PROPERTY(int extraLarge READ extraLarge CONSTANT)
|
||||
Q_PROPERTY(int large READ large CONSTANT)
|
||||
Q_PROPERTY(int normal READ normal CONSTANT)
|
||||
Q_PROPERTY(qreal scale READ scale CONSTANT)
|
||||
Q_PROPERTY(int small READ small CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensAnimDurations(QObject* parent = nullptr);
|
||||
|
||||
int expressiveDefaultSpatial() const { return m_expressiveDefaultSpatial; }
|
||||
int expressiveEffects() const { return m_expressiveEffects; }
|
||||
int expressiveFastEffects() const { return m_expressiveFastEffects; }
|
||||
int expressiveFastSpatial() const { return m_expressiveFastSpatial; }
|
||||
int expressiveSlowEffects() const { return m_expressiveSlowEffects; }
|
||||
int extraLarge() const { return m_extraLarge; }
|
||||
int large() const { return m_large; }
|
||||
int normal() const { return m_normal; }
|
||||
qreal scale() const { return m_scale; }
|
||||
int small() const { return m_small; }
|
||||
|
||||
private:
|
||||
int m_expressiveDefaultSpatial;
|
||||
int m_expressiveEffects;
|
||||
int m_expressiveFastEffects;
|
||||
int m_expressiveFastSpatial;
|
||||
int m_expressiveSlowEffects;
|
||||
int m_extraLarge;
|
||||
int m_large;
|
||||
int m_normal;
|
||||
qreal m_scale;
|
||||
int m_small;
|
||||
};
|
||||
|
||||
class TokensAnim : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
QML_UNCREATABLE("Instantiated internally by Tokens")
|
||||
|
||||
Q_PROPERTY(TokensAnimCurves* curves READ curves CONSTANT)
|
||||
Q_PROPERTY(TokensAnimDurations* durations READ durations CONSTANT)
|
||||
|
||||
public:
|
||||
explicit TokensAnim(QObject* parent = nullptr);
|
||||
|
||||
TokensAnimCurves* curves() const { return m_curves; }
|
||||
TokensAnimDurations* durations() const { return m_durations; }
|
||||
|
||||
private:
|
||||
TokensAnimCurves* m_curves = nullptr;
|
||||
TokensAnimDurations* m_durations = nullptr;
|
||||
};
|
||||
|
||||
class Tokens : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
Q_PROPERTY(TokensRounding* rounding READ rounding CONSTANT)
|
||||
Q_PROPERTY(TokensPadding* padding READ padding CONSTANT)
|
||||
Q_PROPERTY(TokensSpacing* spacing READ spacing CONSTANT)
|
||||
Q_PROPERTY(TokensFont* font READ font CONSTANT)
|
||||
Q_PROPERTY(TokensAnim* anim READ anim CONSTANT)
|
||||
|
||||
public:
|
||||
explicit Tokens(QObject* parent = nullptr);
|
||||
static Tokens* create(QQmlEngine*, QJSEngine*);
|
||||
|
||||
TokensRounding* rounding() const { return m_rounding; }
|
||||
TokensPadding* padding() const { return m_padding; }
|
||||
TokensSpacing* spacing() const { return m_spacing; }
|
||||
TokensFont* font() const { return m_font; }
|
||||
TokensAnim* anim() const { return m_anim; }
|
||||
|
||||
private:
|
||||
TokensRounding* m_rounding = nullptr;
|
||||
TokensPadding* m_padding = nullptr;
|
||||
TokensSpacing* m_spacing = nullptr;
|
||||
TokensFont* m_font = nullptr;
|
||||
TokensAnim* m_anim = nullptr;
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "Utilities.hpp"
|
||||
|
||||
UtilitiesSizes::UtilitiesSizes(QObject *parent) : ConfigSection(parent) {
|
||||
m_toastWidth = 430;
|
||||
m_width = 430;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Toasts::Toasts(QObject *parent) : ConfigSection(parent) {
|
||||
m_audioInputChanged = true;
|
||||
m_audioOutputChanged = true;
|
||||
m_capsLockChanged = true;
|
||||
m_chargingChanged = true;
|
||||
m_configLoaded = true;
|
||||
m_dndChanged = true;
|
||||
m_gameModeChanged = true;
|
||||
m_kbLayoutChanged = true;
|
||||
m_kbLimit = true;
|
||||
m_nowPlaying = false;
|
||||
m_numLockChanged = true;
|
||||
m_vpnChanged = true;
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Vpn::Vpn(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = false;
|
||||
m_provider = { QStringLiteral("netbird") };
|
||||
wireSignals();
|
||||
}
|
||||
|
||||
Utilities::Utilities(QObject *parent) : ConfigSection(parent) {
|
||||
m_enabled = true;
|
||||
m_maxToasts = 4;
|
||||
m_sizes = new UtilitiesSizes(this);
|
||||
m_toasts = new Toasts(this);
|
||||
m_vpn = new Vpn(this);
|
||||
wireSignals();
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#pragma once
|
||||
#include "ConfigSection.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QVariantList>
|
||||
|
||||
class UtilitiesSizes : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(int, toastWidth, ToastWidth)
|
||||
CFG_PROPERTY(int, width, Width)
|
||||
|
||||
public:
|
||||
explicit UtilitiesSizes(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Toasts : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, audioInputChanged, AudioInputChanged)
|
||||
CFG_PROPERTY(bool, audioOutputChanged, AudioOutputChanged)
|
||||
CFG_PROPERTY(bool, capsLockChanged, CapsLockChanged)
|
||||
CFG_PROPERTY(bool, chargingChanged, ChargingChanged)
|
||||
CFG_PROPERTY(bool, configLoaded, ConfigLoaded)
|
||||
CFG_PROPERTY(bool, dndChanged, DndChanged)
|
||||
CFG_PROPERTY(bool, gameModeChanged, GameModeChanged)
|
||||
CFG_PROPERTY(bool, kbLayoutChanged, KbLayoutChanged)
|
||||
CFG_PROPERTY(bool, kbLimit, KbLimit)
|
||||
CFG_PROPERTY(bool, nowPlaying, NowPlaying)
|
||||
CFG_PROPERTY(bool, numLockChanged, NumLockChanged)
|
||||
CFG_PROPERTY(bool, vpnChanged, VpnChanged)
|
||||
|
||||
public:
|
||||
explicit Toasts(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Vpn : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(QVariantList, provider, Provider)
|
||||
|
||||
public:
|
||||
explicit Vpn(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
class Utilities : public ConfigSection {
|
||||
Q_OBJECT
|
||||
QML_UNCREATABLE("Instantiated internally by Config")
|
||||
|
||||
CFG_PROPERTY(bool, enabled, Enabled)
|
||||
CFG_PROPERTY(int, maxToasts, MaxToasts)
|
||||
CFG_SECTION(UtilitiesSizes, sizes, Sizes)
|
||||
CFG_SECTION(Toasts, toasts, Toasts)
|
||||
CFG_SECTION(Vpn, vpn, Vpn)
|
||||
|
||||
public:
|
||||
explicit Utilities(QObject *parent = nullptr);
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Anim : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, mediaGifSpeedAdjustment, 300)
|
||||
CFG_PROPERTY(qreal, sessionGifSpeed, 0.7)
|
||||
|
||||
public:
|
||||
explicit Anim(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Deform : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
|
||||
public:
|
||||
explicit Deform(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontFamily : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, clock, QStringLiteral("Rubik"))
|
||||
CFG_PROPERTY(QString, material, QStringLiteral("Material Symbols Rounded"))
|
||||
CFG_PROPERTY(QString, mono, QStringLiteral("CaskaydiaCove NF"))
|
||||
CFG_PROPERTY(QString, sans, QStringLiteral("Segoe UI Variable Text"))
|
||||
|
||||
public:
|
||||
explicit FontFamily(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Font : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(FontFamily, family)
|
||||
|
||||
public:
|
||||
explicit Font(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_family(new FontFamily(this)) {}
|
||||
};
|
||||
|
||||
class Transparency : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, base, 0.85)
|
||||
CFG_PROPERTY(bool, enabled, false)
|
||||
CFG_PROPERTY(qreal, layers, 0.4)
|
||||
|
||||
public:
|
||||
explicit Transparency(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Appearance : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(Anim, anim)
|
||||
CONFIG_SUBOBJECT(Deform, deform)
|
||||
CONFIG_SUBOBJECT(Font, font)
|
||||
CONFIG_SUBOBJECT(Transparency, transparency)
|
||||
|
||||
public:
|
||||
explicit Appearance(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_anim(new Anim(this))
|
||||
, m_deform(new Deform(this))
|
||||
, m_font(new Font(this))
|
||||
, m_transparency(new Transparency(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Background : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(int, wallFadeDuration, 300)
|
||||
|
||||
public:
|
||||
explicit Background(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include "configlist.hpp"
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class BarEntry : public ListEntry {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
public:
|
||||
explicit BarEntry(QObject* parent = nullptr) : ListEntry(parent) {}
|
||||
};
|
||||
|
||||
class Popouts : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, statusIcons, true)
|
||||
CFG_PROPERTY(bool, tray, true)
|
||||
|
||||
public:
|
||||
explicit Popouts(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Tray : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, recolorIcons, false)
|
||||
CFG_PROPERTY(bool, showOnHover, true)
|
||||
CFG_PROPERTY(int, trayIconSize, 24)
|
||||
CONFIG_LIST(
|
||||
EntryList,
|
||||
statusIcons,
|
||||
{
|
||||
LIST_ENTRY(audio, true),
|
||||
LIST_ENTRY(microphone, true),
|
||||
LIST_ENTRY(bluetooth, false),
|
||||
LIST_ENTRY(network, false),
|
||||
LIST_ENTRY(wifi, false),
|
||||
LIST_ENTRY(power, true),
|
||||
})
|
||||
|
||||
public:
|
||||
explicit Tray(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Bar : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, autoHide, false)
|
||||
CFG_PROPERTY(int, border, 4)
|
||||
CFG_PROPERTY(bool, fullscreenReveal, true)
|
||||
CFG_PROPERTY(int, height, 24)
|
||||
CFG_PROPERTY(bool, hideWhenNotif, true)
|
||||
CONFIG_SUBOBJECT(Popouts, popouts)
|
||||
CFG_PROPERTY(int, revealDelay, 100)
|
||||
CFG_PROPERTY(int, rounding, 14)
|
||||
CFG_PROPERTY(int, smoothing, 32)
|
||||
CONFIG_SUBOBJECT(Tray, tray)
|
||||
CONFIG_LIST(
|
||||
EntryList,
|
||||
entries,
|
||||
{
|
||||
LIST_ENTRY(workspaces, true),
|
||||
LIST_ENTRY(audio, true),
|
||||
LIST_ENTRY(media, true),
|
||||
LIST_ENTRY(resources, true),
|
||||
LIST_ENTRY(updates, true),
|
||||
LIST_ENTRY(dash, false),
|
||||
LIST_ENTRY(spacer, true),
|
||||
LIST_ENTRY(activeWindow, true),
|
||||
LIST_ENTRY(spacer, true),
|
||||
LIST_ENTRY(hyprsunset, true),
|
||||
LIST_ENTRY(tray, true),
|
||||
LIST_ENTRY(statusIcons, true),
|
||||
LIST_ENTRY(network, false),
|
||||
LIST_ENTRY(upower, true),
|
||||
LIST_ENTRY(clock, true),
|
||||
LIST_ENTRY(notifBell, true),
|
||||
})
|
||||
|
||||
public:
|
||||
explicit Bar(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_popouts(new Popouts(this))
|
||||
, m_tray(new Tray(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class ClipboardSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, itemHeight, 60)
|
||||
CFG_PROPERTY(int, minPreviewWidth, 200)
|
||||
CFG_PROPERTY(int, previewWidth, 800)
|
||||
CFG_PROPERTY(int, width, 500)
|
||||
|
||||
public:
|
||||
explicit ClipboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Clipboard : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(int, maxEntriesShown, 10)
|
||||
CONFIG_SUBOBJECT(ClipboardSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Clipboard(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_sizes(new ClipboardSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Presets : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, accent, QString())
|
||||
CFG_PROPERTY(QString, name, QStringLiteral("Catppuccin"))
|
||||
CFG_PROPERTY(QString, variant, QStringLiteral("latte"))
|
||||
|
||||
public:
|
||||
explicit Presets(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Colors : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(Presets, presets)
|
||||
CFG_PROPERTY(QString, schemeType, QStringLiteral("fidelity"))
|
||||
|
||||
public:
|
||||
explicit Colors(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_presets(new Presets(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -1,4 +1,21 @@
|
||||
#include "Config.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
#include "appearance.hpp"
|
||||
#include "background.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "clipboard.hpp"
|
||||
#include "colors.hpp"
|
||||
#include "dashboard.hpp"
|
||||
#include "dock.hpp"
|
||||
#include "general.hpp"
|
||||
#include "launcher.hpp"
|
||||
#include "lock.hpp"
|
||||
#include "notifs.hpp"
|
||||
#include "osd.hpp"
|
||||
#include "screenshot.hpp"
|
||||
#include "services.hpp"
|
||||
#include "sidebar.hpp"
|
||||
#include "utilities.hpp"
|
||||
|
||||
#include <QFile>
|
||||
#include <QSaveFile>
|
||||
@@ -8,31 +25,30 @@
|
||||
#include <QDebug>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
Config::Config(QObject* parent) : ConfigSection(parent) {
|
||||
m_appearance = new Appearance(this);
|
||||
m_background = new Background(this);
|
||||
m_bar = new Bar(this);
|
||||
m_clipboard = new Clipboard(this);
|
||||
m_colors = new Colors(this);
|
||||
m_dashboard = new Dashboard(this);
|
||||
m_dock = new Dock(this);
|
||||
m_general = new General(this);
|
||||
m_launcher = new Launcher(this);
|
||||
m_lock = new Lock(this);
|
||||
m_notifs = new Notifs(this);
|
||||
m_osd = new Osd(this);
|
||||
m_overview = new Overview(this);
|
||||
m_screenshot = new Screenshot(this);
|
||||
m_services = new Services(this);
|
||||
m_sidebar = new Sidebar(this);
|
||||
m_utilities = new Utilities(this);
|
||||
wireSignals(); // forwards every child's changed() up to our own changed()
|
||||
namespace ZShell::config {
|
||||
|
||||
connect(this, &ConfigSection::changed, this, &Config::scheduleSave);
|
||||
Config::Config(QObject* parent)
|
||||
: ConfigObject(parent)
|
||||
, m_appearance(new Appearance(this))
|
||||
, m_background(new Background(this))
|
||||
, m_bar(new Bar(this))
|
||||
, m_clipboard(new Clipboard(this))
|
||||
, m_colors(new Colors(this))
|
||||
, m_dashboard(new Dashboard(this))
|
||||
, m_dock(new Dock(this))
|
||||
, m_general(new General(this))
|
||||
, m_launcher(new Launcher(this))
|
||||
, m_lock(new Lock(this))
|
||||
, m_notifs(new Notifs(this))
|
||||
, m_osd(new Osd(this))
|
||||
, m_screenshot(new Screenshot(this))
|
||||
, m_services(new Services(this))
|
||||
, m_sidebar(new Sidebar(this))
|
||||
, m_utilities(new Utilities(this)) {
|
||||
connect(this, &ConfigObject::propertiesChanged, this, &Config::scheduleSave);
|
||||
|
||||
m_saveTimer.setSingleShot(true);
|
||||
m_saveTimer.setInterval(
|
||||
300); // debounce: coalesce rapid-fire edits (e.g. dragging a slider)
|
||||
m_saveTimer.setInterval(300);
|
||||
connect(&m_saveTimer, &QTimer::timeout, this, &Config::flushAsync);
|
||||
|
||||
loadSync();
|
||||
@@ -40,7 +56,6 @@ Config::Config(QObject* parent) : ConfigSection(parent) {
|
||||
}
|
||||
|
||||
Config* Config::create(QQmlEngine*, QJSEngine*) {
|
||||
// The QML engine takes ownership of singletons created this way.
|
||||
return new Config();
|
||||
}
|
||||
|
||||
@@ -53,12 +68,11 @@ QString Config::filePath() const {
|
||||
}
|
||||
|
||||
void Config::loadSync() {
|
||||
m_loading =
|
||||
true; // suppress scheduleSave() while properties are set from disk
|
||||
m_loading = true;
|
||||
QFile f(filePath());
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
const auto doc = QJsonDocument::fromJson(f.readAll());
|
||||
if (doc.isObject()) fromJson(doc.object());
|
||||
if (doc.isObject()) loadFromJson(QJsonValue(doc.object()));
|
||||
} else {
|
||||
qInfo() << "Config: no existing config at" << filePath()
|
||||
<< "- using defaults";
|
||||
@@ -73,21 +87,24 @@ void Config::loadAsync() {
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
const auto doc = QJsonDocument::fromJson(f.readAll());
|
||||
if (doc.isObject()) {
|
||||
QMetaObject::invokeMethod(this, [this, doc]() {
|
||||
fromJson(doc.object());
|
||||
m_loading = false;
|
||||
}, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, doc]() {
|
||||
loadFromJson(QJsonValue(doc.object()));
|
||||
m_loading = false;
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
m_loading = false;
|
||||
}, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this]() { m_loading = false; },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
} else {
|
||||
qInfo() << "Config: failed to reload from" << filePath()
|
||||
<< "- using in-memory values";
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
m_loading = false;
|
||||
}, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(
|
||||
this, [this]() { m_loading = false; }, Qt::QueuedConnection);
|
||||
}
|
||||
});
|
||||
m_loadFuture = future;
|
||||
@@ -107,12 +124,13 @@ void Config::reloadAsync() {
|
||||
|
||||
void Config::scheduleSave() {
|
||||
if (m_loading) return;
|
||||
m_saveTimer.start(); // restarts the window if it's already running
|
||||
m_saveTimer.start();
|
||||
}
|
||||
|
||||
void Config::flushAsync() {
|
||||
auto future = QtConcurrent::run([this]() {
|
||||
const QByteArray data = QJsonDocument(toJson()).toJson(QJsonDocument::Indented);
|
||||
const QByteArray data =
|
||||
QJsonDocument(toJson().toObject()).toJson(QJsonDocument::Indented);
|
||||
writeAtomically(data);
|
||||
});
|
||||
}
|
||||
@@ -123,9 +141,6 @@ void Config::saveNow() {
|
||||
}
|
||||
|
||||
void Config::writeAtomically(const QByteArray& data) {
|
||||
// QSaveFile writes to a temp file next to the target and atomically
|
||||
// renames it into place on commit() - a crash or power loss mid-write
|
||||
// can never leave config.json half-written.
|
||||
QSaveFile f(filePath());
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "Config: failed to open for atomic write:"
|
||||
@@ -135,3 +150,5 @@ void Config::writeAtomically(const QByteArray& data) {
|
||||
f.write(data);
|
||||
if (!f.commit()) qWarning() << "Config: commit failed:" << f.errorString();
|
||||
}
|
||||
|
||||
}; // namespace ZShell::config
|
||||
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlregistration.h>
|
||||
#include <QTimer>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QFuture>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
class QQmlEngine;
|
||||
class QJSEngine;
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Appearance;
|
||||
class Background;
|
||||
class Bar;
|
||||
class Clipboard;
|
||||
class Colors;
|
||||
class Dashboard;
|
||||
class Dock;
|
||||
class General;
|
||||
class Launcher;
|
||||
class Lock;
|
||||
class Notifs;
|
||||
class Osd;
|
||||
class Screenshot;
|
||||
class Services;
|
||||
class Sidebar;
|
||||
class Utilities;
|
||||
|
||||
class Config : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
Q_MOC_INCLUDE("appearance.hpp")
|
||||
Q_MOC_INCLUDE("background.hpp")
|
||||
Q_MOC_INCLUDE("bar.hpp")
|
||||
Q_MOC_INCLUDE("clipboard.hpp")
|
||||
Q_MOC_INCLUDE("colors.hpp")
|
||||
Q_MOC_INCLUDE("dashboard.hpp")
|
||||
Q_MOC_INCLUDE("dock.hpp")
|
||||
Q_MOC_INCLUDE("general.hpp")
|
||||
Q_MOC_INCLUDE("launcher.hpp")
|
||||
Q_MOC_INCLUDE("lock.hpp")
|
||||
Q_MOC_INCLUDE("notifs.hpp")
|
||||
Q_MOC_INCLUDE("osd.hpp")
|
||||
Q_MOC_INCLUDE("screenshot.hpp")
|
||||
Q_MOC_INCLUDE("services.hpp")
|
||||
Q_MOC_INCLUDE("sidebar.hpp")
|
||||
Q_MOC_INCLUDE("utilities.hpp")
|
||||
|
||||
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(Dock, dock)
|
||||
CONFIG_SUBOBJECT(General, general)
|
||||
CONFIG_SUBOBJECT(Launcher, launcher)
|
||||
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 Config(QObject* parent = nullptr);
|
||||
static Config* create(QQmlEngine*, QJSEngine*);
|
||||
|
||||
Q_INVOKABLE void load();
|
||||
Q_INVOKABLE void saveNow();
|
||||
Q_INVOKABLE void reloadAsync();
|
||||
|
||||
private Q_SLOTS:
|
||||
void scheduleSave();
|
||||
void flushAsync();
|
||||
|
||||
private:
|
||||
QString filePath() const;
|
||||
void writeAtomically(const QByteArray& data);
|
||||
void loadSync();
|
||||
void loadAsync();
|
||||
|
||||
QTimer m_saveTimer;
|
||||
bool m_loading = false;
|
||||
bool m_firstLoadDone = false;
|
||||
QFuture<void> m_loadFuture;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,305 @@
|
||||
#include "configlist.hpp"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMetaObject>
|
||||
#include <QQmlEngine>
|
||||
#include <QString>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
ConfigList::ConfigList(QObject* parent, const QVariantList& defaults)
|
||||
: ConfigNode(parent), m_defaults(QJsonArray::fromVariantList(defaults)) {}
|
||||
|
||||
int ConfigList::count() const {
|
||||
return static_cast<int>(m_items.size());
|
||||
}
|
||||
|
||||
QVariantList ConfigList::values() const {
|
||||
QVariantList vals;
|
||||
vals.reserve(m_items.size());
|
||||
for (auto* const item : m_items)
|
||||
vals.append(QVariant::fromValue(item));
|
||||
return vals;
|
||||
}
|
||||
|
||||
ConfigObject* ConfigList::itemAt(int index) const {
|
||||
if (index < 0 || index >= m_items.size()) return nullptr;
|
||||
|
||||
return m_items.at(index);
|
||||
}
|
||||
|
||||
const QList<ConfigObject*>& ConfigList::items() const {
|
||||
return m_items;
|
||||
}
|
||||
|
||||
void ConfigList::remove(int index) {
|
||||
if (index < 0 || index >= m_items.size()) {
|
||||
qCWarning(lcConfig)
|
||||
<< metaObject()->className() << "cannot remove index" << index
|
||||
<< "of" << count();
|
||||
return;
|
||||
}
|
||||
|
||||
destroyItem(m_items.takeAt(index));
|
||||
|
||||
m_loaded = true;
|
||||
emit countChanged();
|
||||
emit valuesChanged();
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
void ConfigList::move(int from, int to) {
|
||||
if (from < 0 || from >= m_items.size() || to < 0 || to >= m_items.size()) {
|
||||
qCWarning(lcConfig) << metaObject()->className() << "cannot move"
|
||||
<< from << "to" << to << "of" << count();
|
||||
return;
|
||||
}
|
||||
|
||||
if (from == to) return;
|
||||
|
||||
m_items.move(from, to);
|
||||
|
||||
m_loaded = true;
|
||||
emit valuesChanged();
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
void ConfigList::clear() {
|
||||
if (m_items.isEmpty()) return;
|
||||
|
||||
destroyItems();
|
||||
|
||||
m_loaded = true;
|
||||
emit countChanged();
|
||||
emit valuesChanged();
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
void ConfigList::loadFromJson(const QJsonValue& json) {
|
||||
if (!json.isArray()) {
|
||||
qCWarning(
|
||||
lcConfig,
|
||||
"Option '%s' must be a list, ignoring",
|
||||
qUtf8Printable(propertyPath()));
|
||||
m_rejectedJson = json;
|
||||
return;
|
||||
}
|
||||
|
||||
m_rejectedJson = QJsonValue::Undefined;
|
||||
populate(json.toArray());
|
||||
m_loaded = true;
|
||||
}
|
||||
|
||||
QJsonValue ConfigList::toJson() const {
|
||||
if (m_loaded) return elementsToJson();
|
||||
|
||||
return m_rejectedJson;
|
||||
}
|
||||
|
||||
void ConfigList::clearLoadedKeys() {
|
||||
m_loaded = false;
|
||||
m_rejectedJson = QJsonValue::Undefined;
|
||||
}
|
||||
|
||||
QStringList ConfigList::unknownKeys() const {
|
||||
QStringList keys;
|
||||
|
||||
for (int i = 0; i < m_items.size(); ++i) {
|
||||
const auto childKeys = m_items.at(i)->unknownKeys();
|
||||
for (const auto& childKey : childKeys)
|
||||
keys.append(joinPath(QString("[%1]").arg(i), childKey));
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
void ConfigList::resyncFromGlobal() {
|
||||
syncValuesFromGlobal();
|
||||
}
|
||||
|
||||
ConfigObject* ConfigList::insertItem(const QVariantMap& props, int index) {
|
||||
const auto pos = index < 0 || index > m_items.size() ? m_items.size()
|
||||
: index;
|
||||
|
||||
appendItem(QJsonObject::fromVariantMap(props));
|
||||
m_items.move(m_items.size() - 1, pos);
|
||||
|
||||
auto* const item = m_items.at(pos);
|
||||
const auto unknown = item->unknownKeys();
|
||||
for (const auto& key : unknown)
|
||||
qCWarning(lcConfig) << "Unknown option" << key << "for"
|
||||
<< item->metaObject()->className();
|
||||
|
||||
m_loaded = true;
|
||||
emit countChanged();
|
||||
emit valuesChanged();
|
||||
notifyChanged();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QJsonArray ConfigList::elementsToJson() const {
|
||||
QJsonArray arr;
|
||||
|
||||
for (auto* const item : m_items)
|
||||
arr.append(item->toJson().toObject());
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void ConfigList::resetToDefaults() {
|
||||
loadFromJsonQuietly(m_defaults);
|
||||
m_loaded = false;
|
||||
}
|
||||
|
||||
void ConfigList::syncValuesFromGlobal() {
|
||||
if (m_loaded) return;
|
||||
|
||||
if (auto* const global = qobject_cast<ConfigList*>(m_global))
|
||||
populate(global->elementsToJson());
|
||||
}
|
||||
|
||||
void ConfigList::onGlobalPropertiesChanged(const QMap<QString, QVariant>&) {
|
||||
syncValuesFromGlobal();
|
||||
}
|
||||
|
||||
QString ConfigList::childPath(const ConfigNode* child) const {
|
||||
for (int i = 0; i < m_items.size(); ++i)
|
||||
if (m_items.at(i) == child) return QString("[%1]").arg(i);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ConfigList::populate(const QJsonArray& arr) {
|
||||
const auto current = elementsToJson();
|
||||
if (current == arr) return;
|
||||
|
||||
const auto old = m_items;
|
||||
QList<bool> reused(old.size(), false);
|
||||
|
||||
m_items.clear();
|
||||
m_items.reserve(arr.size());
|
||||
|
||||
for (int i = 0; i < arr.size(); ++i) {
|
||||
auto match =
|
||||
i < old.size() && !reused.at(i) && current.at(i) == arr.at(i) ? i
|
||||
: -1;
|
||||
|
||||
for (int j = 0; match < 0 && j < old.size(); ++j)
|
||||
if (!reused.at(j) && current.at(j) == arr.at(i)) match = j;
|
||||
|
||||
auto update = false;
|
||||
for (int j = 0; match < 0 && j < old.size(); ++j) {
|
||||
if (!reused.at(j) &&
|
||||
sameElement(old.at(j), current.at(j), arr.at(i))) {
|
||||
match = j;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (match < 0) {
|
||||
appendItem(arr.at(i));
|
||||
continue;
|
||||
}
|
||||
|
||||
reused[match] = true;
|
||||
|
||||
if (update) old.at(match)->loadFromJsonQuietly(arr.at(i));
|
||||
|
||||
m_items.append(old.at(match));
|
||||
}
|
||||
|
||||
for (int i = 0; i < old.size(); ++i)
|
||||
if (!reused.at(i)) destroyItem(old.at(i));
|
||||
|
||||
if (m_items.size() != old.size()) emit countChanged();
|
||||
|
||||
emit valuesChanged();
|
||||
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
bool ConfigList::sameElement(
|
||||
const ConfigObject* item,
|
||||
const QJsonValue& current,
|
||||
const QJsonValue& json) {
|
||||
const auto keys = item->identityKeys();
|
||||
if (keys.isEmpty()) return false;
|
||||
|
||||
const auto currentObj = current.toObject();
|
||||
const auto newObj = json.toObject();
|
||||
|
||||
if (currentObj.keys() != newObj.keys()) return false;
|
||||
|
||||
for (const auto& key : keys)
|
||||
if (!newObj.contains(key) || currentObj.value(key) != newObj.value(key))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigList::appendItem(const QJsonValue& json) {
|
||||
auto* const item = createItem();
|
||||
QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
|
||||
|
||||
if (m_items.isEmpty()) rejectGlobalOnlyElement(item);
|
||||
|
||||
item->loadFromJsonQuietly(json);
|
||||
|
||||
connectItem(item);
|
||||
|
||||
m_items.append(item);
|
||||
}
|
||||
|
||||
void ConfigList::rejectGlobalOnlyElement(const ConfigObject* item) const {
|
||||
const auto keys = item->globalOnlyKeys();
|
||||
if (keys.isEmpty()) return;
|
||||
|
||||
qCCritical(
|
||||
lcConfig,
|
||||
"%s declares global-only options (%s) which do not work inside a list, "
|
||||
"use CONFIG_GLOBAL_LIST on %s instead",
|
||||
item->metaObject()->className(),
|
||||
qUtf8Printable(keys.join(", ")),
|
||||
metaObject()->className());
|
||||
}
|
||||
|
||||
void ConfigList::connectItem(ConfigNode* node) {
|
||||
connect(
|
||||
node, &ConfigNode::propertiesChanged, this, &ConfigList::onItemChanged);
|
||||
|
||||
const auto children = node->childNodes();
|
||||
for (auto* const child : children)
|
||||
connectItem(child);
|
||||
}
|
||||
|
||||
void ConfigList::disconnectItem(ConfigNode* node) {
|
||||
node->disconnect(this);
|
||||
|
||||
const auto children = node->childNodes();
|
||||
for (auto* const child : children)
|
||||
disconnectItem(child);
|
||||
}
|
||||
|
||||
void ConfigList::destroyItems() {
|
||||
for (auto* const item : std::as_const(m_items))
|
||||
destroyItem(item);
|
||||
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
void ConfigList::destroyItem(ConfigObject* item) {
|
||||
disconnectItem(item);
|
||||
item->deleteLater();
|
||||
}
|
||||
|
||||
void ConfigList::onItemChanged() {
|
||||
m_loaded = true;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
void ConfigList::notifyChanged() {
|
||||
notifyPropertyChanged("values", count());
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QQmlEngine>
|
||||
#include <QVariantList>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class ConfigList : public ConfigNode {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
Q_PROPERTY(QVariantList values READ values NOTIFY valuesChanged)
|
||||
|
||||
public:
|
||||
explicit ConfigList(
|
||||
QObject* parent = nullptr, const QVariantList& defaults = {});
|
||||
|
||||
[[nodiscard]] int count() const;
|
||||
[[nodiscard]] QVariantList values() const;
|
||||
[[nodiscard]] ConfigObject* itemAt(int index) const;
|
||||
[[nodiscard]] const QList<ConfigObject*>& items() const;
|
||||
|
||||
Q_INVOKABLE void remove(int index);
|
||||
Q_INVOKABLE void move(int from, int to);
|
||||
Q_INVOKABLE void clear();
|
||||
|
||||
void loadFromJson(const QJsonValue& json) override;
|
||||
[[nodiscard]] QJsonValue toJson() const override;
|
||||
void clearLoadedKeys() override;
|
||||
[[nodiscard]] QStringList unknownKeys() const override;
|
||||
void resyncFromGlobal() override;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void valuesChanged();
|
||||
|
||||
protected:
|
||||
virtual ConfigObject* createItem() = 0;
|
||||
|
||||
void resetToDefaults();
|
||||
|
||||
ConfigObject* insertItem(const QVariantMap& props, int index = -1);
|
||||
|
||||
[[nodiscard]] QJsonArray elementsToJson() const;
|
||||
|
||||
void syncValuesFromGlobal() override;
|
||||
void onGlobalPropertiesChanged(
|
||||
const QMap<QString, QVariant>& changed) override;
|
||||
[[nodiscard]] QString childPath(const ConfigNode* child) const override;
|
||||
|
||||
private:
|
||||
void populate(const QJsonArray& arr);
|
||||
static bool sameElement(
|
||||
const ConfigObject* item,
|
||||
const QJsonValue& current,
|
||||
const QJsonValue& json);
|
||||
void appendItem(const QJsonValue& json);
|
||||
void destroyItems();
|
||||
void destroyItem(ConfigObject* item);
|
||||
void rejectGlobalOnlyElement(const ConfigObject* item) const;
|
||||
void connectItem(ConfigNode* node);
|
||||
void disconnectItem(ConfigNode* node);
|
||||
void onItemChanged();
|
||||
void notifyChanged();
|
||||
|
||||
QJsonArray m_defaults;
|
||||
QList<ConfigObject*> m_items;
|
||||
bool m_loaded = false;
|
||||
QJsonValue m_rejectedJson = QJsonValue::Undefined;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
|
||||
#define CONFIG_LIST_TYPE(Element, Name) \
|
||||
class Name : public ZShell::config::ConfigList { \
|
||||
Q_OBJECT \
|
||||
QML_ANONYMOUS \
|
||||
\
|
||||
public: \
|
||||
explicit Name( \
|
||||
QObject* parent = nullptr, const QVariantList& defaults = {}) \
|
||||
: ZShell::config::ConfigList(parent, defaults) { \
|
||||
resetToDefaults(); \
|
||||
} \
|
||||
\
|
||||
Q_INVOKABLE ZShell::config::Element* at(int index) const { \
|
||||
return static_cast<ZShell::config::Element*>(itemAt(index)); \
|
||||
} \
|
||||
Q_INVOKABLE ZShell::config::Element* insert( \
|
||||
const QVariantMap& props, int index = -1) { \
|
||||
return static_cast<ZShell::config::Element*>( \
|
||||
insertItem(props, index)); \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
[[nodiscard]] ZShell::config::ConfigObject* createItem() override { \
|
||||
return new ZShell::config::Element(this); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
#define CONFIG_LIST(Type, name, ...) \
|
||||
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
|
||||
\
|
||||
public: \
|
||||
[[nodiscard]] Type* name() const { \
|
||||
return m_##name; \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
Type* m_##name = new Type(this __VA_OPT__(, __VA_ARGS__));
|
||||
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class ListEntry : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, id)
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
|
||||
public:
|
||||
explicit ListEntry(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] QStringList identityKeys() const override {
|
||||
return {QStringLiteral("id")};
|
||||
}
|
||||
};
|
||||
|
||||
CONFIG_LIST_TYPE(ListEntry, EntryList)
|
||||
|
||||
} // namespace ZShell::config
|
||||
|
||||
#define LIST_ENTRY(id, enabled) \
|
||||
vmap({{"id", QString::fromUtf8(#id)}, {"enabled", enabled}})
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "confignode.hpp"
|
||||
|
||||
#include <qjsonvalue.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qmetaobject.h>
|
||||
#include <qstring.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
Q_LOGGING_CATEGORY(lcConfig, "zshell.config")
|
||||
|
||||
ConfigNode::ConfigNode(QObject* parent) : QObject(parent) {
|
||||
m_batchTimer = new QTimer(this);
|
||||
m_batchTimer->setSingleShot(true);
|
||||
m_batchTimer->setInterval(0);
|
||||
connect(
|
||||
m_batchTimer, &QTimer::timeout, this, &ConfigNode::emitBatchedChanges);
|
||||
}
|
||||
|
||||
void ConfigNode::loadFromJsonQuietly(const QJsonValue& json) {
|
||||
setNotifySuppressed(true);
|
||||
loadFromJson(json);
|
||||
setNotifySuppressed(false);
|
||||
}
|
||||
|
||||
void ConfigNode::setNotifySuppressed(bool suppressed) {
|
||||
m_suppressNotify = suppressed;
|
||||
|
||||
const auto children = childNodes();
|
||||
for (auto* const child : children)
|
||||
child->setNotifySuppressed(suppressed);
|
||||
}
|
||||
|
||||
QList<ConfigNode*> ConfigNode::childNodes() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
void ConfigNode::syncFromGlobal(ConfigNode* global) {
|
||||
m_global = global;
|
||||
resyncFromGlobal();
|
||||
}
|
||||
|
||||
bool ConfigNode::isOverlay() const {
|
||||
return m_global != nullptr && this != m_global;
|
||||
}
|
||||
|
||||
QString ConfigNode::propertyPath(const QString& name) const {
|
||||
if (name.isEmpty()) return objectName();
|
||||
|
||||
QObject* const parentObj = parent();
|
||||
if (parentObj) {
|
||||
if (auto* parentNode = qobject_cast<ConfigNode*>(parentObj)) {
|
||||
const auto childName = parentNode->childPath(this);
|
||||
if (!childName.isEmpty()) {
|
||||
return joinPath(parentNode->propertyPath(childName), name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
int ConfigNode::basePropertyOffset() {
|
||||
return QObject::staticMetaObject.propertyCount();
|
||||
}
|
||||
|
||||
void ConfigNode::notifyPropertyChanged(
|
||||
const QString& name, const QVariant& value) {
|
||||
if (m_suppressNotify) return;
|
||||
|
||||
m_pendingChanges[name] = value;
|
||||
if (m_batchTimer && !m_batchTimer->isActive()) m_batchTimer->start();
|
||||
}
|
||||
|
||||
QString ConfigNode::joinPath(const QString& parent, const QString& child) {
|
||||
// List elements are addressed as parent[i], everything else as parent.child
|
||||
if (child.startsWith(QLatin1Char('['))) return parent + child;
|
||||
|
||||
return parent + QLatin1Char('.') + child;
|
||||
}
|
||||
|
||||
void ConfigNode::emitBatchedChanges() {
|
||||
if (m_pendingChanges.isEmpty()) return;
|
||||
|
||||
QMap<QString, QVariant> changes = m_pendingChanges;
|
||||
m_pendingChanges.clear();
|
||||
emit propertiesChanged(changes);
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <QJsonValue>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QVariant>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcConfig)
|
||||
|
||||
class ConfigNode : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigNode(QObject* parent = nullptr);
|
||||
|
||||
virtual void loadFromJson(const QJsonValue& json) = 0;
|
||||
void loadFromJsonQuietly(const QJsonValue& json);
|
||||
[[nodiscard]] virtual QJsonValue toJson() const = 0;
|
||||
|
||||
virtual void clearLoadedKeys() = 0;
|
||||
[[nodiscard]] virtual QStringList unknownKeys() const = 0;
|
||||
[[nodiscard]] virtual QList<ConfigNode*> childNodes() const;
|
||||
|
||||
void syncFromGlobal(ConfigNode* global);
|
||||
virtual void resyncFromGlobal() = 0;
|
||||
|
||||
[[nodiscard]] bool isOverlay() const;
|
||||
[[nodiscard]] QString propertyPath(const QString& name = {}) const;
|
||||
|
||||
[[nodiscard]] static int basePropertyOffset();
|
||||
|
||||
signals:
|
||||
void propertiesChanged(const QMap<QString, QVariant>& changed);
|
||||
|
||||
protected:
|
||||
virtual void syncValuesFromGlobal() = 0;
|
||||
virtual void onGlobalPropertiesChanged(
|
||||
const QMap<QString, QVariant>& changed) = 0;
|
||||
|
||||
[[nodiscard]] virtual QString childPath(const ConfigNode* child) const = 0;
|
||||
|
||||
void notifyPropertyChanged(const QString& name, const QVariant& value);
|
||||
|
||||
[[nodiscard]] static QString joinPath(
|
||||
const QString& parent, const QString& child);
|
||||
|
||||
ConfigNode* m_global = nullptr;
|
||||
|
||||
private:
|
||||
void setNotifySuppressed(bool suppressed);
|
||||
void emitBatchedChanges();
|
||||
|
||||
QMap<QString, QVariant> m_pendingChanges;
|
||||
QTimer* m_batchTimer = nullptr;
|
||||
bool m_suppressNotify = false;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,270 @@
|
||||
#include "configobject.hpp"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QMetaObject>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
ConfigObject::ConfigObject(QObject* parent) : ConfigNode(parent) {}
|
||||
|
||||
void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
const auto obj = json.toObject();
|
||||
const auto* meta = metaObject();
|
||||
|
||||
QSet<QString> known;
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
auto prop = meta->property(i);
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
known.insert(key);
|
||||
|
||||
if (!obj.contains(key)) continue;
|
||||
|
||||
const auto jsonVal = obj.value(key);
|
||||
|
||||
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
node->loadFromJson(jsonVal);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (prop.metaType().id() == QMetaType::QStringList) {
|
||||
QStringList list;
|
||||
const auto jsonArr = jsonVal.toArray();
|
||||
for (const auto& v : jsonArr)
|
||||
list.append(v.toString());
|
||||
prop.write(this, QVariant::fromValue(list));
|
||||
m_loadedKeys.insert(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop.metaType().id() == QMetaType::QVariantList) {
|
||||
prop.write(this, jsonVal.toVariant());
|
||||
m_loadedKeys.insert(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
prop.write(this, jsonVal.toVariant());
|
||||
m_loadedKeys.insert(key);
|
||||
}
|
||||
|
||||
m_extras = {};
|
||||
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||
if (!known.contains(it.key())) {
|
||||
m_extras.insert(it.key(), it.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonValue ConfigObject::toJson() const {
|
||||
QJsonObject obj;
|
||||
const auto* meta = metaObject();
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
|
||||
if (!prop.isReadable()) continue;
|
||||
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
const auto value = prop.read(this);
|
||||
|
||||
if (prop.metaType().flags().testFlag(QMetaType::PointerToQObject)) {
|
||||
if (auto* const node = value.value<ConfigNode*>()) {
|
||||
const auto childJson = node->toJson();
|
||||
if (!childJson.isUndefined()) obj.insert(key, childJson);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_loadedKeys.contains(key)) continue;
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (prop.metaType().id() == QMetaType::QStringList) {
|
||||
QJsonArray arr;
|
||||
const auto strList = value.toStringList();
|
||||
for (const auto& s : strList)
|
||||
arr.append(s);
|
||||
obj.insert(key, arr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop.metaType().id() == QMetaType::QVariantList) {
|
||||
obj.insert(key, QJsonArray::fromVariantList(value.toList()));
|
||||
continue;
|
||||
}
|
||||
|
||||
obj.insert(key, QJsonValue::fromVariant(value));
|
||||
}
|
||||
|
||||
for (auto it = m_extras.begin(); it != m_extras.end(); ++it)
|
||||
obj.insert(it.key(), it.value());
|
||||
|
||||
if (obj.isEmpty()) return QJsonValue::Undefined;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void ConfigObject::clearLoadedKeys() {
|
||||
m_loadedKeys.clear();
|
||||
m_extras = {};
|
||||
|
||||
const auto* meta = metaObject();
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
auto prop = meta->property(i);
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>())
|
||||
node->clearLoadedKeys();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ConfigObject::identityKeys() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList ConfigObject::unknownKeys() const {
|
||||
auto keys = m_extras.keys();
|
||||
|
||||
const auto* meta = metaObject();
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
auto* const node = prop.read(this).value<ConfigNode*>();
|
||||
if (!node) continue;
|
||||
|
||||
const auto childKeys = node->unknownKeys();
|
||||
for (const auto& childKey : childKeys)
|
||||
keys.append(joinPath(QString::fromUtf8(prop.name()), childKey));
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
QList<ConfigNode*> ConfigObject::childNodes() const {
|
||||
QList<ConfigNode*> nodes;
|
||||
|
||||
const auto* meta = metaObject();
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>())
|
||||
nodes.append(node);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void ConfigObject::syncValuesFromGlobal() {
|
||||
const auto* meta = metaObject();
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
auto prop = meta->property(i);
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
if (auto* const globalNode =
|
||||
prop.read(m_global).value<ConfigNode*>())
|
||||
node->syncFromGlobal(globalNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (!m_loadedKeys.contains(key)) {
|
||||
auto val = prop.read(m_global);
|
||||
prop.write(this, val);
|
||||
m_loadedKeys.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigObject::resyncFromGlobal() {
|
||||
if (!m_global) return;
|
||||
|
||||
const auto* meta = metaObject();
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
auto prop = meta->property(i);
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
node->resyncFromGlobal();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (!m_loadedKeys.contains(key)) {
|
||||
prop.write(this, prop.read(m_global));
|
||||
m_loadedKeys.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigObject::isPropertyLoaded(const QString& name) const {
|
||||
return m_loadedKeys.contains(name);
|
||||
}
|
||||
|
||||
bool ConfigObject::isGlobalOnly(const QString& name) const {
|
||||
return m_globalOnlyKeys.contains(name);
|
||||
}
|
||||
|
||||
QStringList ConfigObject::globalOnlyKeys() const {
|
||||
return {m_globalOnlyKeys.begin(), m_globalOnlyKeys.end()};
|
||||
}
|
||||
|
||||
void ConfigObject::resetOption(const QString& name) {
|
||||
m_loadedKeys.remove(name);
|
||||
|
||||
const int idx = metaObject()->indexOfProperty(name.toUtf8().constData());
|
||||
if (idx < 0) return;
|
||||
|
||||
const auto prop = metaObject()->property(idx);
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
node->clearLoadedKeys();
|
||||
node->resyncFromGlobal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_global && prop.isWritable()) prop.write(this, prop.read(m_global));
|
||||
}
|
||||
|
||||
void ConfigObject::onGlobalPropertiesChanged(
|
||||
const QMap<QString, QVariant>& changed) {
|
||||
for (auto it = changed.begin(); it != changed.end(); ++it) {
|
||||
if (m_loadedKeys.contains(it.key()) || isGlobalOnly(it.key())) continue;
|
||||
|
||||
int idx = metaObject()->indexOfProperty(it.key().toUtf8().constData());
|
||||
if (idx >= 0) {
|
||||
metaObject()->property(idx).write(this, it.value());
|
||||
m_loadedKeys.remove(it.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString ConfigObject::childPath(const ConfigNode* child) const {
|
||||
const auto* meta = metaObject();
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
|
||||
if (prop.read(this).value<ConfigNode*>() == child)
|
||||
return QString::fromUtf8(prop.name());
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ConfigObject::markPropertyLoaded(const QString& name) {
|
||||
m_loadedKeys.insert(name);
|
||||
}
|
||||
|
||||
void ConfigObject::markGlobalOnly(const QString& name) {
|
||||
m_globalOnlyKeys.insert(name);
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
|
||||
#include "confignode.hpp"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMetaProperty>
|
||||
#include <QMetaType>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QVariantList>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
inline QVariantMap vmap(
|
||||
std::initializer_list<std::pair<QString, QVariant>> entries) {
|
||||
QVariantMap map;
|
||||
for (const auto& [key, value] : entries)
|
||||
map.insert(key, value);
|
||||
return map;
|
||||
}
|
||||
|
||||
#define CFG_PROPERTY(Type, name, ...) \
|
||||
Q_PROPERTY(Type name READ name WRITE set_##name NOTIFY name##Changed) \
|
||||
public: \
|
||||
[[nodiscard]] Type name() const { \
|
||||
return m_##name; \
|
||||
} \
|
||||
void set_##name(const Type& value) { \
|
||||
if (ConfigObject::updateMember(m_##name, value)) { \
|
||||
markPropertyLoaded(QStringLiteral(#name)); \
|
||||
Q_EMIT name##Changed(); \
|
||||
notifyPropertyChanged( \
|
||||
QStringLiteral(#name), QVariant::fromValue(m_##name)); \
|
||||
} \
|
||||
} \
|
||||
Q_SIGNAL void name##Changed(); \
|
||||
\
|
||||
private: \
|
||||
Type m_##name __VA_OPT__(= __VA_ARGS__);
|
||||
|
||||
#define CONFIG_SUBOBJECT(Type, name) \
|
||||
Q_PROPERTY(ZShell::config::Type* name READ name CONSTANT) \
|
||||
\
|
||||
public: \
|
||||
[[nodiscard]] Type* name() const { \
|
||||
return m_##name; \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
Type* m_##name = nullptr;
|
||||
|
||||
class ConfigObject : public ConfigNode {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigObject(QObject* parent = nullptr);
|
||||
|
||||
void loadFromJson(const QJsonValue& json) override;
|
||||
[[nodiscard]] QJsonValue toJson() const override;
|
||||
void clearLoadedKeys() override;
|
||||
[[nodiscard]] QStringList unknownKeys() const override;
|
||||
[[nodiscard]] QList<ConfigNode*> childNodes() const override;
|
||||
void resyncFromGlobal() override;
|
||||
|
||||
[[nodiscard]] virtual QStringList identityKeys() const;
|
||||
|
||||
[[nodiscard]] bool isPropertyLoaded(const QString& name) const;
|
||||
[[nodiscard]] bool isGlobalOnly(const QString& name) const;
|
||||
[[nodiscard]] QStringList globalOnlyKeys() const;
|
||||
|
||||
Q_INVOKABLE void resetOption(const QString& name);
|
||||
|
||||
template <typename T> static bool updateMember(T& member, const T& value) {
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
if (qFuzzyCompare(member + 1.0, value + 1.0)) return false;
|
||||
} else {
|
||||
if (member == value) return false;
|
||||
}
|
||||
member = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void syncValuesFromGlobal() override;
|
||||
void onGlobalPropertiesChanged(
|
||||
const QMap<QString, QVariant>& changed) override;
|
||||
[[nodiscard]] QString childPath(const ConfigNode* child) const override;
|
||||
|
||||
void markPropertyLoaded(const QString& name);
|
||||
void markGlobalOnly(const QString& name);
|
||||
|
||||
private:
|
||||
QSet<QString> m_loadedKeys;
|
||||
QSet<QString> m_globalOnlyKeys;
|
||||
QJsonObject m_extras;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Performance : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(bool, showBattery, false)
|
||||
CFG_PROPERTY(bool, showCpu, true)
|
||||
CFG_PROPERTY(bool, showGpu, true)
|
||||
CFG_PROPERTY(bool, showMemory, true)
|
||||
CFG_PROPERTY(bool, showNetwork, true)
|
||||
CFG_PROPERTY(bool, showStorage, true)
|
||||
CFG_PROPERTY(bool, showVram, true)
|
||||
|
||||
public:
|
||||
explicit Performance(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class DashboardSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, dateTimeWidth, 110)
|
||||
CFG_PROPERTY(int, infoIconSize, 25)
|
||||
CFG_PROPERTY(int, infoWidth, 200)
|
||||
CFG_PROPERTY(int, mediaCoverArtSize, 150)
|
||||
CFG_PROPERTY(int, mediaProgressSweep, 180)
|
||||
CFG_PROPERTY(int, mediaProgressThickness, 8)
|
||||
CFG_PROPERTY(int, mediaVisualizerSize, 200)
|
||||
CFG_PROPERTY(int, mediaWidth, 200)
|
||||
CFG_PROPERTY(int, resourceProgessThickness, 10)
|
||||
CFG_PROPERTY(int, resourceSize, 200)
|
||||
CFG_PROPERTY(int, tabIndicatorHeight, 3)
|
||||
CFG_PROPERTY(int, tabIndicatorSpacing, 5)
|
||||
CFG_PROPERTY(int, weatherWidth, 250)
|
||||
|
||||
public:
|
||||
explicit DashboardSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Dashboard : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(int, mediaUpdateInterval, 2000)
|
||||
CONFIG_SUBOBJECT(Performance, performance)
|
||||
CFG_PROPERTY(int, resourceUpdateInterval, 1000)
|
||||
CONFIG_SUBOBJECT(DashboardSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Dashboard(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_performance(new Performance(this))
|
||||
, m_sizes(new DashboardSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <QStringList>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Dock : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enable, false)
|
||||
CFG_PROPERTY(int, height, 80)
|
||||
CFG_PROPERTY(bool, hoverToReveal, false)
|
||||
CFG_PROPERTY(QStringList, ignoredAppRegexes, {})
|
||||
CFG_PROPERTY(
|
||||
QStringList,
|
||||
pinnedApps,
|
||||
(QStringList{
|
||||
QStringLiteral("com.ayugram.desktop"),
|
||||
QStringLiteral("com.obsproject.studio"),
|
||||
QStringLiteral("librewolf")}))
|
||||
CFG_PROPERTY(bool, pinnedOnStartup, false)
|
||||
|
||||
public:
|
||||
explicit Dock(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,158 @@
|
||||
#pragma once
|
||||
#include "configlist.hpp"
|
||||
#include "configobject.hpp"
|
||||
#include <QStringList>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class BatteryThresholdEntry : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, icon)
|
||||
CFG_PROPERTY(QString, message)
|
||||
CFG_PROPERTY(QString, name)
|
||||
CFG_PROPERTY(int, perc)
|
||||
|
||||
public:
|
||||
explicit BatteryThresholdEntry(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] QStringList identityKeys() const override {
|
||||
return {QStringLiteral("perc")};
|
||||
}
|
||||
};
|
||||
|
||||
CONFIG_LIST_TYPE(BatteryThresholdEntry, BatteryThresholdList)
|
||||
|
||||
class IdleTimeoutEntry : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, idleAction)
|
||||
CFG_PROPERTY(QString, name)
|
||||
CFG_PROPERTY(int, timeout)
|
||||
|
||||
public:
|
||||
explicit IdleTimeoutEntry(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] QStringList identityKeys() const override {
|
||||
return {QStringLiteral("name")};
|
||||
}
|
||||
};
|
||||
|
||||
CONFIG_LIST_TYPE(IdleTimeoutEntry, IdleTimeoutList)
|
||||
|
||||
class Apps : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QStringList, archiver, {QStringLiteral("ark")})
|
||||
CFG_PROPERTY(QStringList, audio, {QStringLiteral("pavucontrol")})
|
||||
CFG_PROPERTY(QStringList, document, {QStringLiteral("libreoffice")})
|
||||
CFG_PROPERTY(QStringList, editor, {QStringLiteral("kate")})
|
||||
CFG_PROPERTY(QStringList, explorer, {QStringLiteral("dolphin")})
|
||||
CFG_PROPERTY(QStringList, image, {QStringLiteral("imv")})
|
||||
CFG_PROPERTY(QStringList, playback, {QStringLiteral("vlc")})
|
||||
CFG_PROPERTY(QStringList, terminal, {QStringLiteral("wezterm")})
|
||||
|
||||
public:
|
||||
explicit Apps(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Battery : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, critPerc, 5)
|
||||
CONFIG_LIST(
|
||||
BatteryThresholdList,
|
||||
popupThresholds,
|
||||
{
|
||||
vmap(
|
||||
{{"icon", "battery_android_frame_2"},
|
||||
{"message", "Battery low"},
|
||||
{"name", "Low battery"},
|
||||
{"perc", 20}}),
|
||||
vmap(
|
||||
{{"icon", "battery_android_frame_2"},
|
||||
{"message", "Battery lower"},
|
||||
{"name", "Low battery"},
|
||||
{"perc", 15}}),
|
||||
vmap(
|
||||
{{"icon", "battery_android_frame_2"},
|
||||
{"message", "Battery lowest"},
|
||||
{"name", "Low battery"},
|
||||
{"perc", 10}}),
|
||||
})
|
||||
|
||||
public:
|
||||
explicit Battery(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class ColorSettings : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, hyprsunsetTemp, 2600)
|
||||
CFG_PROPERTY(QString, mode, QStringLiteral("dark"))
|
||||
CFG_PROPERTY(bool, neovimColors, false)
|
||||
CFG_PROPERTY(bool, scheduleDark, false)
|
||||
CFG_PROPERTY(int, scheduleDarkEnd, 600)
|
||||
CFG_PROPERTY(int, scheduleDarkStart, 1140)
|
||||
CFG_PROPERTY(bool, scheduleHyprsunset, true)
|
||||
CFG_PROPERTY(int, scheduleHyprsunsetEnd, 570)
|
||||
CFG_PROPERTY(int, scheduleHyprsunsetStart, 1200)
|
||||
CFG_PROPERTY(bool, schemeGeneration, true)
|
||||
CFG_PROPERTY(bool, smart, false)
|
||||
|
||||
public:
|
||||
explicit ColorSettings(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Idle : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_LIST(
|
||||
IdleTimeoutList,
|
||||
timeouts,
|
||||
{
|
||||
vmap(
|
||||
{{"idleAction", QStringLiteral("lock")},
|
||||
{"name", QStringLiteral("Lock")},
|
||||
{"timeout", 180}}),
|
||||
})
|
||||
|
||||
public:
|
||||
explicit Idle(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class General : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(Apps, apps)
|
||||
CONFIG_SUBOBJECT(Battery, battery)
|
||||
CONFIG_SUBOBJECT(ColorSettings, color)
|
||||
CFG_PROPERTY(QString, dateFormat, QStringLiteral("ddd d MMM - hh:mm:ss"))
|
||||
CFG_PROPERTY(bool, desktopIcons, true)
|
||||
CONFIG_SUBOBJECT(Idle, idle)
|
||||
CFG_PROPERTY(QString, logo, QString())
|
||||
CFG_PROPERTY(bool, showOverFullscreen, true)
|
||||
CFG_PROPERTY(
|
||||
QString,
|
||||
wallpaperPath,
|
||||
QStringLiteral("/mnt/IronWolf/SDImages/SWWW_Wals/"))
|
||||
|
||||
public:
|
||||
explicit General(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_apps(new Apps(this))
|
||||
, m_battery(new Battery(this))
|
||||
, m_color(new ColorSettings(this))
|
||||
, m_idle(new Idle(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,177 @@
|
||||
#pragma once
|
||||
#include "configlist.hpp"
|
||||
#include "configobject.hpp"
|
||||
#include <QStringList>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class LauncherActionEntry : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QVariantList, command)
|
||||
CFG_PROPERTY(bool, dangerous, false)
|
||||
CFG_PROPERTY(QString, description)
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(QString, icon)
|
||||
CFG_PROPERTY(QString, name)
|
||||
|
||||
public:
|
||||
explicit LauncherActionEntry(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] QStringList identityKeys() const override {
|
||||
return {QStringLiteral("name")};
|
||||
}
|
||||
};
|
||||
|
||||
CONFIG_LIST_TYPE(LauncherActionEntry, LauncherActionList)
|
||||
|
||||
class LauncherSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, itemHeight, 50)
|
||||
CFG_PROPERTY(int, itemWidth, 600)
|
||||
CFG_PROPERTY(int, wallpaperHeight, 200)
|
||||
CFG_PROPERTY(int, wallpaperWidth, 280)
|
||||
|
||||
public:
|
||||
explicit LauncherSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class UseFuzzy : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, actions, true)
|
||||
CFG_PROPERTY(bool, apps, true)
|
||||
CFG_PROPERTY(bool, schemes, true)
|
||||
CFG_PROPERTY(bool, variants, true)
|
||||
CFG_PROPERTY(bool, wallpapers, true)
|
||||
|
||||
public:
|
||||
explicit UseFuzzy(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Launcher : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, actionPrefix, QStringLiteral("<"))
|
||||
CONFIG_LIST(
|
||||
LauncherActionList,
|
||||
actions,
|
||||
{
|
||||
vmap(
|
||||
{{"command", QVariantList{"autocomplete", "calc"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Do simple math equations"},
|
||||
{"enabled", true},
|
||||
{"icon", "calculate"},
|
||||
{"name", "Calculator"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"setMode", "light"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Change to light mode"},
|
||||
{"enabled", true},
|
||||
{"icon", "light_mode"},
|
||||
{"name", "Light"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"setMode", "dark"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Change to dark mode"},
|
||||
{"enabled", true},
|
||||
{"icon", "dark_mode"},
|
||||
{"name", "Dark"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"autocomplete", "wallpaper"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Change the current wallpaper"},
|
||||
{"enabled", true},
|
||||
{"icon", "image"},
|
||||
{"name", "Wallpaper"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"autocomplete", "variant"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Change the current scheme variant"},
|
||||
{"enabled", true},
|
||||
{"icon", "colors"},
|
||||
{"name", "Variant"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"systemctl", "poweroff"}},
|
||||
{"dangerous", true},
|
||||
{"description", "Shutdown the system"},
|
||||
{"enabled", true},
|
||||
{"icon", "power_settings_new"},
|
||||
{"name", "Shutdown"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"systemctl", "reboot"}},
|
||||
{"dangerous", true},
|
||||
{"description", "Reboot the system"},
|
||||
{"enabled", true},
|
||||
{"icon", "cached"},
|
||||
{"name", "Reboot"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"loginctl", "terminate-user", ""}},
|
||||
{"dangerous", true},
|
||||
{"description", "Log out of the current session"},
|
||||
{"enabled", true},
|
||||
{"icon", "logout"},
|
||||
{"name", "Logout"}}),
|
||||
vmap(
|
||||
{{"command", QVariantList{"loginctl", "lock-session"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Lock the current session"},
|
||||
{"enabled", true},
|
||||
{"icon", "lock"},
|
||||
{"name", "Lock"}}),
|
||||
vmap(
|
||||
{{"command",
|
||||
QVariantList{"systemctl", "suspend-then-hibernate"}},
|
||||
{"dangerous", false},
|
||||
{"description", "Suspend then hibernate"},
|
||||
{"enabled", true},
|
||||
{"icon", "bedtime"},
|
||||
{"name", "Sleep"}}),
|
||||
})
|
||||
CFG_PROPERTY(int, dragThreshold, 150)
|
||||
CFG_PROPERTY(bool, enableDangerousActions, true)
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(
|
||||
QStringList,
|
||||
favoriteApps,
|
||||
{QStringLiteral("Balatro"),
|
||||
QStringLiteral("Slay the Spire 2"),
|
||||
QStringLiteral("com.obsproject.Studio")})
|
||||
CFG_PROPERTY(
|
||||
QStringList,
|
||||
hiddenApps,
|
||||
{QStringLiteral("zellij"),
|
||||
QStringLiteral("vim"),
|
||||
QStringLiteral("jshell-java-openjdk"),
|
||||
QStringLiteral("jconsole-java-openjdk"),
|
||||
QStringLiteral("jshell-java21-openjdk"),
|
||||
QStringLiteral("jconsole-java21-openjdk"),
|
||||
QStringLiteral("jshell-java17-openjdk"),
|
||||
QStringLiteral("jconsole-java17-openjdk"),
|
||||
QStringLiteral("org.neovim.nvim"),
|
||||
QStringLiteral("avahi-discover"),
|
||||
QStringLiteral("bvnc"),
|
||||
QStringLiteral("bssh"),
|
||||
QStringLiteral("nm-connection-editor")})
|
||||
CFG_PROPERTY(int, maxAppsShown, 18)
|
||||
CFG_PROPERTY(int, maxWallpapers, 7)
|
||||
CONFIG_SUBOBJECT(LauncherSizes, sizes)
|
||||
CFG_PROPERTY(QString, specialPrefix, QStringLiteral("@"))
|
||||
CONFIG_SUBOBJECT(UseFuzzy, useFuzzy)
|
||||
CFG_PROPERTY(bool, uwsm, true)
|
||||
|
||||
public:
|
||||
explicit Launcher(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_sizes(new LauncherSizes(this))
|
||||
, m_useFuzzy(new UseFuzzy(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class LockSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, centerWidth, 600)
|
||||
CFG_PROPERTY(qreal, heightMult, 0.7)
|
||||
CFG_PROPERTY(qreal, ratio, 1.78)
|
||||
|
||||
public:
|
||||
explicit LockSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Lock : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, blurAmount, 10)
|
||||
CFG_PROPERTY(bool, enableFprint, true)
|
||||
CFG_PROPERTY(int, maxFprintTries, 3)
|
||||
CFG_PROPERTY(bool, recolorLogo, false)
|
||||
CFG_PROPERTY(bool, showNotifContent, true)
|
||||
CFG_PROPERTY(bool, showNotifIcon, true)
|
||||
CONFIG_SUBOBJECT(LockSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Lock(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_sizes(new LockSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class NotifsSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, badge, 20)
|
||||
CFG_PROPERTY(int, image, 41)
|
||||
CFG_PROPERTY(int, width, 400)
|
||||
|
||||
public:
|
||||
explicit NotifsSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Notifs : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, actionOnClick, false)
|
||||
CFG_PROPERTY(int, appNotifCooldown, 0)
|
||||
CFG_PROPERTY(qreal, clearThreshold, 0.3)
|
||||
CFG_PROPERTY(int, defaultExpireTimeout, 5000)
|
||||
CFG_PROPERTY(int, expandThreshold, 20)
|
||||
CFG_PROPERTY(bool, expire, true)
|
||||
CFG_PROPERTY(int, groupPreviewNum, 5)
|
||||
CFG_PROPERTY(bool, openExpanded, false)
|
||||
CFG_PROPERTY(bool, showInFullscreen, false)
|
||||
CONFIG_SUBOBJECT(NotifsSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Notifs(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_sizes(new NotifsSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class OsdSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, sliderHeight, 150)
|
||||
CFG_PROPERTY(int, sliderWidth, 30)
|
||||
|
||||
public:
|
||||
explicit OsdSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Osd : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, allMonBrightness, true)
|
||||
CFG_PROPERTY(bool, enableBrightness, true)
|
||||
CFG_PROPERTY(bool, enableMicrophone, true)
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(int, hideDelay, 3000)
|
||||
CONFIG_SUBOBJECT(OsdSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Osd(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_sizes(new OsdSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <QVariantList>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class Screenshot : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enable_pp, false)
|
||||
CFG_PROPERTY(QString, mode, QStringLiteral("manual"))
|
||||
CFG_PROPERTY(int, radius, 49)
|
||||
CFG_PROPERTY(bool, rounding, false)
|
||||
CFG_PROPERTY(bool, saveOnCopy, false)
|
||||
CFG_PROPERTY(bool, shadow, true)
|
||||
CFG_PROPERTY(int, shadow_blur, 0)
|
||||
CFG_PROPERTY(QVariantList, shadow_color, (QVariantList{0, 0, 0, 160}))
|
||||
CFG_PROPERTY(int, shadow_offset_x, 30)
|
||||
CFG_PROPERTY(int, shadow_offset_y, 50)
|
||||
|
||||
public:
|
||||
explicit Screenshot(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
#include "configlist.hpp"
|
||||
#include "configobject.hpp"
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class PlayerAliasEntry : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(QString, from)
|
||||
CFG_PROPERTY(QString, to)
|
||||
|
||||
public:
|
||||
explicit PlayerAliasEntry(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] QStringList identityKeys() const override {
|
||||
return {QStringLiteral("from")};
|
||||
}
|
||||
};
|
||||
|
||||
CONFIG_LIST_TYPE(PlayerAliasEntry, PlayerAliasList)
|
||||
|
||||
class Services : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, audioIncrement, 0.1)
|
||||
CFG_PROPERTY(qreal, brightnessIncrement, 0.1)
|
||||
CFG_PROPERTY(bool, ddcutilService, true)
|
||||
CFG_PROPERTY(QString, defaultPlayer, QStringLiteral("Spotify"))
|
||||
CFG_PROPERTY(QString, gpuType, QStringLiteral("NVIDIA"))
|
||||
CFG_PROPERTY(qreal, maxVolume, 1)
|
||||
CFG_PROPERTY(qreal, minBrightness, 0.01)
|
||||
CONFIG_LIST(
|
||||
PlayerAliasList,
|
||||
playerAliases,
|
||||
{
|
||||
vmap(
|
||||
{{"from", QStringLiteral("com.github.th_ch.youtube_music")},
|
||||
{"to", QStringLiteral("YT Music")}}),
|
||||
})
|
||||
CFG_PROPERTY(bool, updates, true)
|
||||
CFG_PROPERTY(bool, useFahrenheit, false)
|
||||
CFG_PROPERTY(bool, useTwelveHourClock, false)
|
||||
CFG_PROPERTY(int, visualizerBars, 50)
|
||||
CFG_PROPERTY(QString, weatherLocation, QString())
|
||||
|
||||
public:
|
||||
explicit Services(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class SidebarSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, width, 520)
|
||||
|
||||
public:
|
||||
explicit SidebarSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Sidebar : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, dragThreshold, 30)
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CONFIG_SUBOBJECT(SidebarSizes, sizes)
|
||||
|
||||
public:
|
||||
explicit Sidebar(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_sizes(new SidebarSizes(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,221 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
|
||||
#include <QVariantList>
|
||||
#include <qqmlengine.h>
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class AppearanceRounding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, extraSmall, 4)
|
||||
CFG_PROPERTY(qreal, full, 1000)
|
||||
CFG_PROPERTY(qreal, large, 24)
|
||||
CFG_PROPERTY(qreal, medium, 16)
|
||||
CFG_PROPERTY(qreal, normal, 18)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(qreal, small, 12)
|
||||
CFG_PROPERTY(qreal, smallest, 8)
|
||||
|
||||
public:
|
||||
explicit AppearanceRounding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AppearancePadding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, extraLarge, 28)
|
||||
CFG_PROPERTY(qreal, extraLargeIncreased, 32)
|
||||
CFG_PROPERTY(qreal, extraSmall, 4)
|
||||
CFG_PROPERTY(qreal, large, 16)
|
||||
CFG_PROPERTY(qreal, largeIncreased, 20)
|
||||
CFG_PROPERTY(qreal, larger, 12)
|
||||
CFG_PROPERTY(qreal, normal, 8)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(qreal, small, 5)
|
||||
CFG_PROPERTY(qreal, smaller, 7)
|
||||
CFG_PROPERTY(qreal, smallest, 2)
|
||||
|
||||
public:
|
||||
explicit AppearancePadding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AppearanceSpacing : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, extraSmall, 4)
|
||||
CFG_PROPERTY(qreal, large, 20)
|
||||
CFG_PROPERTY(qreal, larger, 16)
|
||||
CFG_PROPERTY(qreal, normal, 12)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(qreal, small, 8)
|
||||
CFG_PROPERTY(qreal, smaller, 10)
|
||||
|
||||
public:
|
||||
explicit AppearanceSpacing(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontSizeTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, extraLarge, 28)
|
||||
CFG_PROPERTY(qreal, large, 18)
|
||||
CFG_PROPERTY(qreal, larger, 16)
|
||||
CFG_PROPERTY(qreal, medium, 14)
|
||||
CFG_PROPERTY(qreal, normal, 13)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(qreal, small, 11)
|
||||
CFG_PROPERTY(qreal, smaller, 12)
|
||||
|
||||
public:
|
||||
explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(FontSizeTokens, size)
|
||||
|
||||
public:
|
||||
explicit FontTokens(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_size(new FontSizeTokens(this)) {}
|
||||
};
|
||||
|
||||
class AnimCurves : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
emphasized,
|
||||
QVariantList{
|
||||
0.05,
|
||||
0,
|
||||
2.0 / 15.0,
|
||||
0.06,
|
||||
1.0 / 6.0,
|
||||
0.4,
|
||||
5.0 / 24.0,
|
||||
0.82,
|
||||
0.25,
|
||||
1,
|
||||
1,
|
||||
1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList, emphasizedAccel, QVariantList{0.3, 0, 0.8, 0.15, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList, emphasizedDecel, QVariantList{0.05, 0.7, 0.1, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveDefaultEffects,
|
||||
QVariantList{0.34, 0.8, 0.34, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveDefaultSpatial,
|
||||
QVariantList{0.38, 1.21, 0.22, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList, expressiveEffects, QVariantList{0.34, 0.8, 0.34, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveFastEffects,
|
||||
QVariantList{0.31, 0.94, 0.34, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveFastSpatial,
|
||||
QVariantList{0.42, 1.67, 0.21, 0.9, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveSlowEffects,
|
||||
QVariantList{0.34, 0.88, 0.34, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(
|
||||
QVariantList,
|
||||
expressiveSlowSpatial,
|
||||
QVariantList{0.39, 1.29, 0.35, 0.98, 1, 1})
|
||||
|
||||
CFG_PROPERTY(QVariantList, standard, QVariantList{0.2, 0, 0, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(QVariantList, standardAccel, QVariantList{0.3, 0, 1, 1, 1, 1})
|
||||
|
||||
CFG_PROPERTY(QVariantList, standardDecel, QVariantList{0, 0, 0, 1, 1, 1})
|
||||
|
||||
public:
|
||||
explicit AnimCurves(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AnimDurations : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, expressiveDefaultSpatial, 500)
|
||||
CFG_PROPERTY(int, expressiveEffects, 200)
|
||||
CFG_PROPERTY(int, expressiveFastEffects, 150)
|
||||
CFG_PROPERTY(int, expressiveFastSpatial, 350)
|
||||
CFG_PROPERTY(int, expressiveSlowEffects, 300)
|
||||
CFG_PROPERTY(int, extraLarge, 1000)
|
||||
CFG_PROPERTY(int, large, 600)
|
||||
CFG_PROPERTY(int, normal, 400)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(int, small, 200)
|
||||
|
||||
public:
|
||||
explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AnimTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(AnimCurves, curves)
|
||||
CONFIG_SUBOBJECT(AnimDurations, durations)
|
||||
|
||||
public:
|
||||
explicit AnimTokens(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_curves(new AnimCurves(this))
|
||||
, m_durations(new AnimDurations(this)) {}
|
||||
};
|
||||
|
||||
class Tokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
CONFIG_SUBOBJECT(AppearanceRounding, rounding)
|
||||
CONFIG_SUBOBJECT(AppearancePadding, padding)
|
||||
CONFIG_SUBOBJECT(AppearanceSpacing, spacing)
|
||||
CONFIG_SUBOBJECT(FontTokens, font)
|
||||
CONFIG_SUBOBJECT(AnimTokens, anim)
|
||||
|
||||
public:
|
||||
explicit Tokens(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_rounding(new AppearanceRounding(this))
|
||||
, m_padding(new AppearancePadding(this))
|
||||
, m_spacing(new AppearanceSpacing(this))
|
||||
, m_font(new FontTokens(this))
|
||||
, m_anim(new AnimTokens(this)) {}
|
||||
|
||||
static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); }
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "configobject.hpp"
|
||||
#include <QVariantList>
|
||||
#include <QStringList>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class UtilitiesSizes : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, toastWidth, 430)
|
||||
CFG_PROPERTY(int, width, 430)
|
||||
|
||||
public:
|
||||
explicit UtilitiesSizes(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Toasts : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, audioInputChanged, true)
|
||||
CFG_PROPERTY(bool, audioOutputChanged, true)
|
||||
CFG_PROPERTY(bool, capsLockChanged, true)
|
||||
CFG_PROPERTY(bool, chargingChanged, true)
|
||||
CFG_PROPERTY(bool, configLoaded, true)
|
||||
CFG_PROPERTY(bool, dndChanged, true)
|
||||
CFG_PROPERTY(bool, gameModeChanged, true)
|
||||
CFG_PROPERTY(bool, kbLayoutChanged, true)
|
||||
CFG_PROPERTY(bool, kbLimit, true)
|
||||
CFG_PROPERTY(bool, nowPlaying, false)
|
||||
CFG_PROPERTY(bool, numLockChanged, true)
|
||||
CFG_PROPERTY(bool, vpnChanged, true)
|
||||
|
||||
public:
|
||||
explicit Toasts(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Vpn : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, false)
|
||||
CFG_PROPERTY(QStringList, provider, (QStringList{QStringLiteral("netbird")}))
|
||||
|
||||
public:
|
||||
explicit Vpn(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Utilities : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(bool, enabled, true)
|
||||
CFG_PROPERTY(int, maxToasts, 4)
|
||||
CONFIG_SUBOBJECT(UtilitiesSizes, sizes)
|
||||
CONFIG_SUBOBJECT(Toasts, toasts)
|
||||
CONFIG_SUBOBJECT(Vpn, vpn)
|
||||
|
||||
public:
|
||||
explicit Utilities(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_sizes(new UtilitiesSizes(this))
|
||||
, m_toasts(new Toasts(this))
|
||||
, m_vpn(new Vpn(this)) {}
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
Reference in New Issue
Block a user