Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorEasing.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 fuddlesworth
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
7#include <PhosphorAnimation/phosphoranimation_export.h>
8
9#include <QtCore/QObject>
10#include <QtCore/QString>
11#include <QtCore/QtGlobal>
12#include <QtQml/qqmlregistration.h>
13
14#include <cmath>
15
16namespace PhosphorAnimation {
17
37class PHOSPHORANIMATION_EXPORT PhosphorEasing
38{
39 Q_GADGET
40 QML_VALUE_TYPE(phosphorEasing)
41 QML_STRUCTURED_VALUE
42
43 Q_PROPERTY(Type type READ type WRITE setType)
44 Q_PROPERTY(qreal x1 READ x1 WRITE setX1)
45 Q_PROPERTY(qreal y1 READ y1 WRITE setY1)
46 Q_PROPERTY(qreal x2 READ x2 WRITE setX2)
47 Q_PROPERTY(qreal y2 READ y2 WRITE setY2)
48 Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude)
49 Q_PROPERTY(qreal period READ period WRITE setPeriod)
50 Q_PROPERTY(int bounces READ bounces WRITE setBounces)
51
52public:
53 // Parallel to `PhosphorAnimation::Easing::Type` so QML enum references
54 // work without the caller having to know about the nested C++ enum.
55 // Integer values kept identical for `static_cast` round-trip.
56 enum class Type : int {
57 CubicBezier = int(Easing::Type::CubicBezier),
58 ElasticIn = int(Easing::Type::ElasticIn),
59 ElasticOut = int(Easing::Type::ElasticOut),
60 ElasticInOut = int(Easing::Type::ElasticInOut),
61 BounceIn = int(Easing::Type::BounceIn),
62 BounceOut = int(Easing::Type::BounceOut),
63 BounceInOut = int(Easing::Type::BounceInOut),
64 };
65 Q_ENUM(Type)
66
67 PhosphorEasing() = default;
70 explicit PhosphorEasing(const Easing& value)
71 : m_value(value)
72 {
73 }
74
80 const Easing& value() const
81 {
82 return m_value;
83 }
84
85 // ─── Property delegates ───
86 //
87 // Setters mirror the bounds enforced by `Easing::fromString`'s
88 // qBound clamps: x ∈ [0, 1], y ∈ [-1, 2], amplitude ∈ [0.5, 3],
89 // period ∈ [0.1, 1], bounces ∈ [1, 8]. NaN/inf are silently
90 // dropped (the previous value is preserved). Direct field writes
91 // would otherwise let a settings UI sneak pathological values past
92 // the parse-path clamp.
93
94 Type type() const
95 {
96 return static_cast<Type>(static_cast<int>(m_value.type));
97 }
98 void setType(Type t)
99 {
100 m_value.type = static_cast<Easing::Type>(static_cast<int>(t));
101 }
102
103 qreal x1() const
104 {
105 return m_value.x1;
106 }
107 void setX1(qreal v)
108 {
109 if (!std::isfinite(v)) {
110 return;
111 }
112 m_value.x1 = qBound(0.0, v, 1.0);
113 }
114 qreal y1() const
115 {
116 return m_value.y1;
117 }
118 void setY1(qreal v)
119 {
120 if (!std::isfinite(v)) {
121 return;
122 }
123 m_value.y1 = qBound(-1.0, v, 2.0);
124 }
125 qreal x2() const
126 {
127 return m_value.x2;
128 }
129 void setX2(qreal v)
130 {
131 if (!std::isfinite(v)) {
132 return;
133 }
134 m_value.x2 = qBound(0.0, v, 1.0);
135 }
136 qreal y2() const
137 {
138 return m_value.y2;
139 }
140 void setY2(qreal v)
141 {
142 if (!std::isfinite(v)) {
143 return;
144 }
145 m_value.y2 = qBound(-1.0, v, 2.0);
146 }
147
148 qreal amplitude() const
149 {
150 return m_value.amplitude;
151 }
152 void setAmplitude(qreal v)
153 {
154 if (!std::isfinite(v)) {
155 return;
156 }
157 m_value.amplitude = qBound(0.5, v, 3.0);
158 }
159 qreal period() const
160 {
161 return m_value.period;
162 }
163 void setPeriod(qreal v)
164 {
165 if (!std::isfinite(v)) {
166 return;
167 }
168 m_value.period = qBound(0.1, v, 1.0);
169 }
170 int bounces() const
171 {
172 return m_value.bounces;
173 }
174 void setBounces(int v)
175 {
176 m_value.bounces = qBound(1, v, 8);
177 }
178
179 // ─── Serialization ───
180
182 Q_INVOKABLE QString toString() const
183 {
184 return m_value.toString();
185 }
186
190 Q_INVOKABLE static PhosphorEasing fromString(const QString& str)
191 {
192 return PhosphorEasing(Easing::fromString(str));
193 }
194
195 // ─── Equality ───
196
197 bool operator==(const PhosphorEasing& other) const
198 {
199 return m_value == other.m_value;
200 }
201 bool operator!=(const PhosphorEasing& other) const
202 {
203 return !(*this == other);
204 }
205
206private:
207 Easing m_value;
208};
209
210} // namespace PhosphorAnimation
211
212Q_DECLARE_METATYPE(PhosphorAnimation::PhosphorEasing)
Parametric easing curve: cubic bezier, elastic, or bounce.
Definition Easing.h:18
Type
Definition Easing.h:20
QML value-type wrapper around PhosphorAnimation::Easing.
Definition PhosphorEasing.h:38
QString toString() const
Canonical wire format from PhosphorAnimation::Easing::toString.
Definition PhosphorEasing.h:182
Type
Definition PhosphorEasing.h:56
void setX1(qreal v)
Definition PhosphorEasing.h:107
void setType(Type t)
Definition PhosphorEasing.h:98
qreal amplitude() const
Definition PhosphorEasing.h:148
bool operator==(const PhosphorEasing &other) const
Definition PhosphorEasing.h:197
int bounces() const
Definition PhosphorEasing.h:170
bool operator!=(const PhosphorEasing &other) const
Definition PhosphorEasing.h:201
void setBounces(int v)
Definition PhosphorEasing.h:174
qreal y2() const
Definition PhosphorEasing.h:136
qreal x1() const
Definition PhosphorEasing.h:103
qreal y1() const
Definition PhosphorEasing.h:114
static PhosphorEasing fromString(const QString &str)
Parse the same wire format.
Definition PhosphorEasing.h:190
const Easing & value() const
Read-only access to the underlying value.
Definition PhosphorEasing.h:80
qreal x2() const
Definition PhosphorEasing.h:125
void setY2(qreal v)
Definition PhosphorEasing.h:140
void setX2(qreal v)
Definition PhosphorEasing.h:129
void setY1(qreal v)
Definition PhosphorEasing.h:118
void setAmplitude(qreal v)
Definition PhosphorEasing.h:152
qreal period() const
Definition PhosphorEasing.h:159
void setPeriod(qreal v)
Definition PhosphorEasing.h:163
Type type() const
Definition PhosphorEasing.h:94
Definition AnimatedValue.h:31