diff --git a/src/Window.hpp b/src/Window.hpp index 9df525dc..eacf69bf 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -62,6 +62,9 @@ public: SSurfaceTreeNode* m_pSurfaceTree = nullptr; + // Animated border + CColor m_cRealBorderColor = CColor(0,0,0,0); + // For the list lookup bool operator==(const CWindow& rhs) { diff --git a/src/defines.hpp b/src/defines.hpp index 29233ab5..004b8121 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -2,6 +2,7 @@ #include "debug/Log.hpp" #include "helpers/MiscFunctions.hpp" #include "helpers/WLListener.hpp" +#include "helpers/Color.hpp" #ifndef NDEBUG #define ISDEBUG true diff --git a/src/helpers/Color.cpp b/src/helpers/Color.cpp new file mode 100644 index 00000000..6b73b4d7 --- /dev/null +++ b/src/helpers/Color.cpp @@ -0,0 +1,24 @@ +#include "Color.hpp" +#include "../defines.hpp" + +CColor::CColor() { + +} + +CColor::CColor(float r, float g, float b, float a) { + this->r = r; + this->g = g; + this->b = b; + this->a = a; +} + +CColor::CColor(uint64_t hex) { + this->r = RED(hex) * 255.f; + this->g = GREEN(hex) * 255.f; + this->b = BLUE(hex) * 255.f; + this->a = ALPHA(hex) * 255.f; +} + +uint64_t CColor::getAsHex() { + return ((int)a) * 0x1000000 + ((int)r) * 0x10000 + ((int)g) * 0x100 + ((int)b) * 0x1; +} \ No newline at end of file diff --git a/src/helpers/Color.hpp b/src/helpers/Color.hpp new file mode 100644 index 00000000..7c0d30be --- /dev/null +++ b/src/helpers/Color.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "../includes.hpp" + +class CColor { +public: + CColor(); + CColor(float, float, float, float); + CColor(uint64_t); + + float r = 0, g = 0, b = 0, a = 255; + + uint64_t getAsHex(); + +}; \ No newline at end of file diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp index 2682f881..beb1549e 100644 --- a/src/managers/AnimationManager.cpp +++ b/src/managers/AnimationManager.cpp @@ -8,34 +8,47 @@ void CAnimationManager::tick() { if (!g_pConfigManager->getInt("animations:enabled")) animationsDisabled = true; - const bool WINDOWSENABLED = g_pConfigManager->getInt("animations:windows"); - // const bool BORDERSENABLED = g_pConfigManager->getInt("animations:borders"); - // const bool FADEENABLED = g_pConfigManager->getInt("animations:fadein"); + const bool WINDOWSENABLED = g_pConfigManager->getInt("animations:windows") && !animationsDisabled; + const bool BORDERSENABLED = g_pConfigManager->getInt("animations:borders") && !animationsDisabled; + // const bool FADEENABLED = g_pConfigManager->getInt("animations:fadein") && !animationsDisabled; const float ANIMSPEED = g_pConfigManager->getFloat("animations:speed"); + const auto BORDERACTIVECOL = CColor(g_pConfigManager->getInt("general:col.active_border")); + const auto BORDERINACTIVECOL = CColor(g_pConfigManager->getInt("general:col.inactive_border")); + for (auto& w : g_pCompositor->m_lWindows) { - if (animationsDisabled) { - w.m_vRealPosition = w.m_vEffectivePosition; - w.m_vRealSize = w.m_vEffectiveSize; - continue; + + // process the borders + const auto& COLOR = g_pXWaylandManager->getWindowSurface(&w) == g_pCompositor->m_pLastFocus ? BORDERACTIVECOL : BORDERINACTIVECOL; + + if (BORDERSENABLED) { + if (!deltazero(COLOR, w.m_cRealBorderColor)) { + if (deltaSmallToFlip(COLOR, w.m_cRealBorderColor)) { + w.m_cRealBorderColor = COLOR; + } else { + w.m_cRealBorderColor = parabolic(ANIMSPEED, w.m_cRealBorderColor, COLOR); + } + } + } else { + w.m_cRealBorderColor = COLOR; } // process the window if (WINDOWSENABLED) { - if (deltazero(w.m_vRealPosition, w.m_vEffectivePosition) && deltazero(w.m_vRealSize, w.m_vEffectiveSize)) { - continue; + if (!deltazero(w.m_vRealPosition, w.m_vEffectivePosition) || !deltazero(w.m_vRealSize, w.m_vEffectiveSize)) { + if (deltaSmallToFlip(w.m_vRealPosition, w.m_vEffectivePosition) && deltaSmallToFlip(w.m_vRealSize, w.m_vEffectiveSize)) { + w.m_vRealPosition = w.m_vEffectivePosition; + w.m_vRealSize = w.m_vEffectiveSize; + g_pXWaylandManager->setWindowSize(&w, w.m_vRealSize); + } else { + // if it is to be animated, animate it. + w.m_vRealPosition = Vector2D(parabolic(w.m_vRealPosition.x, w.m_vEffectivePosition.x, ANIMSPEED), parabolic(w.m_vRealPosition.y, w.m_vEffectivePosition.y, ANIMSPEED)); + w.m_vRealSize = Vector2D(parabolic(w.m_vRealSize.x, w.m_vEffectiveSize.x, ANIMSPEED), parabolic(w.m_vRealSize.y, w.m_vEffectiveSize.y, ANIMSPEED)); + } } - - if (deltaSmallToFlip(w.m_vRealPosition, w.m_vEffectivePosition) && deltaSmallToFlip(w.m_vRealSize, w.m_vEffectiveSize)) { - w.m_vRealPosition = w.m_vEffectivePosition; - w.m_vRealSize = w.m_vEffectiveSize; - g_pXWaylandManager->setWindowSize(&w, w.m_vRealSize); - continue; - } - - // if it is to be animated, animate it. - w.m_vRealPosition = Vector2D(parabolic(w.m_vRealPosition.x, w.m_vEffectivePosition.x, ANIMSPEED), parabolic(w.m_vRealPosition.y, w.m_vEffectivePosition.y, ANIMSPEED)); - w.m_vRealSize = Vector2D(parabolic(w.m_vRealSize.x, w.m_vEffectiveSize.x, ANIMSPEED), parabolic(w.m_vRealSize.y, w.m_vEffectiveSize.y, ANIMSPEED)); + } else { + w.m_vRealPosition = w.m_vEffectivePosition; + w.m_vRealSize = w.m_vEffectiveSize; } } } @@ -44,10 +57,29 @@ bool CAnimationManager::deltaSmallToFlip(const Vector2D& a, const Vector2D& b) { return std::abs(a.x - b.x) < 0.5f && std::abs(a.y - b.y) < 0.5f; } +bool CAnimationManager::deltaSmallToFlip(const CColor& a, const CColor& b) { + return std::abs(a.r - b.r) < 0.5f && std::abs(a.g - b.g) < 0.5f && std::abs(a.b - b.b) < 0.5f && std::abs(a.a - b.a) < 0.5f; +} + bool CAnimationManager::deltazero(const Vector2D& a, const Vector2D& b) { return a.x == b.x && a.y == b.y; } -double CAnimationManager::parabolic(double from, double to, double incline) { +bool CAnimationManager::deltazero(const CColor& a, const CColor& b) { + return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a; +} + +double CAnimationManager::parabolic(const double from, const double to, const double incline) { return from + ((to - from) / incline); +} + +CColor CAnimationManager::parabolic(const double incline, const CColor& from, const CColor& to) { + CColor newColor; + + newColor.r = parabolic(from.r, to.r, incline); + newColor.g = parabolic(from.g, to.g, incline); + newColor.b = parabolic(from.b, to.b, incline); + newColor.a = parabolic(from.a, to.a, incline); + + return newColor; } \ No newline at end of file diff --git a/src/managers/AnimationManager.hpp b/src/managers/AnimationManager.hpp index 38e433c6..450bbe2c 100644 --- a/src/managers/AnimationManager.hpp +++ b/src/managers/AnimationManager.hpp @@ -10,8 +10,11 @@ public: private: bool deltaSmallToFlip(const Vector2D& a, const Vector2D& b); + bool deltaSmallToFlip(const CColor& a, const CColor& b); bool deltazero(const Vector2D& a, const Vector2D& b); - double parabolic(double, double, double); + bool deltazero(const CColor& a, const CColor& b); + double parabolic(const double, const double, const double); + CColor parabolic(const double, const CColor&, const CColor&); }; inline std::unique_ptr g_pAnimationManager; \ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index a7babdd9..7ca86bca 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -395,7 +395,7 @@ void CHyprRenderer::arrangeLayersForMonitor(const int& monitor) { void CHyprRenderer::drawBorderForWindow(CWindow* pWindow, SMonitor* pMonitor) { const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size"); - const auto BORDERCOL = pWindow == g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus) ? g_pConfigManager->getInt("general:col.active_border") : g_pConfigManager->getInt("general:col.inactive_border"); + const auto BORDERCOL = pWindow->m_cRealBorderColor.getAsHex(); const float BORDERWLRCOL[4] = {RED(BORDERCOL), GREEN(BORDERCOL), BLUE(BORDERCOL), ALPHA(BORDERCOL)};