#include #include #include 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 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 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::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(); }