feat: fontbuilder to streamline font styling
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m10s
Python / verify (pull_request) Successful in 1m53s
Rust / fmt (pull_request) Successful in 34s
Rust / clippy (pull_request) Successful in 57s
C++ / fmt (pull_request) Failing after 4s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 10s
JS/TS / lint (pull_request) Successful in 9s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 1m10s
Python / verify (pull_request) Successful in 1m53s
Rust / fmt (pull_request) Successful in 34s
Rust / clippy (pull_request) Successful in 57s
This commit is contained in:
@@ -8,6 +8,8 @@ qml_module(ZShell-config
|
||||
config.hpp config.cpp
|
||||
migration.hpp migration.cpp
|
||||
anim.hpp anim.cpp
|
||||
fontbuilder.hpp fontbuilder.cpp
|
||||
font.hpp font.cpp
|
||||
tokens.hpp
|
||||
appearance.hpp
|
||||
background.hpp
|
||||
@@ -28,4 +30,6 @@ qml_module(ZShell-config
|
||||
services.hpp
|
||||
sidebar.hpp
|
||||
utilities.hpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
)
|
||||
|
||||
@@ -1,19 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
#include <QFont>
|
||||
#include <QVariantMap>
|
||||
#include <limits>
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class AnimDurations : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
|
||||
Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveDefaultEffects READ expressiveDefaultEffects NOTIFY
|
||||
scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveDefaultSpatial READ expressiveDefaultSpatial NOTIFY
|
||||
scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveFastEffects READ expressiveFastEffects NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveFastSpatial READ expressiveFastSpatial NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveSlowEffects READ expressiveSlowEffects NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int expressiveSlowSpatial READ expressiveSlowSpatial NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int large READ large NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int normal READ normal NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int small READ small NOTIFY scaleChanged)
|
||||
|
||||
public:
|
||||
explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] int small() const { return static_cast<int>(200 * scale()); }
|
||||
[[nodiscard]] int normal() const { return static_cast<int>(400 * scale()); }
|
||||
[[nodiscard]] int large() const { return static_cast<int>(600 * scale()); }
|
||||
[[nodiscard]] int extraLarge() const {
|
||||
return static_cast<int>(1000 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveFastSpatial() const {
|
||||
return static_cast<int>(350 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveDefaultSpatial() const {
|
||||
return static_cast<int>(500 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveSlowSpatial() const {
|
||||
return static_cast<int>(650 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveFastEffects() const {
|
||||
return static_cast<int>(150 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveDefaultEffects() const {
|
||||
return static_cast<int>(200 * scale());
|
||||
}
|
||||
[[nodiscard]] int expressiveSlowEffects() const {
|
||||
return static_cast<int>(300 * scale());
|
||||
}
|
||||
};
|
||||
|
||||
class Anim : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, mediaGifSpeedAdjustment, 300)
|
||||
CFG_PROPERTY(qreal, sessionGifSpeed, 0.7)
|
||||
CONFIG_SUBOBJECT(AnimDurations, durations)
|
||||
|
||||
public:
|
||||
explicit Anim(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
explicit Anim(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_durations(new AnimDurations(this)) {}
|
||||
};
|
||||
|
||||
class Deform : public ConfigObject {
|
||||
@@ -39,15 +98,161 @@ class FontFamily : public ConfigObject {
|
||||
explicit FontFamily(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class Font : public ConfigObject {
|
||||
namespace detail {
|
||||
|
||||
struct FontConfig {
|
||||
QString family = {};
|
||||
int size;
|
||||
int weight = QFont::Normal;
|
||||
bool italic = false;
|
||||
QVariantMap vaxes = {{QStringLiteral("ROND"), 25}};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class FontSizeNode : public ConfigObject {
|
||||
public:
|
||||
explicit FontSizeNode(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontStyleNode : public ConfigObject {
|
||||
public:
|
||||
explicit FontStyleNode(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
|
||||
virtual FontSizeNode* largeNode() const = 0;
|
||||
virtual FontSizeNode* mediumNode() const = 0;
|
||||
virtual FontSizeNode* smallNode() const = 0;
|
||||
virtual FontSizeNode* extraLargeNode() const { return nullptr; }
|
||||
};
|
||||
|
||||
#define ARG(...) __VA_ARGS__
|
||||
#define FONT(...) ZShell::config::detail::FontConfig __VA_ARGS__
|
||||
#define FONT_CONFIG(Style, Size, props) \
|
||||
class FontConfig##Style##Size : public FontSizeNode { \
|
||||
Q_OBJECT QML_ANONYMOUS \
|
||||
\
|
||||
CFG_PROPERTY(QString, family, ARG(props).family) \
|
||||
CFG_PROPERTY(int, size, ARG(props).size) \
|
||||
CFG_PROPERTY(int, weight, ARG(props).weight) \
|
||||
CFG_PROPERTY(bool, italic, ARG(props).italic) \
|
||||
CFG_PROPERTY(QVariantMap, vaxes, ARG(props).vaxes) \
|
||||
\
|
||||
public \
|
||||
: explicit FontConfig##Style##Size(QObject* parent = nullptr) \
|
||||
: FontSizeNode(parent) {} \
|
||||
};
|
||||
#define FONT_STYLE(Style, family_, large_, medium_, small_) \
|
||||
FONT_CONFIG(Style, Large, ARG(large_)) \
|
||||
FONT_CONFIG(Style, Medium, ARG(medium_)) \
|
||||
FONT_CONFIG(Style, Small, ARG(small_)) \
|
||||
\
|
||||
class FontStyle##Style : public FontStyleNode { \
|
||||
Q_OBJECT QML_ANONYMOUS \
|
||||
\
|
||||
CFG_PROPERTY(QString, family, family_) \
|
||||
CONFIG_SUBOBJECT(FontConfig##Style##Large, large) \
|
||||
CONFIG_SUBOBJECT(FontConfig##Style##Medium, medium) \
|
||||
CONFIG_SUBOBJECT(FontConfig##Style##Small, small) \
|
||||
\
|
||||
public \
|
||||
: explicit FontStyle##Style(QObject* parent = nullptr) \
|
||||
: FontStyleNode(parent) \
|
||||
, m_large(new FontConfig##Style##Large(this)) \
|
||||
, m_medium(new FontConfig##Style##Medium(this)) \
|
||||
, m_small(new FontConfig##Style##Small(this)) {} \
|
||||
\
|
||||
FontSizeNode* largeNode() const override { return m_large; } \
|
||||
FontSizeNode* mediumNode() const override { return m_medium; } \
|
||||
FontSizeNode* smallNode() const override { return m_small; } \
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
FONT_STYLE(Headline, QStringLiteral("GoogleSansFlex"),
|
||||
FONT({ .size = 32, .weight = QFont::Medium }),
|
||||
FONT({ .size = 28, .weight = QFont::Medium }),
|
||||
FONT({ .size = 24, .weight = QFont::Medium })
|
||||
)
|
||||
FONT_STYLE(Title, QStringLiteral("GoogleSansFlex"),
|
||||
FONT({ .size = 22, .weight = QFont::Medium }),
|
||||
FONT({ .size = 16, .weight = QFont::Medium }),
|
||||
FONT({ .size = 14, .weight = QFont::Medium })
|
||||
)
|
||||
FONT_STYLE(Body, QStringLiteral("GoogleSansFlex"),
|
||||
FONT({ .size = 16 }),
|
||||
FONT({ .size = 14 }),
|
||||
FONT({ .size = 12 })
|
||||
)
|
||||
FONT_STYLE(Label, QStringLiteral("GoogleSansFlex"),
|
||||
FONT({ .size = 14, .weight = QFont::Medium }),
|
||||
FONT({ .size = 12, .weight = QFont::Medium }),
|
||||
FONT({ .size = 11 })
|
||||
)
|
||||
FONT_STYLE(Mono, QStringLiteral("CaskaydiaCove NF"),
|
||||
FONT({ .size = 16, .vaxes = {} }),
|
||||
FONT({ .size = 14, .vaxes = {} }),
|
||||
FONT({ .size = 12, .vaxes = {} })
|
||||
)
|
||||
// clang-format on
|
||||
|
||||
FONT_CONFIG(Icon, ExtraLarge, FONT({.size = static_cast<int>(48 / 1.33)}))
|
||||
FONT_CONFIG(Icon, Large, FONT({.size = static_cast<int>(32 / 1.33)}))
|
||||
FONT_CONFIG(Icon, Medium, FONT({.size = static_cast<int>(24 / 1.33)}))
|
||||
FONT_CONFIG(Icon, Small, FONT({.size = static_cast<int>(20 / 1.33)}))
|
||||
|
||||
class FontStyleIcon : public FontStyleNode {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(FontFamily, family)
|
||||
CFG_PROPERTY(QString, family, QStringLiteral("Material Symbols Rounded"))
|
||||
CONFIG_SUBOBJECT(FontConfigIconExtraLarge, extraLarge)
|
||||
CONFIG_SUBOBJECT(FontConfigIconLarge, large)
|
||||
CONFIG_SUBOBJECT(FontConfigIconMedium, medium)
|
||||
CONFIG_SUBOBJECT(FontConfigIconSmall, small)
|
||||
|
||||
public:
|
||||
explicit Font(QObject* parent = nullptr)
|
||||
: ConfigObject(parent), m_family(new FontFamily(this)) {}
|
||||
explicit FontStyleIcon(QObject* parent = nullptr)
|
||||
: FontStyleNode(parent)
|
||||
, m_extraLarge(new FontConfigIconExtraLarge(this))
|
||||
, m_large(new FontConfigIconLarge(this))
|
||||
, m_medium(new FontConfigIconMedium(this))
|
||||
, m_small(new FontConfigIconSmall(this)) {}
|
||||
|
||||
FontSizeNode* extraLargeNode() const override { return m_extraLarge; }
|
||||
FontSizeNode* largeNode() const override { return m_large; }
|
||||
FontSizeNode* mediumNode() const override { return m_medium; }
|
||||
FontSizeNode* smallNode() const override { return m_small; }
|
||||
};
|
||||
|
||||
#undef ARG
|
||||
#undef FONT
|
||||
#undef FONT_CONFIG
|
||||
#undef FONT_STYLE
|
||||
|
||||
class AppearanceFont : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CONFIG_SUBOBJECT(FontFamily, family)
|
||||
CONFIG_SUBOBJECT(FontStyleHeadline, headline)
|
||||
CONFIG_SUBOBJECT(FontStyleTitle, title)
|
||||
CONFIG_SUBOBJECT(FontStyleBody, body)
|
||||
CONFIG_SUBOBJECT(FontStyleLabel, label)
|
||||
CONFIG_SUBOBJECT(FontStyleMono, mono)
|
||||
CONFIG_SUBOBJECT(FontStyleIcon, icon)
|
||||
CFG_PROPERTY(QString, clock, QStringLiteral("Rubik"))
|
||||
CFG_PROPERTY(QString, workspaces, QStringLiteral("Rubik"))
|
||||
|
||||
public:
|
||||
explicit AppearanceFont(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_family(new FontFamily(this))
|
||||
, m_headline(new FontStyleHeadline(this))
|
||||
, m_title(new FontStyleTitle(this))
|
||||
, m_body(new FontStyleBody(this))
|
||||
, m_label(new FontStyleLabel(this))
|
||||
, m_mono(new FontStyleMono(this))
|
||||
, m_icon(new FontStyleIcon(this)) {}
|
||||
};
|
||||
|
||||
class Transparency : public ConfigObject {
|
||||
@@ -62,13 +267,140 @@ class Transparency : public ConfigObject {
|
||||
explicit Transparency(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AppearanceRounding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
|
||||
Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int small READ small NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int medium READ medium NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int large READ large NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int full READ full CONSTANT)
|
||||
|
||||
public:
|
||||
explicit AppearanceRounding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] int extraSmall() const {
|
||||
return static_cast<int>(4 * scale());
|
||||
}
|
||||
[[nodiscard]] int small() const { return static_cast<int>(8 * scale()); }
|
||||
[[nodiscard]] int medium() const { return static_cast<int>(12 * scale()); }
|
||||
[[nodiscard]] int large() const { return static_cast<int>(16 * scale()); }
|
||||
[[nodiscard]] int largeIncreased() const {
|
||||
return static_cast<int>(20 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLarge() const {
|
||||
return static_cast<int>(28 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLargeIncreased() const {
|
||||
return static_cast<int>(32 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraExtraLarge() const {
|
||||
return static_cast<int>(48 * scale());
|
||||
}
|
||||
[[nodiscard]] int full() const { return std::numeric_limits<int>::max(); }
|
||||
};
|
||||
|
||||
class AppearanceSpacing : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
|
||||
Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int small READ small NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int medium READ medium NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int large READ large NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged)
|
||||
|
||||
public:
|
||||
explicit AppearanceSpacing(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] int extraSmall() const {
|
||||
return static_cast<int>(4 * scale());
|
||||
}
|
||||
[[nodiscard]] int small() const { return static_cast<int>(8 * scale()); }
|
||||
[[nodiscard]] int medium() const { return static_cast<int>(12 * scale()); }
|
||||
[[nodiscard]] int large() const { return static_cast<int>(16 * scale()); }
|
||||
[[nodiscard]] int largeIncreased() const {
|
||||
return static_cast<int>(20 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLarge() const {
|
||||
return static_cast<int>(28 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLargeIncreased() const {
|
||||
return static_cast<int>(32 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraExtraLarge() const {
|
||||
return static_cast<int>(48 * scale());
|
||||
}
|
||||
};
|
||||
|
||||
class AppearancePadding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
|
||||
Q_PROPERTY(int extraSmall READ extraSmall NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int smaller READ smaller NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int small READ small NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int medium READ medium NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int large READ large NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int largeIncreased READ largeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraLarge READ extraLarge NOTIFY scaleChanged)
|
||||
Q_PROPERTY(
|
||||
int extraLargeIncreased READ extraLargeIncreased NOTIFY scaleChanged)
|
||||
Q_PROPERTY(int extraExtraLarge READ extraExtraLarge NOTIFY scaleChanged)
|
||||
|
||||
public:
|
||||
explicit AppearancePadding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
|
||||
[[nodiscard]] int extraSmall() const {
|
||||
return static_cast<int>(4 * scale());
|
||||
}
|
||||
[[nodiscard]] int smaller() const { return static_cast<int>(5 * scale()); }
|
||||
[[nodiscard]] int small() const { return static_cast<int>(8 * scale()); }
|
||||
[[nodiscard]] int medium() const { return static_cast<int>(12 * scale()); }
|
||||
[[nodiscard]] int large() const { return static_cast<int>(16 * scale()); }
|
||||
[[nodiscard]] int largeIncreased() const {
|
||||
return static_cast<int>(20 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLarge() const {
|
||||
return static_cast<int>(28 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraLargeIncreased() const {
|
||||
return static_cast<int>(32 * scale());
|
||||
}
|
||||
[[nodiscard]] int extraExtraLarge() const {
|
||||
return static_cast<int>(48 * scale());
|
||||
}
|
||||
};
|
||||
|
||||
class Appearance : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(Anim, anim)
|
||||
CONFIG_SUBOBJECT(Deform, deform)
|
||||
CONFIG_SUBOBJECT(Font, font)
|
||||
CONFIG_SUBOBJECT(AppearanceFont, font)
|
||||
CONFIG_SUBOBJECT(AppearanceRounding, rounding)
|
||||
CONFIG_SUBOBJECT(AppearanceSpacing, spacing)
|
||||
CONFIG_SUBOBJECT(AppearancePadding, padding)
|
||||
CONFIG_SUBOBJECT(Transparency, transparency)
|
||||
|
||||
public:
|
||||
@@ -76,8 +408,11 @@ class Appearance : public ConfigObject {
|
||||
: ConfigObject(parent)
|
||||
, m_anim(new Anim(this))
|
||||
, m_deform(new Deform(this))
|
||||
, m_font(new Font(this))
|
||||
, m_transparency(new Transparency(this)) {}
|
||||
, m_font(new AppearanceFont(this))
|
||||
, m_rounding(new AppearanceRounding(this))
|
||||
, m_spacing(new AppearanceSpacing(this))
|
||||
, m_padding(new AppearancePadding(this))
|
||||
, m_transparency(new Transparency(this)) {};
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
|
||||
@@ -65,13 +65,12 @@ void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
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)) {
|
||||
known.insert(key);
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
node->loadFromJson(jsonVal);
|
||||
continue;
|
||||
@@ -80,6 +79,8 @@ void ConfigObject::loadFromJson(const QJsonValue& json) {
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
known.insert(key);
|
||||
|
||||
if (!jsonValueMatchesType(jsonVal, prop.metaType())) {
|
||||
qWarning() << "Config: type mismatch for" << key << "in"
|
||||
<< meta->className() << "- expected"
|
||||
@@ -218,18 +219,9 @@ void ConfigObject::materializeDefaults() {
|
||||
|
||||
for (int i = basePropertyOffset(); i < meta->propertyCount(); ++i) {
|
||||
const auto prop = meta->property(i);
|
||||
const auto key = QString::fromUtf8(prop.name());
|
||||
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>()) {
|
||||
if (auto* const node = prop.read(this).value<ConfigNode*>())
|
||||
node->materializeDefaults();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!prop.isWritable()) continue;
|
||||
|
||||
if (m_global) continue;
|
||||
|
||||
m_loadedKeys.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
#include "font.hpp"
|
||||
|
||||
#include "appearance.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
FontStyleBase::FontStyleBase(QObject* parent) : QObject(parent) {}
|
||||
|
||||
QFont FontStyleBase::large() const {
|
||||
return m_large;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::medium() const {
|
||||
return m_medium;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::small() const {
|
||||
return m_small;
|
||||
}
|
||||
|
||||
QFont FontStyleBase::buildFont(
|
||||
const FontSizeNode* cfg, const QString& fallbackFamily, qreal scale) {
|
||||
const auto family = cfg->property("family").toString();
|
||||
const auto size = cfg->property("size").toInt();
|
||||
const auto weight = cfg->property("weight").value<QFont::Weight>();
|
||||
const auto italic = cfg->property("italic").toBool();
|
||||
const auto vaxes = cfg->property("vaxes").toMap();
|
||||
|
||||
QFont font;
|
||||
font.setFamily(family.isEmpty() ? fallbackFamily : family);
|
||||
const int scaledSize = static_cast<int>(size * scale);
|
||||
const int cappedSize = scaledSize > 0 ? scaledSize : 1;
|
||||
font.setPointSize(cappedSize);
|
||||
font.setVariableAxis("opsz", static_cast<float>(cappedSize));
|
||||
font.setWeight(weight);
|
||||
font.setVariableAxis("wght", static_cast<float>(weight));
|
||||
font.setItalic(italic);
|
||||
|
||||
for (auto it = vaxes.constBegin(); it != vaxes.constEnd(); ++it) {
|
||||
if (auto tag = QFont::Tag::fromString(it.key()))
|
||||
font.setVariableAxis(*tag, it.value().toFloat());
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void FontStyleBase::bind(FontStyleNode* cfg) {
|
||||
if (m_cfg == cfg) return;
|
||||
|
||||
if (m_cfg) {
|
||||
disconnect(m_cfg, nullptr, this, nullptr);
|
||||
disconnect(m_cfg->largeNode(), nullptr, this, nullptr);
|
||||
disconnect(m_cfg->mediumNode(), nullptr, this, nullptr);
|
||||
disconnect(m_cfg->smallNode(), nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
m_cfg = cfg;
|
||||
|
||||
if (cfg) {
|
||||
connect(
|
||||
cfg, &ConfigNode::propertiesChanged, this, &FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->largeNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->mediumNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
connect(
|
||||
cfg->smallNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&FontStyleBase::rebuild);
|
||||
}
|
||||
|
||||
rebuild();
|
||||
}
|
||||
|
||||
void FontStyleBase::rebuild() {
|
||||
if (m_cfg) {
|
||||
const auto family = m_cfg->property("family").toString();
|
||||
m_large = buildFont(m_cfg->largeNode(), family, m_scale);
|
||||
m_medium = buildFont(m_cfg->mediumNode(), family, m_scale);
|
||||
m_small = buildFont(m_cfg->smallNode(), family, m_scale);
|
||||
} else {
|
||||
m_large = QFont();
|
||||
m_medium = QFont();
|
||||
m_small = QFont();
|
||||
}
|
||||
emit fontsChanged();
|
||||
}
|
||||
|
||||
void FontStyleBase::setScale(qreal scale) {
|
||||
if (qFuzzyCompare(m_scale + 1.0, scale + 1.0)) return;
|
||||
m_scale = scale;
|
||||
rebuild();
|
||||
}
|
||||
|
||||
FontStyle::FontStyle(QObject* parent)
|
||||
: FontStyleBase(parent), m_builders(new FontBuilders(this, this)) {}
|
||||
|
||||
FontBuilders* FontStyle::builders() const {
|
||||
return m_builders;
|
||||
}
|
||||
|
||||
IconFontStyle::IconFontStyle(QObject* parent)
|
||||
: FontStyleBase(parent), m_builders(new IconFontBuilders(this, this)) {}
|
||||
|
||||
FontBuilder IconFontStyle::size(int pointSize) {
|
||||
return FontBuilder(m_small).size(pointSize);
|
||||
}
|
||||
|
||||
FontBuilder IconFontStyle::pixelSize(int pixelSize) {
|
||||
return FontBuilder(m_small).pixelSize(pixelSize);
|
||||
}
|
||||
|
||||
void IconFontStyle::bind(FontStyleNode* cfg) {
|
||||
if (m_cfg == cfg) return;
|
||||
|
||||
if (m_cfg) disconnect(m_cfg->extraLargeNode(), nullptr, this, nullptr);
|
||||
|
||||
FontStyleBase::bind(cfg);
|
||||
|
||||
if (cfg)
|
||||
connect(
|
||||
cfg->extraLargeNode(),
|
||||
&ConfigNode::propertiesChanged,
|
||||
this,
|
||||
&IconFontStyle::rebuild);
|
||||
}
|
||||
|
||||
QFont IconFontStyle::extraLarge() const {
|
||||
return m_extraLarge;
|
||||
}
|
||||
|
||||
IconFontBuilders* IconFontStyle::builders() const {
|
||||
return m_builders;
|
||||
}
|
||||
|
||||
void IconFontStyle::rebuild() {
|
||||
if (m_cfg) {
|
||||
const auto family = m_cfg->property("family").toString();
|
||||
m_extraLarge = buildFont(m_cfg->extraLargeNode(), family, m_scale);
|
||||
} else {
|
||||
m_extraLarge = QFont();
|
||||
}
|
||||
FontStyleBase::rebuild();
|
||||
}
|
||||
|
||||
FontBuilders::FontBuilders(const FontStyleBase* style, QObject* parent)
|
||||
: QObject(parent), m_style(style) {
|
||||
connect(
|
||||
style,
|
||||
&FontStyleBase::fontsChanged,
|
||||
this,
|
||||
&FontBuilders::buildersChanged);
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::large() const {
|
||||
return FontBuilder(m_style->large());
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::medium() const {
|
||||
return FontBuilder(m_style->medium());
|
||||
}
|
||||
|
||||
FontBuilder FontBuilders::small() const {
|
||||
return FontBuilder(m_style->small());
|
||||
}
|
||||
|
||||
IconFontBuilders::IconFontBuilders(const IconFontStyle* style, QObject* parent)
|
||||
: FontBuilders(style, parent) {}
|
||||
|
||||
FontBuilder IconFontBuilders::extraLarge() const {
|
||||
return FontBuilder(
|
||||
static_cast<const IconFontStyle*>(m_style)->extraLarge());
|
||||
}
|
||||
|
||||
FontTokens::FontTokens(QObject* parent)
|
||||
: ConfigObject(parent)
|
||||
, m_size(new FontSizeTokens(this))
|
||||
, m_headline(new FontStyle(this))
|
||||
, m_title(new FontStyle(this))
|
||||
, m_body(new FontStyle(this))
|
||||
, m_label(new FontStyle(this))
|
||||
, m_mono(new FontStyle(this))
|
||||
, m_icon(new IconFontStyle(this)) {
|
||||
if (!Config::instance()) new Config();
|
||||
bindFont(Config::instance()->appearance()->font());
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::headline() const {
|
||||
return m_headline;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::title() const {
|
||||
return m_title;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::body() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::label() const {
|
||||
return m_label;
|
||||
}
|
||||
|
||||
FontStyle* FontTokens::mono() const {
|
||||
return m_mono;
|
||||
}
|
||||
|
||||
IconFontStyle* FontTokens::icon() const {
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
FontBuilder FontTokens::clock() const {
|
||||
return FontBuilder(m_clock);
|
||||
}
|
||||
|
||||
QString FontTokens::workspaces() const {
|
||||
return m_font ? m_font->workspaces() : QString();
|
||||
}
|
||||
|
||||
void FontTokens::bindFont(AppearanceFont* font) {
|
||||
if (m_font == font) return;
|
||||
|
||||
if (m_font) disconnect(m_font, nullptr, this, nullptr);
|
||||
|
||||
m_font = font;
|
||||
|
||||
if (font) {
|
||||
rebuildScale();
|
||||
m_headline->bind(font->headline());
|
||||
m_title->bind(font->title());
|
||||
m_body->bind(font->body());
|
||||
m_label->bind(font->label());
|
||||
m_mono->bind(font->mono());
|
||||
m_icon->bind(font->icon());
|
||||
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::clockChanged,
|
||||
this,
|
||||
&FontTokens::rebuildClock);
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::scaleChanged,
|
||||
this,
|
||||
&FontTokens::rebuildScale);
|
||||
connect(
|
||||
font,
|
||||
&AppearanceFont::workspacesChanged,
|
||||
this,
|
||||
&FontTokens::workspacesChanged);
|
||||
} else {
|
||||
rebuildScale();
|
||||
m_headline->bind(nullptr);
|
||||
m_title->bind(nullptr);
|
||||
m_body->bind(nullptr);
|
||||
m_label->bind(nullptr);
|
||||
m_mono->bind(nullptr);
|
||||
m_icon->bind(nullptr);
|
||||
}
|
||||
|
||||
rebuildClock();
|
||||
emit workspacesChanged();
|
||||
}
|
||||
|
||||
void FontTokens::rebuildScale() {
|
||||
const qreal s = m_font ? m_font->scale() : 1;
|
||||
m_headline->setScale(s);
|
||||
m_title->setScale(s);
|
||||
m_body->setScale(s);
|
||||
m_label->setScale(s);
|
||||
m_mono->setScale(s);
|
||||
m_icon->setScale(s);
|
||||
}
|
||||
|
||||
void FontTokens::rebuildClock() {
|
||||
QFont f;
|
||||
if (m_font) f.setFamily(m_font->clock());
|
||||
m_clock = f;
|
||||
emit clockChanged();
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,200 @@
|
||||
#pragma once
|
||||
|
||||
#include "configobject.hpp"
|
||||
#include "fontbuilder.hpp"
|
||||
|
||||
#include <qfont.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qvariantmap.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class AppearanceFont;
|
||||
class FontBuilders;
|
||||
class FontStyleBase;
|
||||
class FontSizeNode;
|
||||
class FontStyleNode;
|
||||
class IconFontStyle;
|
||||
|
||||
class FontSizeTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, small, 11)
|
||||
CFG_PROPERTY(int, smaller, 12)
|
||||
CFG_PROPERTY(int, normal, 13)
|
||||
CFG_PROPERTY(int, larger, 15)
|
||||
CFG_PROPERTY(int, large, 18)
|
||||
CFG_PROPERTY(int, extraLarge, 28)
|
||||
|
||||
public:
|
||||
explicit FontSizeTokens(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontBuilders : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(
|
||||
ZShell::config::FontBuilder large READ large NOTIFY buildersChanged
|
||||
FINAL)
|
||||
Q_PROPERTY(
|
||||
ZShell::config::FontBuilder medium READ medium NOTIFY buildersChanged
|
||||
FINAL)
|
||||
Q_PROPERTY(
|
||||
ZShell::config::FontBuilder small READ small NOTIFY buildersChanged
|
||||
FINAL)
|
||||
|
||||
public:
|
||||
explicit FontBuilders(const FontStyleBase* style, QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] FontBuilder large() const;
|
||||
[[nodiscard]] FontBuilder medium() const;
|
||||
[[nodiscard]] FontBuilder small() const;
|
||||
|
||||
signals:
|
||||
void buildersChanged();
|
||||
|
||||
protected:
|
||||
const FontStyleBase* m_style;
|
||||
};
|
||||
|
||||
class IconFontBuilders : public FontBuilders {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(
|
||||
ZShell::config::FontBuilder extraLarge READ extraLarge NOTIFY
|
||||
buildersChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit IconFontBuilders(
|
||||
const IconFontStyle* style, QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] FontBuilder extraLarge() const;
|
||||
};
|
||||
|
||||
class FontStyleBase : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QFont large READ large NOTIFY fontsChanged FINAL)
|
||||
Q_PROPERTY(QFont medium READ medium NOTIFY fontsChanged FINAL)
|
||||
Q_PROPERTY(QFont small READ small NOTIFY fontsChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit FontStyleBase(QObject* parent = nullptr);
|
||||
|
||||
virtual void bind(FontStyleNode* cfg);
|
||||
void setScale(qreal scale);
|
||||
|
||||
[[nodiscard]] QFont large() const;
|
||||
[[nodiscard]] QFont medium() const;
|
||||
[[nodiscard]] QFont small() const;
|
||||
|
||||
signals:
|
||||
void fontsChanged();
|
||||
|
||||
protected:
|
||||
virtual void rebuild();
|
||||
|
||||
static QFont buildFont(
|
||||
const FontSizeNode* cfg, const QString& fallbackFamily, qreal scale);
|
||||
|
||||
FontStyleNode* m_cfg = nullptr;
|
||||
qreal m_scale = 1;
|
||||
QFont m_large;
|
||||
QFont m_medium;
|
||||
QFont m_small;
|
||||
};
|
||||
|
||||
class FontStyle : public FontStyleBase {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(FontBuilders* builders READ builders CONSTANT FINAL)
|
||||
|
||||
public:
|
||||
explicit FontStyle(QObject* parent = nullptr);
|
||||
|
||||
[[nodiscard]] FontBuilders* builders() const;
|
||||
|
||||
private:
|
||||
FontBuilders* m_builders;
|
||||
};
|
||||
|
||||
class IconFontStyle : public FontStyleBase {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(QFont extraLarge READ extraLarge NOTIFY fontsChanged FINAL)
|
||||
Q_PROPERTY(IconFontBuilders* builders READ builders CONSTANT FINAL)
|
||||
|
||||
public:
|
||||
explicit IconFontStyle(QObject* parent = nullptr);
|
||||
|
||||
Q_INVOKABLE FontBuilder size(int pointSize);
|
||||
Q_INVOKABLE FontBuilder pixelSize(int pixelSize);
|
||||
|
||||
void bind(FontStyleNode* cfg) override;
|
||||
|
||||
[[nodiscard]] QFont extraLarge() const;
|
||||
[[nodiscard]] IconFontBuilders* builders() const;
|
||||
|
||||
protected:
|
||||
void rebuild() override;
|
||||
|
||||
private:
|
||||
QFont m_extraLarge;
|
||||
IconFontBuilders* m_builders;
|
||||
};
|
||||
|
||||
class FontTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(FontSizeTokens, size)
|
||||
|
||||
Q_PROPERTY(FontStyle* headline READ headline CONSTANT FINAL)
|
||||
Q_PROPERTY(FontStyle* title READ title CONSTANT FINAL)
|
||||
Q_PROPERTY(FontStyle* body READ body CONSTANT FINAL)
|
||||
Q_PROPERTY(FontStyle* label READ label CONSTANT FINAL)
|
||||
Q_PROPERTY(FontStyle* mono READ mono CONSTANT FINAL)
|
||||
Q_PROPERTY(IconFontStyle* icon READ icon CONSTANT FINAL)
|
||||
Q_PROPERTY(
|
||||
ZShell::config::FontBuilder clock READ clock NOTIFY clockChanged FINAL)
|
||||
Q_PROPERTY(QString workspaces READ workspaces NOTIFY workspacesChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit FontTokens(QObject* parent = nullptr);
|
||||
|
||||
void bindFont(AppearanceFont* font);
|
||||
|
||||
[[nodiscard]] FontStyle* headline() const;
|
||||
[[nodiscard]] FontStyle* title() const;
|
||||
[[nodiscard]] FontStyle* body() const;
|
||||
[[nodiscard]] FontStyle* label() const;
|
||||
[[nodiscard]] FontStyle* mono() const;
|
||||
[[nodiscard]] IconFontStyle* icon() const;
|
||||
[[nodiscard]] FontBuilder clock() const;
|
||||
[[nodiscard]] QString workspaces() const;
|
||||
|
||||
signals:
|
||||
void clockChanged();
|
||||
void workspacesChanged();
|
||||
|
||||
private:
|
||||
void rebuildClock();
|
||||
void rebuildScale();
|
||||
|
||||
AppearanceFont* m_font = nullptr;
|
||||
FontStyle* m_headline;
|
||||
FontStyle* m_title;
|
||||
FontStyle* m_body;
|
||||
FontStyle* m_label;
|
||||
FontStyle* m_mono;
|
||||
IconFontStyle* m_icon;
|
||||
QFont m_clock;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "fontbuilder.hpp"
|
||||
|
||||
#include <qloggingcategory.h>
|
||||
|
||||
namespace {
|
||||
|
||||
Q_LOGGING_CATEGORY(lcFontBuilder, "zshell.fontbuilder", QtInfoMsg)
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
FontBuilder::FontBuilder(const QFont& font) : m_font(font) {}
|
||||
|
||||
FontBuilder FontBuilder::family(const QString& family) {
|
||||
m_font.setFamily(family);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::size(int pointSize) {
|
||||
if (pointSize <= 0) pointSize = 1;
|
||||
m_font.setPointSize(pointSize);
|
||||
m_font.setVariableAxis("opsz", static_cast<float>(pointSize));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::pixelSize(int pixelSize) {
|
||||
if (pixelSize <= 0) pixelSize = 1;
|
||||
m_font.setPixelSize(pixelSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::weight(QFont::Weight weight) {
|
||||
m_font.setWeight(weight);
|
||||
m_font.setVariableAxis("wght", static_cast<float>(weight));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::italic(bool on) {
|
||||
m_font.setItalic(on);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::stretch(int stretch) {
|
||||
m_font.setStretch(stretch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::letterSpacing(qreal spacing, bool absolute) {
|
||||
m_font.setLetterSpacing(
|
||||
absolute ? QFont::AbsoluteSpacing : QFont::PercentageSpacing, spacing);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::capitalisation(QFont::Capitalization cap) {
|
||||
m_font.setCapitalization(cap);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::vaxis(const QString& tag, float value) {
|
||||
if (auto t = QFont::Tag::fromString(tag))
|
||||
m_font.setVariableAxis(*t, value);
|
||||
else
|
||||
qCWarning(lcFontBuilder)
|
||||
<< "Unable to convert tag" << tag << "to QFont::Tag";
|
||||
return *this;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::vaxes(const QVariantMap& axes) {
|
||||
for (auto it = axes.constBegin(); it != axes.constEnd(); ++it) {
|
||||
if (it.value().canConvert<float>()) {
|
||||
if (auto tag = QFont::Tag::fromString(it.key()))
|
||||
m_font.setVariableAxis(*tag, it.value().toFloat());
|
||||
else
|
||||
qCWarning(lcFontBuilder)
|
||||
<< "Unable to convert tag" << it.key() << "to QFont::Tag";
|
||||
} else {
|
||||
qCWarning(lcFontBuilder)
|
||||
<< "Unable to convert value" << it.value() << "to float";
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QFont FontBuilder::build() const {
|
||||
return m_font;
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::fill(float value) {
|
||||
return vaxis(QStringLiteral("FILL"), value);
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::grade(float value) {
|
||||
return vaxis(QStringLiteral("GRAD"), value);
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::width(float value) {
|
||||
return vaxis(QStringLiteral("wdth"), value);
|
||||
}
|
||||
|
||||
FontBuilder FontBuilder::scale(qreal factor) {
|
||||
return size(static_cast<int>(m_font.pointSize() * factor));
|
||||
}
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <qfont.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class FontBuilder {
|
||||
Q_GADGET
|
||||
QML_ANONYMOUS
|
||||
|
||||
public:
|
||||
FontBuilder() = default;
|
||||
explicit FontBuilder(const QFont& font);
|
||||
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder family(const QString& family);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder size(int pointSize);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder pixelSize(int pixelSize);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder weight(QFont::Weight weight);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder italic(bool on = true);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder stretch(int stretch);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder
|
||||
letterSpacing(qreal spacing, bool absolute = true);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder
|
||||
capitalisation(QFont::Capitalization cap);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder vaxis(const QString& tag, float value);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder vaxes(const QVariantMap& axes);
|
||||
[[nodiscard]] Q_INVOKABLE QFont build() const;
|
||||
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder fill(float value);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder grade(float value);
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder width(float value);
|
||||
|
||||
[[nodiscard]] Q_INVOKABLE FontBuilder scale(qreal factor);
|
||||
|
||||
private:
|
||||
QFont m_font;
|
||||
};
|
||||
|
||||
} // namespace ZShell::config
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include "configobject.hpp"
|
||||
#include "anim.hpp"
|
||||
#include "appearance.hpp"
|
||||
#include "config.hpp"
|
||||
#include "font.hpp"
|
||||
|
||||
#include <QVariantList>
|
||||
#include <limits>
|
||||
@@ -13,89 +16,6 @@
|
||||
|
||||
namespace ZShell::config {
|
||||
|
||||
class AppearanceRounding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(qreal, extraSmall, 4)
|
||||
CFG_PROPERTY(qreal, full, std::numeric_limits<int>::max())
|
||||
CFG_PROPERTY(qreal, large, 16)
|
||||
CFG_PROPERTY(qreal, largeIncreased, 20)
|
||||
CFG_PROPERTY(qreal, extraLarge, 28)
|
||||
CFG_PROPERTY(qreal, extraLargeIncreased, 32)
|
||||
CFG_PROPERTY(qreal, extraExtraLarge, 48)
|
||||
CFG_PROPERTY(qreal, medium, 12)
|
||||
CFG_PROPERTY(qreal, scale, 1)
|
||||
CFG_PROPERTY(qreal, small, 8)
|
||||
|
||||
public:
|
||||
explicit AppearanceRounding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AppearancePadding : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, extraSmall, 4)
|
||||
CFG_PROPERTY(int, smaller, 5)
|
||||
CFG_PROPERTY(int, small, 8)
|
||||
CFG_PROPERTY(int, medium, 12)
|
||||
CFG_PROPERTY(int, large, 16)
|
||||
CFG_PROPERTY(int, largeIncreased, 20)
|
||||
CFG_PROPERTY(int, extraLarge, 28)
|
||||
CFG_PROPERTY(int, extraLargeIncreased, 32)
|
||||
CFG_PROPERTY(int, extraExtraLarge, 48)
|
||||
|
||||
public:
|
||||
explicit AppearancePadding(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AppearanceSpacing : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, extraSmall, 4)
|
||||
CFG_PROPERTY(int, small, 8)
|
||||
CFG_PROPERTY(int, medium, 12)
|
||||
CFG_PROPERTY(int, large, 16)
|
||||
CFG_PROPERTY(int, largeIncreased, 20)
|
||||
CFG_PROPERTY(int, extraLarge, 28)
|
||||
CFG_PROPERTY(int, extraLargeIncreased, 32)
|
||||
CFG_PROPERTY(int, extraExtraLarge, 48)
|
||||
|
||||
public:
|
||||
explicit AppearanceSpacing(QObject* parent = nullptr)
|
||||
: ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class FontSizeTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, small, 11)
|
||||
CFG_PROPERTY(int, smaller, 12)
|
||||
CFG_PROPERTY(int, normal, 13)
|
||||
CFG_PROPERTY(int, larger, 15)
|
||||
CFG_PROPERTY(int, large, 18)
|
||||
CFG_PROPERTY(int, extraLarge, 28)
|
||||
|
||||
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
|
||||
@@ -142,31 +62,11 @@ class AnimCurves : public ConfigObject {
|
||||
, m_expressiveSlowEffects({0.34, 0.88, 0.34, 1, 1, 1}) {}
|
||||
};
|
||||
|
||||
class AnimDurations : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CFG_PROPERTY(int, small, 200)
|
||||
CFG_PROPERTY(int, scale, 1)
|
||||
CFG_PROPERTY(int, normal, 400)
|
||||
CFG_PROPERTY(int, large, 600)
|
||||
CFG_PROPERTY(int, extraLarge, 1000)
|
||||
CFG_PROPERTY(int, expressiveFastSpatial, 350)
|
||||
CFG_PROPERTY(int, expressiveDefaultSpatial, 500)
|
||||
CFG_PROPERTY(int, expressiveSlowSpatial, 650)
|
||||
CFG_PROPERTY(int, expressiveFastEffects, 150)
|
||||
CFG_PROPERTY(int, expressiveDefaultEffects, 200)
|
||||
CFG_PROPERTY(int, expressiveSlowEffects, 300)
|
||||
|
||||
public:
|
||||
explicit AnimDurations(QObject* parent = nullptr) : ConfigObject(parent) {}
|
||||
};
|
||||
|
||||
class AnimTokens : public ConfigObject {
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
CONFIG_SUBOBJECT(AnimDurations, durations)
|
||||
Q_PROPERTY(ZShell::config::AnimDurations* durations READ durations CONSTANT)
|
||||
|
||||
Q_PROPERTY(QEasingCurve emphasized READ emphasized NOTIFY curvesChanged)
|
||||
Q_PROPERTY(
|
||||
@@ -201,7 +101,6 @@ class AnimTokens : public ConfigObject {
|
||||
explicit AnimTokens(QObject* parent = nullptr)
|
||||
: ConfigObject(parent)
|
||||
, m_curves(new AnimCurves(this))
|
||||
, m_durations(new AnimDurations(this))
|
||||
, m_easing(new AnimEasing(this)) {
|
||||
connect(
|
||||
m_easing,
|
||||
@@ -211,6 +110,10 @@ class AnimTokens : public ConfigObject {
|
||||
m_easing->bindCurves(m_curves);
|
||||
}
|
||||
|
||||
[[nodiscard]] AnimDurations* durations() const {
|
||||
return Config::instance()->appearance()->anim()->durations();
|
||||
}
|
||||
|
||||
[[nodiscard]] QEasingCurve emphasized() const {
|
||||
return m_easing->emphasized();
|
||||
}
|
||||
@@ -269,9 +172,10 @@ class Tokens : public ConfigObject {
|
||||
QML_ELEMENT
|
||||
QML_SINGLETON
|
||||
|
||||
CONFIG_SUBOBJECT(AppearanceRounding, rounding)
|
||||
CONFIG_SUBOBJECT(AppearancePadding, padding)
|
||||
CONFIG_SUBOBJECT(AppearanceSpacing, spacing)
|
||||
Q_PROPERTY(
|
||||
ZShell::config::AppearanceRounding* rounding READ rounding CONSTANT)
|
||||
Q_PROPERTY(ZShell::config::AppearancePadding* padding READ padding CONSTANT)
|
||||
Q_PROPERTY(ZShell::config::AppearanceSpacing* spacing READ spacing CONSTANT)
|
||||
CONFIG_SUBOBJECT(FontTokens, font)
|
||||
CONFIG_SUBOBJECT(AnimTokens, anim)
|
||||
CONFIG_SUBOBJECT(BarTokens, bar)
|
||||
@@ -279,12 +183,21 @@ class Tokens : public ConfigObject {
|
||||
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))
|
||||
, m_bar(new BarTokens(this)) {}
|
||||
, m_bar(new BarTokens(this)) {
|
||||
if (!Config::instance()) new Config();
|
||||
}
|
||||
|
||||
[[nodiscard]] AppearanceRounding* rounding() const {
|
||||
return Config::instance()->appearance()->rounding();
|
||||
}
|
||||
[[nodiscard]] AppearancePadding* padding() const {
|
||||
return Config::instance()->appearance()->padding();
|
||||
}
|
||||
[[nodiscard]] AppearanceSpacing* spacing() const {
|
||||
return Config::instance()->appearance()->spacing();
|
||||
}
|
||||
|
||||
static Tokens* create(QQmlEngine*, QJSEngine*) { return new Tokens(); }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user