2022-04-23 14:16:02 +02:00
|
|
|
#pragma once
|
|
|
|
|
2023-08-07 13:35:19 +02:00
|
|
|
#include <functional>
|
2022-04-23 14:16:02 +02:00
|
|
|
#include <any>
|
2023-08-07 13:35:19 +02:00
|
|
|
#include <chrono>
|
2024-03-02 01:35:17 +01:00
|
|
|
#include <type_traits>
|
2023-08-07 13:35:19 +02:00
|
|
|
#include "Vector2D.hpp"
|
|
|
|
#include "Color.hpp"
|
|
|
|
#include "../macros.hpp"
|
2023-09-30 03:09:08 +02:00
|
|
|
#include "../debug/Log.hpp"
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2023-12-06 23:54:56 +01:00
|
|
|
enum ANIMATEDVARTYPE {
|
2022-04-23 14:16:02 +02:00
|
|
|
AVARTYPE_INVALID = -1,
|
|
|
|
AVARTYPE_FLOAT,
|
|
|
|
AVARTYPE_VECTOR,
|
|
|
|
AVARTYPE_COLOR
|
|
|
|
};
|
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
// Utility to bind a type with its corresponding ANIMATEDVARTYPE
|
|
|
|
template <class T>
|
|
|
|
struct typeToANIMATEDVARTYPE_t {
|
|
|
|
static constexpr ANIMATEDVARTYPE value = AVARTYPE_INVALID;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct typeToANIMATEDVARTYPE_t<float> {
|
|
|
|
static constexpr ANIMATEDVARTYPE value = AVARTYPE_FLOAT;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct typeToANIMATEDVARTYPE_t<Vector2D> {
|
|
|
|
static constexpr ANIMATEDVARTYPE value = AVARTYPE_VECTOR;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct typeToANIMATEDVARTYPE_t<CColor> {
|
|
|
|
static constexpr ANIMATEDVARTYPE value = AVARTYPE_COLOR;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
inline constexpr ANIMATEDVARTYPE typeToANIMATEDVARTYPE = typeToANIMATEDVARTYPE_t<T>::value;
|
|
|
|
|
2023-12-06 23:54:56 +01:00
|
|
|
enum AVARDAMAGEPOLICY {
|
2023-01-20 20:48:07 +01:00
|
|
|
AVARDAMAGE_NONE = -1,
|
|
|
|
AVARDAMAGE_ENTIRE = 0,
|
2022-07-16 12:44:45 +02:00
|
|
|
AVARDAMAGE_BORDER,
|
|
|
|
AVARDAMAGE_SHADOW
|
2022-05-05 14:02:30 +02:00
|
|
|
};
|
|
|
|
|
2022-04-23 14:16:02 +02:00
|
|
|
class CAnimationManager;
|
2022-05-12 11:27:31 +02:00
|
|
|
class CWorkspace;
|
2022-05-14 17:23:46 +02:00
|
|
|
struct SLayerSurface;
|
2022-07-28 13:28:43 +02:00
|
|
|
struct SAnimationPropertyConfig;
|
2022-11-06 18:52:09 +01:00
|
|
|
class CHyprRenderer;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
// Utility to define a concept as a list of possible type
|
|
|
|
template <class T, class... U>
|
|
|
|
concept OneOf = (... or std::same_as<T, U>);
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
// Concept to describe which type can be placed into CAnimatedVariable
|
|
|
|
// This is mainly to get better errors if we put a type that's not supported
|
|
|
|
// Otherwise template errors are ugly
|
|
|
|
template <class T>
|
|
|
|
concept Animable = OneOf<T, Vector2D, float, CColor>;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
class CBaseAnimatedVariable {
|
|
|
|
public:
|
|
|
|
CBaseAnimatedVariable(ANIMATEDVARTYPE type);
|
|
|
|
void create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy);
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete;
|
|
|
|
CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete;
|
|
|
|
CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete;
|
|
|
|
CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete;
|
2022-05-12 11:27:31 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
virtual ~CBaseAnimatedVariable();
|
2022-11-06 18:52:09 +01:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
void unregister();
|
|
|
|
void registerVar();
|
2023-07-19 22:40:03 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
virtual void warp(bool endCallback = true) = 0;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
//
|
2022-07-28 13:28:43 +02:00
|
|
|
void setConfig(SAnimationPropertyConfig* pConfig) {
|
|
|
|
m_pConfig = pConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
SAnimationPropertyConfig* getConfig() {
|
|
|
|
return m_pConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getDurationLeftMs();
|
|
|
|
|
2022-11-06 18:52:09 +01:00
|
|
|
/* returns the spent (completion) % */
|
|
|
|
float getPercent();
|
|
|
|
|
2022-12-29 12:30:43 +01:00
|
|
|
/* returns the current curve value */
|
|
|
|
float getCurveValue();
|
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
// checks if an animation is in progress
|
|
|
|
inline bool isBeingAnimated() {
|
|
|
|
return m_bIsBeingAnimated;
|
|
|
|
}
|
|
|
|
|
2022-11-04 16:56:31 +01:00
|
|
|
/* sets a function to be ran when the animation finishes.
|
|
|
|
if an animation is not running, runs instantly.
|
2022-11-06 18:52:09 +01:00
|
|
|
if "remove" is set to true, will remove the callback when ran. */
|
|
|
|
void setCallbackOnEnd(std::function<void(void* thisptr)> func, bool remove = true) {
|
2022-12-16 18:17:31 +01:00
|
|
|
m_fEndCallback = func;
|
2022-11-06 18:52:09 +01:00
|
|
|
m_bRemoveEndAfterRan = remove;
|
2022-11-04 16:56:31 +01:00
|
|
|
|
|
|
|
if (!isBeingAnimated())
|
|
|
|
onAnimationEnd();
|
|
|
|
}
|
|
|
|
|
2022-11-06 18:52:09 +01:00
|
|
|
/* sets a function to be ran when an animation is started.
|
|
|
|
if "remove" is set to true, will remove the callback when ran. */
|
|
|
|
void setCallbackOnBegin(std::function<void(void* thisptr)> func, bool remove = true) {
|
2022-12-16 18:17:31 +01:00
|
|
|
m_fBeginCallback = func;
|
2022-11-06 18:52:09 +01:00
|
|
|
m_bRemoveBeginAfterRan = remove;
|
|
|
|
}
|
|
|
|
|
2023-05-15 18:11:51 +02:00
|
|
|
/* Sets the update callback, called every time the value is animated and a step is done
|
|
|
|
Warning: calling unregisterVar/registerVar in this handler will cause UB */
|
|
|
|
void setUpdateCallback(std::function<void(void* thisptr)> func) {
|
|
|
|
m_fUpdateCallback = func;
|
|
|
|
}
|
|
|
|
|
2022-11-18 14:53:54 +01:00
|
|
|
/* resets all callbacks. Does not call any. */
|
|
|
|
void resetAllCallbacks() {
|
2022-12-16 18:17:31 +01:00
|
|
|
m_fBeginCallback = nullptr;
|
|
|
|
m_fEndCallback = nullptr;
|
2023-05-15 18:11:51 +02:00
|
|
|
m_fUpdateCallback = nullptr;
|
2022-11-18 14:53:54 +01:00
|
|
|
m_bRemoveBeginAfterRan = false;
|
2022-12-16 18:17:31 +01:00
|
|
|
m_bRemoveEndAfterRan = false;
|
2022-11-18 14:53:54 +01:00
|
|
|
}
|
|
|
|
|
2024-03-02 01:35:17 +01:00
|
|
|
protected:
|
2022-12-16 18:17:31 +01:00
|
|
|
void* m_pWindow = nullptr;
|
|
|
|
void* m_pWorkspace = nullptr;
|
|
|
|
void* m_pLayer = nullptr;
|
2022-05-14 17:23:46 +02:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
SAnimationPropertyConfig* m_pConfig = nullptr;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2023-07-19 22:40:03 +02:00
|
|
|
bool m_bDummy = true;
|
|
|
|
bool m_bIsRegistered = false;
|
|
|
|
bool m_bIsBeingAnimated = false;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2022-04-23 21:47:16 +02:00
|
|
|
std::chrono::system_clock::time_point animationBegin;
|
|
|
|
|
2023-01-20 20:48:07 +01:00
|
|
|
AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_NONE;
|
2024-03-02 01:35:17 +01:00
|
|
|
ANIMATEDVARTYPE m_Type;
|
2022-04-23 14:16:02 +02:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
bool m_bRemoveEndAfterRan = true;
|
|
|
|
bool m_bRemoveBeginAfterRan = true;
|
|
|
|
std::function<void(void* thisptr)> m_fEndCallback;
|
|
|
|
std::function<void(void* thisptr)> m_fBeginCallback;
|
2023-05-15 18:11:51 +02:00
|
|
|
std::function<void(void* thisptr)> m_fUpdateCallback;
|
2022-11-04 16:56:31 +01:00
|
|
|
|
2023-07-20 19:26:10 +02:00
|
|
|
bool m_bIsConnectedToActive = false;
|
2024-03-02 01:35:17 +01:00
|
|
|
|
2023-07-20 19:26:10 +02:00
|
|
|
void connectToActive();
|
2024-03-02 01:35:17 +01:00
|
|
|
|
2023-07-20 19:26:10 +02:00
|
|
|
void disconnectFromActive();
|
|
|
|
|
2022-11-04 16:56:31 +01:00
|
|
|
// methods
|
|
|
|
void onAnimationEnd() {
|
2023-07-19 22:40:03 +02:00
|
|
|
m_bIsBeingAnimated = false;
|
2023-07-20 19:26:10 +02:00
|
|
|
disconnectFromActive();
|
2023-07-19 22:40:03 +02:00
|
|
|
|
2022-11-04 16:56:31 +01:00
|
|
|
if (m_fEndCallback) {
|
2023-05-29 09:51:58 +02:00
|
|
|
// loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false.
|
|
|
|
auto removeEndCallback = m_bRemoveEndAfterRan;
|
2022-11-04 16:56:31 +01:00
|
|
|
m_fEndCallback(this);
|
2023-05-29 09:51:58 +02:00
|
|
|
if (removeEndCallback)
|
2022-12-16 18:17:31 +01:00
|
|
|
m_fEndCallback = nullptr; // reset
|
2022-11-06 18:52:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void onAnimationBegin() {
|
2023-07-19 22:40:03 +02:00
|
|
|
m_bIsBeingAnimated = true;
|
2023-07-20 19:26:10 +02:00
|
|
|
connectToActive();
|
2023-07-19 22:40:03 +02:00
|
|
|
|
2022-11-06 18:52:09 +01:00
|
|
|
if (m_fBeginCallback) {
|
|
|
|
m_fBeginCallback(this);
|
|
|
|
if (m_bRemoveBeginAfterRan)
|
2022-12-16 18:17:31 +01:00
|
|
|
m_fBeginCallback = nullptr; // reset
|
2022-11-04 16:56:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-23 14:16:02 +02:00
|
|
|
friend class CAnimationManager;
|
2022-05-12 11:27:31 +02:00
|
|
|
friend class CWorkspace;
|
2022-05-14 17:23:46 +02:00
|
|
|
friend struct SLayerSurface;
|
2022-11-06 18:52:09 +01:00
|
|
|
friend class CHyprRenderer;
|
2022-09-25 20:07:48 +02:00
|
|
|
};
|
2024-03-02 01:35:17 +01:00
|
|
|
|
|
|
|
template <Animable VarType>
|
|
|
|
class CAnimatedVariable : public CBaseAnimatedVariable {
|
|
|
|
public:
|
|
|
|
CAnimatedVariable() : CBaseAnimatedVariable(typeToANIMATEDVARTYPE<VarType>) {} // dummy var
|
|
|
|
|
|
|
|
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) {
|
|
|
|
create(pAnimConfig, pWindow, policy);
|
|
|
|
m_Value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
using CBaseAnimatedVariable::create;
|
|
|
|
|
|
|
|
CAnimatedVariable(const CAnimatedVariable&) = delete;
|
|
|
|
CAnimatedVariable(CAnimatedVariable&&) = delete;
|
|
|
|
CAnimatedVariable& operator=(const CAnimatedVariable&) = delete;
|
|
|
|
CAnimatedVariable& operator=(CAnimatedVariable&&) = delete;
|
|
|
|
|
|
|
|
~CAnimatedVariable() = default;
|
|
|
|
|
|
|
|
// gets the current vector value (real time)
|
|
|
|
const VarType& value() const {
|
|
|
|
return m_Value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// gets the goal vector value
|
|
|
|
const VarType& goal() const {
|
|
|
|
return m_Goal;
|
|
|
|
}
|
|
|
|
|
|
|
|
CAnimatedVariable& operator=(const VarType& v) {
|
|
|
|
if (v == m_Goal)
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
m_Goal = v;
|
|
|
|
animationBegin = std::chrono::system_clock::now();
|
|
|
|
m_Begun = m_Value;
|
|
|
|
|
|
|
|
onAnimationBegin();
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sets the actual stored value, without affecting the goal, but resets the timer
|
|
|
|
void setValue(const VarType& v) {
|
|
|
|
if (v == m_Value)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_Value = v;
|
|
|
|
animationBegin = std::chrono::system_clock::now();
|
|
|
|
m_Begun = m_Value;
|
|
|
|
|
|
|
|
onAnimationBegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sets the actual value and goal
|
|
|
|
void setValueAndWarp(const VarType& v) {
|
|
|
|
m_Goal = v;
|
|
|
|
warp();
|
|
|
|
}
|
|
|
|
|
|
|
|
void warp(bool endCallback = true) override {
|
|
|
|
m_Value = m_Goal;
|
|
|
|
|
|
|
|
m_bIsBeingAnimated = false;
|
|
|
|
|
|
|
|
if (endCallback)
|
|
|
|
onAnimationEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
VarType m_Value{};
|
|
|
|
VarType m_Goal{};
|
|
|
|
VarType m_Begun{};
|
|
|
|
|
|
|
|
// owners
|
|
|
|
|
|
|
|
friend class CAnimationManager;
|
|
|
|
friend class CWorkspace;
|
|
|
|
friend struct SLayerSurface;
|
|
|
|
friend class CHyprRenderer;
|
|
|
|
};
|