feat: add proper anim tokens to Tokens
This commit is contained in:
parent
b5dcd07ab8
commit
180120801a
5 changed files with 177 additions and 19 deletions
|
|
@ -6,6 +6,7 @@ qml_module(caelestia-config
|
|||
configscope.cpp
|
||||
appearanceconfig.cpp
|
||||
tokens.cpp
|
||||
anim.cpp
|
||||
monitorconfigmanager.cpp
|
||||
backgroundconfig.hpp
|
||||
barconfig.hpp
|
||||
|
|
|
|||
62
plugin/src/Caelestia/Config/anim.cpp
Normal file
62
plugin/src/Caelestia/Config/anim.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "anim.hpp"
|
||||
#include "appearanceconfig.hpp"
|
||||
#include "tokens.hpp"
|
||||
|
||||
#include <qpoint.h>
|
||||
|
||||
namespace caelestia::config {
|
||||
|
||||
AnimTokens::AnimTokens(QObject* parent)
|
||||
: QObject(parent) {}
|
||||
|
||||
QEasingCurve AnimTokens::buildCurve(const QList<qreal>& points) {
|
||||
QEasingCurve curve(QEasingCurve::BezierSpline);
|
||||
|
||||
// Points come in pairs of (x, y) forming cubic bezier segments.
|
||||
// Each segment needs 3 control points: c1, c2, endPoint.
|
||||
// So 6 values per segment: c1x, c1y, c2x, c2y, endX, endY.
|
||||
for (int i = 0; i + 5 < points.size(); i += 6) {
|
||||
QPointF c1(points[i], points[i + 1]);
|
||||
QPointF c2(points[i + 2], points[i + 3]);
|
||||
QPointF end(points[i + 4], points[i + 5]);
|
||||
curve.addCubicBezierSegment(c1, c2, end);
|
||||
}
|
||||
|
||||
return curve;
|
||||
}
|
||||
|
||||
void AnimTokens::rebuildCurves() {
|
||||
if (!m_curves)
|
||||
return;
|
||||
|
||||
m_emphasized = buildCurve(m_curves->emphasized());
|
||||
m_emphasizedAccel = buildCurve(m_curves->emphasizedAccel());
|
||||
m_emphasizedDecel = buildCurve(m_curves->emphasizedDecel());
|
||||
m_standard = buildCurve(m_curves->standard());
|
||||
m_standardAccel = buildCurve(m_curves->standardAccel());
|
||||
m_standardDecel = buildCurve(m_curves->standardDecel());
|
||||
m_expressiveFastSpatial = buildCurve(m_curves->expressiveFastSpatial());
|
||||
m_expressiveDefaultSpatial = buildCurve(m_curves->expressiveDefaultSpatial());
|
||||
m_expressiveSlowSpatial = buildCurve(m_curves->expressiveSlowSpatial());
|
||||
|
||||
emit curvesChanged();
|
||||
}
|
||||
|
||||
void AnimTokens::bindCurves(AnimCurves* curves) {
|
||||
m_curves = curves;
|
||||
|
||||
// Rebuild when any curve control points change
|
||||
connect(curves, &AnimCurves::propertiesChanged, this, &AnimTokens::rebuildCurves);
|
||||
|
||||
rebuildCurves();
|
||||
}
|
||||
|
||||
void AnimTokens::bindDurations(AnimDurations* durations) {
|
||||
if (m_durations == durations)
|
||||
return;
|
||||
|
||||
m_durations = durations;
|
||||
emit durationsChanged();
|
||||
}
|
||||
|
||||
} // namespace caelestia::config
|
||||
78
plugin/src/Caelestia/Config/anim.hpp
Normal file
78
plugin/src/Caelestia/Config/anim.hpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#pragma once
|
||||
|
||||
#include <qeasingcurve.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
|
||||
namespace caelestia::config {
|
||||
|
||||
class AnimCurves;
|
||||
class AnimDurations;
|
||||
class ConfigScope;
|
||||
|
||||
class AnimTokens : public QObject {
|
||||
Q_OBJECT
|
||||
Q_MOC_INCLUDE("appearanceconfig.hpp")
|
||||
QML_ANONYMOUS
|
||||
|
||||
Q_PROPERTY(QEasingCurve emphasized READ emphasized NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve emphasizedAccel READ emphasizedAccel NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve emphasizedDecel READ emphasizedDecel NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve standard READ standard NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve standardAccel READ standardAccel NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve standardDecel READ standardDecel NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve expressiveFastSpatial READ expressiveFastSpatial NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve expressiveDefaultSpatial READ expressiveDefaultSpatial NOTIFY curvesChanged)
|
||||
Q_PROPERTY(QEasingCurve expressiveSlowSpatial READ expressiveSlowSpatial NOTIFY curvesChanged)
|
||||
|
||||
Q_PROPERTY(caelestia::config::AnimDurations* durations READ durations NOTIFY durationsChanged)
|
||||
|
||||
public:
|
||||
explicit AnimTokens(QObject* parent = nullptr);
|
||||
|
||||
void bindCurves(AnimCurves* curves);
|
||||
void bindDurations(AnimDurations* durations);
|
||||
|
||||
[[nodiscard]] QEasingCurve emphasized() const { return m_emphasized; }
|
||||
|
||||
[[nodiscard]] QEasingCurve emphasizedAccel() const { return m_emphasizedAccel; }
|
||||
|
||||
[[nodiscard]] QEasingCurve emphasizedDecel() const { return m_emphasizedDecel; }
|
||||
|
||||
[[nodiscard]] QEasingCurve standard() const { return m_standard; }
|
||||
|
||||
[[nodiscard]] QEasingCurve standardAccel() const { return m_standardAccel; }
|
||||
|
||||
[[nodiscard]] QEasingCurve standardDecel() const { return m_standardDecel; }
|
||||
|
||||
[[nodiscard]] QEasingCurve expressiveFastSpatial() const { return m_expressiveFastSpatial; }
|
||||
|
||||
[[nodiscard]] QEasingCurve expressiveDefaultSpatial() const { return m_expressiveDefaultSpatial; }
|
||||
|
||||
[[nodiscard]] QEasingCurve expressiveSlowSpatial() const { return m_expressiveSlowSpatial; }
|
||||
|
||||
[[nodiscard]] AnimDurations* durations() const { return m_durations; }
|
||||
|
||||
signals:
|
||||
void curvesChanged();
|
||||
void durationsChanged();
|
||||
|
||||
private:
|
||||
void rebuildCurves();
|
||||
static QEasingCurve buildCurve(const QList<qreal>& points);
|
||||
|
||||
AnimCurves* m_curves = nullptr;
|
||||
AnimDurations* m_durations = nullptr;
|
||||
|
||||
QEasingCurve m_emphasized;
|
||||
QEasingCurve m_emphasizedAccel;
|
||||
QEasingCurve m_emphasizedDecel;
|
||||
QEasingCurve m_standard;
|
||||
QEasingCurve m_standardAccel;
|
||||
QEasingCurve m_standardDecel;
|
||||
QEasingCurve m_expressiveFastSpatial;
|
||||
QEasingCurve m_expressiveDefaultSpatial;
|
||||
QEasingCurve m_expressiveSlowSpatial;
|
||||
};
|
||||
|
||||
} // namespace caelestia::config
|
||||
|
|
@ -62,18 +62,6 @@ TokenConfig* TokenConfig::create(QQmlEngine* engine, QJSEngine*) {
|
|||
|
||||
// Tokens (attached type)
|
||||
|
||||
Tokens::Tokens(ConfigScope* scope, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_scope(scope) {
|
||||
connectScope();
|
||||
}
|
||||
|
||||
void Tokens::connectScope() {
|
||||
if (!m_scope)
|
||||
return;
|
||||
connect(m_scope, &ConfigScope::configChanged, this, &Tokens::sourceChanged);
|
||||
}
|
||||
|
||||
// Resolve appearance from per-monitor GlobalConfig overlay or global GlobalConfig
|
||||
static const AppearanceConfig* resolveAppearance(ConfigScope* scope) {
|
||||
if (scope && scope->config())
|
||||
|
|
@ -82,6 +70,35 @@ static const AppearanceConfig* resolveAppearance(ConfigScope* scope) {
|
|||
return global ? global->appearance() : nullptr;
|
||||
}
|
||||
|
||||
Tokens::Tokens(ConfigScope* scope, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_scope(scope)
|
||||
, m_anim(new AnimTokens(this)) {
|
||||
connectScope();
|
||||
bindAnim();
|
||||
}
|
||||
|
||||
void Tokens::connectScope() {
|
||||
if (!m_scope)
|
||||
return;
|
||||
connect(m_scope, &ConfigScope::configChanged, this, &Tokens::sourceChanged);
|
||||
connect(m_scope, &ConfigScope::configChanged, this, &Tokens::bindAnim);
|
||||
}
|
||||
|
||||
void Tokens::bindAnim() {
|
||||
auto* appearance = resolveAppearance(m_scope);
|
||||
if (!appearance)
|
||||
return;
|
||||
|
||||
// Bind durations from resolved GlobalConfig appearance
|
||||
m_anim->bindDurations(appearance->anim()->durations());
|
||||
|
||||
// Bind curves from TokenConfig
|
||||
auto* tokens = TokenConfig::instance();
|
||||
if (tokens)
|
||||
m_anim->bindCurves(tokens->appearance()->curves());
|
||||
}
|
||||
|
||||
const AppearanceRounding* Tokens::rounding() const {
|
||||
auto* a = resolveAppearance(m_scope);
|
||||
return a ? a->rounding() : nullptr;
|
||||
|
|
@ -102,11 +119,6 @@ const AppearanceFont* Tokens::font() const {
|
|||
return a ? a->font() : nullptr;
|
||||
}
|
||||
|
||||
const AppearanceAnim* Tokens::anim() const {
|
||||
auto* a = resolveAppearance(m_scope);
|
||||
return a ? a->anim() : nullptr;
|
||||
}
|
||||
|
||||
const AppearanceTransparency* Tokens::transparency() const {
|
||||
auto* a = resolveAppearance(m_scope);
|
||||
return a ? a->transparency() : nullptr;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "anim.hpp"
|
||||
#include "appearanceconfig.hpp"
|
||||
#include "configobject.hpp"
|
||||
|
||||
|
|
@ -356,9 +357,9 @@ class Tokens : public QObject {
|
|||
Q_PROPERTY(const caelestia::config::AppearanceSpacing* spacing READ spacing NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::AppearancePadding* padding READ padding NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::AppearanceFont* font READ font NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::AppearanceAnim* anim READ anim NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::AppearanceTransparency* transparency READ transparency NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::SizeTokens* sizes READ sizes NOTIFY sourceChanged)
|
||||
Q_PROPERTY(const caelestia::config::AnimTokens* anim READ anim NOTIFY sourceChanged)
|
||||
|
||||
public:
|
||||
explicit Tokens(ConfigScope* scope, QObject* parent = nullptr);
|
||||
|
|
@ -367,10 +368,12 @@ public:
|
|||
[[nodiscard]] const AppearanceSpacing* spacing() const;
|
||||
[[nodiscard]] const AppearancePadding* padding() const;
|
||||
[[nodiscard]] const AppearanceFont* font() const;
|
||||
[[nodiscard]] const AppearanceAnim* anim() const;
|
||||
[[nodiscard]] const AppearanceTransparency* transparency() const;
|
||||
|
||||
[[nodiscard]] const SizeTokens* sizes() const;
|
||||
|
||||
[[nodiscard]] const AnimTokens* anim() const { return m_anim; }
|
||||
|
||||
static Tokens* qmlAttachedProperties(QObject* object);
|
||||
|
||||
signals:
|
||||
|
|
@ -378,8 +381,10 @@ signals:
|
|||
|
||||
private:
|
||||
void connectScope();
|
||||
void bindAnim();
|
||||
|
||||
ConfigScope* m_scope;
|
||||
AnimTokens* m_anim = nullptr;
|
||||
};
|
||||
|
||||
} // namespace caelestia::config
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue