Hyprland/src/helpers/AnimatedVariable.hpp

317 lines
8.5 KiB
C++
Raw Normal View History

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>
#include "Vector2D.hpp"
#include "Color.hpp"
#include "../macros.hpp"
#include "../debug/Log.hpp"
2022-04-23 14:16:02 +02:00
enum ANIMATEDVARTYPE {
2022-04-23 14:16:02 +02:00
AVARTYPE_INVALID = -1,
AVARTYPE_FLOAT,
AVARTYPE_VECTOR,
AVARTYPE_COLOR
};
enum AVARDAMAGEPOLICY {
2023-01-20 20:48:07 +01:00
AVARDAMAGE_NONE = -1,
AVARDAMAGE_ENTIRE = 0,
AVARDAMAGE_BORDER,
AVARDAMAGE_SHADOW
};
2022-04-23 14:16:02 +02:00
class CAnimationManager;
2022-05-12 11:27:31 +02:00
class CWorkspace;
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
class CAnimatedVariable {
public:
2022-04-23 14:16:02 +02:00
CAnimatedVariable(); // dummy var
2022-07-28 13:28:43 +02:00
void create(ANIMATEDVARTYPE, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY);
void create(ANIMATEDVARTYPE, std::any val, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY);
2022-04-23 14:16:02 +02:00
CAnimatedVariable(const CAnimatedVariable&) = delete;
CAnimatedVariable(CAnimatedVariable&&) = delete;
CAnimatedVariable& operator=(const CAnimatedVariable&) = delete;
CAnimatedVariable& operator=(CAnimatedVariable&&) = delete;
2022-04-23 14:16:02 +02:00
~CAnimatedVariable();
2022-05-12 11:27:31 +02:00
void unregister();
void registerVar();
2022-05-12 11:27:31 +02:00
// gets the current vector value (real time)
2022-04-23 14:40:51 +02:00
const Vector2D& vec() const {
2022-04-23 14:16:02 +02:00
return m_vValue;
}
// gets the current float value (real time)
2022-04-23 14:40:51 +02:00
const float& fl() const {
2022-04-23 14:16:02 +02:00
return m_fValue;
}
// gets the current color value (real time)
2022-04-23 14:40:51 +02:00
const CColor& col() const {
2022-04-23 14:16:02 +02:00
return m_cValue;
}
// gets the goal vector value
2022-04-23 14:40:51 +02:00
const Vector2D& goalv() const {
return m_vGoal;
}
// gets the goal float value
2022-04-23 14:40:51 +02:00
const float& goalf() const {
return m_fGoal;
}
// gets the goal color value
2022-04-23 14:40:51 +02:00
const CColor& goalc() const {
return m_cGoal;
}
CAnimatedVariable& operator=(const Vector2D& v) {
if (v == m_vGoal)
return *this;
m_vGoal = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
return *this;
2022-04-23 14:16:02 +02:00
}
CAnimatedVariable& operator=(const float& v) {
if (v == m_fGoal)
return *this;
m_fGoal = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_fBegun = m_fValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
return *this;
2022-04-23 14:16:02 +02:00
}
CAnimatedVariable& operator=(const CColor& v) {
if (v == m_cGoal)
return *this;
m_cGoal = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_cBegun = m_cValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
return *this;
2022-04-23 14:16:02 +02:00
}
2022-04-23 21:47:16 +02:00
// Sets the actual stored value, without affecting the goal, but resets the timer
2022-04-23 14:16:02 +02:00
void setValue(const Vector2D& v) {
if (v == m_vValue)
return;
m_vValue = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
2022-04-23 14:16:02 +02:00
}
2022-04-23 21:47:16 +02:00
// Sets the actual stored value, without affecting the goal, but resets the timer
2022-04-23 14:16:02 +02:00
void setValue(const float& v) {
if (v == m_fValue)
return;
m_fValue = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
2022-04-23 14:16:02 +02:00
}
2022-04-23 21:47:16 +02:00
// Sets the actual stored value, without affecting the goal, but resets the timer
2022-04-23 14:16:02 +02:00
void setValue(const CColor& v) {
if (v == m_cValue)
return;
m_cValue = v;
2022-04-23 21:47:16 +02:00
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
2022-11-06 18:52:09 +01:00
onAnimationBegin();
2022-04-23 14:16:02 +02:00
}
// Sets the actual value and goal
void setValueAndWarp(const Vector2D& v) {
m_vGoal = v;
warp();
}
// Sets the actual value and goal
void setValueAndWarp(const float& v) {
m_fGoal = v;
warp();
}
// Sets the actual value and goal
void setValueAndWarp(const CColor& v) {
m_cGoal = v;
warp();
}
2022-05-12 11:27:31 +02:00
// checks if an animation is in progress
2023-07-19 22:40:03 +02:00
inline bool isBeingAnimated() {
return m_bIsBeingAnimated;
2022-05-12 11:27:31 +02:00
}
2022-11-06 18:52:09 +01:00
void warp(bool endCallback = true) {
2022-04-23 14:16:02 +02:00
switch (m_eVarType) {
case AVARTYPE_FLOAT: {
m_fValue = m_fGoal;
break;
}
case AVARTYPE_VECTOR: {
m_vValue = m_vGoal;
break;
}
case AVARTYPE_COLOR: {
m_cValue = m_cGoal;
break;
}
default: UNREACHABLE();
2022-04-23 14:16:02 +02:00
}
2022-11-06 18:52:09 +01:00
2023-07-19 22:40:03 +02:00
m_bIsBeingAnimated = false;
2022-11-06 18:52:09 +01:00
if (endCallback)
onAnimationEnd();
2022-04-23 14:16:02 +02: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();
/* 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) {
m_fEndCallback = func;
2022-11-06 18:52:09 +01:00
m_bRemoveEndAfterRan = remove;
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) {
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() {
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;
m_bRemoveEndAfterRan = false;
2022-11-18 14:53:54 +01:00
}
private:
Vector2D m_vValue = Vector2D(0, 0);
float m_fValue = 0;
CColor m_cValue;
2022-04-23 14:16:02 +02:00
Vector2D m_vGoal = Vector2D(0, 0);
float m_fGoal = 0;
CColor m_cGoal;
2022-04-23 14:16:02 +02:00
Vector2D m_vBegun = Vector2D(0, 0);
float m_fBegun = 0;
CColor m_cBegun;
2022-04-23 21:47:16 +02:00
// owners
void* m_pWindow = nullptr;
void* m_pWorkspace = nullptr;
void* m_pLayer = nullptr;
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;
ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID;
2023-01-20 20:48:07 +01:00
AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_NONE;
2022-04-23 14:16:02 +02: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;
bool m_bIsConnectedToActive = false;
void connectToActive();
void disconnectFromActive();
// methods
void onAnimationEnd() {
2023-07-19 22:40:03 +02:00
m_bIsBeingAnimated = false;
disconnectFromActive();
2023-07-19 22:40:03 +02:00
if (m_fEndCallback) {
// loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false.
auto removeEndCallback = m_bRemoveEndAfterRan;
m_fEndCallback(this);
if (removeEndCallback)
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;
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)
m_fBeginCallback = nullptr; // reset
}
}
2022-04-23 14:16:02 +02:00
friend class CAnimationManager;
2022-05-12 11:27:31 +02:00
friend class CWorkspace;
friend struct SLayerSurface;
2022-11-06 18:52:09 +01:00
friend class CHyprRenderer;
2022-09-25 20:07:48 +02:00
};