diff --git a/docs b/docs index b130193..a036d37 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit b13019316035a0f57bfaa470ae702b65b8f6bc01 +Subproject commit a036d378c03366009ad4a8dd64e3622d9dfe97af diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index dd47085..2cfae69 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -21,6 +21,7 @@ qt_add_library(quickshell-core STATIC qsintercept.cpp incubator.cpp lazyloader.cpp + easingcurve.cpp ) set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}") diff --git a/src/core/easingcurve.cpp b/src/core/easingcurve.cpp new file mode 100644 index 0000000..a758bd3 --- /dev/null +++ b/src/core/easingcurve.cpp @@ -0,0 +1,33 @@ +#include "easingcurve.hpp" +#include + +#include +#include +#include +#include +#include + +qreal EasingCurve::valueAt(qreal x) const { return this->mCurve.valueForProgress(x); } + +qreal EasingCurve::interpolate(qreal x, qreal a, qreal b) const { + return a + (b - a) * this->valueAt(x); +} + +QPointF EasingCurve::interpolate(qreal x, const QPointF& a, const QPointF& b) const { + return QPointF(this->interpolate(x, a.x(), b.x()), this->interpolate(x, a.y(), b.y())); +} + +QRectF EasingCurve::interpolate(qreal x, const QRectF& a, const QRectF& b) const { + return QRectF( + this->interpolate(x, a.topLeft(), b.topLeft()), + this->interpolate(x, a.bottomRight(), b.bottomRight()) + ); +} + +QEasingCurve EasingCurve::curve() const { return this->mCurve; } + +void EasingCurve::setCurve(QEasingCurve curve) { + if (this->mCurve == curve) return; + this->mCurve = std::move(curve); + emit this->curveChanged(); +} diff --git a/src/core/easingcurve.hpp b/src/core/easingcurve.hpp new file mode 100644 index 0000000..ef21038 --- /dev/null +++ b/src/core/easingcurve.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +///! Easing curve. +/// Directly accessible easing curve as used in property animations. +class EasingCurve: public QObject { + Q_OBJECT; + /// Easing curve settings. Works exactly the same as + /// [PropertyAnimation.easing](https://doc.qt.io/qt-6/qml-qtquick-propertyanimation.html#easing-prop). + Q_PROPERTY(QEasingCurve curve READ curve WRITE setCurve NOTIFY curveChanged); + QML_ELEMENT; + +public: + EasingCurve(QObject* parent = nullptr): QObject(parent) {} + + /// Returns the Y value for the given X value on the curve + /// from 0.0 to 1.0. + Q_INVOKABLE [[nodiscard]] qreal valueAt(qreal x) const; + /// Interpolates between two values using the given X coordinate. + Q_INVOKABLE [[nodiscard]] qreal interpolate(qreal x, qreal a, qreal b) const; + /// Interpolates between two points using the given X coordinate. + Q_INVOKABLE [[nodiscard]] QPointF interpolate(qreal x, const QPointF& a, const QPointF& b) const; + /// Interpolates two rects using the given X coordinate. + Q_INVOKABLE [[nodiscard]] QRectF interpolate(qreal x, const QRectF& a, const QRectF& b) const; + + [[nodiscard]] QEasingCurve curve() const; + void setCurve(QEasingCurve curve); + +signals: + void curveChanged(); + +private: + QEasingCurve mCurve; +}; diff --git a/src/core/module.md b/src/core/module.md index b8b6e45..bb713ec 100644 --- a/src/core/module.md +++ b/src/core/module.md @@ -15,5 +15,6 @@ headers = [ "popupwindow.hpp", "singleton.hpp", "lazyloader.hpp", + "easingcurve.hpp", ] -----