hyprutils/src/animation/AnimatedVariable.cpp

155 lines
4.4 KiB
C++

#include <hyprutils/animation/AnimatedVariable.hpp>
#include <hyprutils/animation/AnimationManager.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
using namespace Hyprutils::Animation;
using namespace Hyprutils::Memory;
static const std::string DEFAULTBEZIERNAME = "default";
static const std::string DEFAULTSTYLE = "";
#define SP CSharedPointer
#define WP CWeakPointer
void CBaseAnimatedVariable::create(CAnimationManager* pManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
m_Type = typeInfo;
m_pSelf = std::move(pSelf);
m_pAnimationManager = pManager;
m_pSignals = pManager->getSignals();
m_bDummy = false;
}
void CBaseAnimatedVariable::create2(CAnimationManager* pManager, int typeInfo, WP<CBaseAnimatedVariable> pSelf) {
m_Type = typeInfo;
m_pSelf = std::move(pSelf);
m_pAnimationManager = pManager;
m_pSignals = pManager->getSignals();
m_bDummy = false;
}
void CBaseAnimatedVariable::connectToActive() {
if (m_bDummy || m_bIsConnectedToActive || isAnimationManagerDead())
return;
m_pSignals->connect.emit(m_pSelf);
m_bIsConnectedToActive = true;
}
void CBaseAnimatedVariable::disconnectFromActive() {
if (isAnimationManagerDead())
return;
m_pSignals->disconnect.emit(m_pSelf);
m_bIsConnectedToActive = false;
}
bool Hyprutils::Animation::CBaseAnimatedVariable::enabled() const {
if (m_pConfig && m_pConfig->pValues)
return m_pConfig->pValues->internalEnabled;
return false;
}
const std::string& CBaseAnimatedVariable::getBezierName() const {
if (m_pConfig && m_pConfig->pValues)
return m_pConfig->pValues->internalBezier;
return DEFAULTBEZIERNAME;
}
const std::string& CBaseAnimatedVariable::getStyle() const {
if (m_pConfig && m_pConfig->pValues)
return m_pConfig->pValues->internalStyle;
return DEFAULTSTYLE;
}
float CBaseAnimatedVariable::getPercent() const {
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - animationBegin).count();
if (m_pConfig && m_pConfig->pValues)
return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f);
return 1.f;
}
float CBaseAnimatedVariable::getCurveValue() const {
if (!m_bIsBeingAnimated || isAnimationManagerDead())
return 1.f;
const auto BEZIER = m_pAnimationManager->getBezier(getBezierName());
if (!BEZIER)
return 1.f;
const auto SPENT = getPercent();
if (SPENT >= 1.f)
return 1.f;
return BEZIER->getYForPoint(SPENT);
}
bool CBaseAnimatedVariable::ok() const {
return m_pConfig && !m_bDummy && !isAnimationManagerDead();
}
void CBaseAnimatedVariable::onUpdate() {
if (m_bIsBeingAnimated && m_fUpdateCallback)
m_fUpdateCallback(m_pSelf);
}
void CBaseAnimatedVariable::setCallbackOnEnd(CallbackFun func, bool remove) {
m_fEndCallback = std::move(func);
m_bRemoveEndAfterRan = remove;
if (!isBeingAnimated())
onAnimationEnd();
}
void CBaseAnimatedVariable::setCallbackOnBegin(CallbackFun func, bool remove) {
m_fBeginCallback = std::move(func);
m_bRemoveBeginAfterRan = remove;
}
void CBaseAnimatedVariable::setUpdateCallback(CallbackFun func) {
m_fUpdateCallback = std::move(func);
}
void CBaseAnimatedVariable::resetAllCallbacks() {
m_fBeginCallback = nullptr;
m_fEndCallback = nullptr;
m_fUpdateCallback = nullptr;
m_bRemoveBeginAfterRan = false;
m_bRemoveEndAfterRan = false;
}
void CBaseAnimatedVariable::onAnimationEnd() {
m_bIsBeingAnimated = false;
/* We do not call disconnectFromActive here. The animation manager will remove it on a call to tickDone. */
if (m_fEndCallback) {
CallbackFun cb = nullptr;
m_fEndCallback.swap(cb);
cb(m_pSelf);
if (!m_bRemoveEndAfterRan && /* callback did not set a new one by itself */ !m_fEndCallback)
m_fEndCallback = cb; // restore
}
}
void CBaseAnimatedVariable::onAnimationBegin() {
m_bIsBeingAnimated = true;
animationBegin = std::chrono::steady_clock::now();
connectToActive();
if (m_fBeginCallback) {
m_fBeginCallback(m_pSelf);
if (m_bRemoveBeginAfterRan)
m_fBeginCallback = nullptr; // reset
}
}
bool CBaseAnimatedVariable::isAnimationManagerDead() const {
return m_pSignals.expired();
}