mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-22 19:45:58 +01:00
Added bezier curves
This commit is contained in:
parent
306d163613
commit
3ebe7d7972
14 changed files with 255 additions and 67 deletions
|
@ -50,7 +50,8 @@ Try it out and report bugs / suggestions!
|
|||
|
||||
- Easily expandable and readable codebase
|
||||
- Config reloaded instantly upon saving
|
||||
- Parabolic window animations
|
||||
- Bezier-curve window animations
|
||||
- Custom bezier curves
|
||||
- Workspaces protocol support
|
||||
- Tiling / floating / fullscreen windows
|
||||
- Window / monitor rules
|
||||
|
|
|
@ -41,7 +41,9 @@ decoration {
|
|||
|
||||
animations {
|
||||
enabled=1
|
||||
speed=7
|
||||
speed=7 # speed is measured in 100s of ms, 7 = 700ms
|
||||
curve=default # you can customize your own bezier curves, see the wiki
|
||||
windows_curve=default # specific curve for all window animations
|
||||
windows_speed=6 # specific speeds for components can be made with name_speed=float. 0 means use global (speed=float). If not set, will use the global value.
|
||||
windows=1
|
||||
borders=1
|
||||
|
|
|
@ -158,6 +158,9 @@ void CCompositor::startCompositor() {
|
|||
Debug::log(LOG, "Creating the KeybindManager!");
|
||||
g_pKeybindManager = std::make_unique<CKeybindManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the AnimationManager!");
|
||||
g_pAnimationManager = std::make_unique<CAnimationManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the ConfigManager!");
|
||||
g_pConfigManager = std::make_unique<CConfigManager>();
|
||||
|
||||
|
@ -178,9 +181,6 @@ void CCompositor::startCompositor() {
|
|||
|
||||
Debug::log(LOG, "Creating the LayoutManager!");
|
||||
g_pLayoutManager = std::make_unique<CLayoutManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the AnimationManager!");
|
||||
g_pAnimationManager = std::make_unique<CAnimationManager>();
|
||||
//
|
||||
//
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
#include "Compositor.hpp"
|
||||
|
||||
CWindow::CWindow() {
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, (void*)this);
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, (void*)this);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, (void*)this);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, (void*)this);
|
||||
m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*) this);
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this);
|
||||
}
|
||||
|
||||
CWindow::~CWindow() {
|
||||
|
|
|
@ -43,10 +43,14 @@ void CConfigManager::setDefaultVars() {
|
|||
|
||||
configValues["animations:enabled"].intValue = 1;
|
||||
configValues["animations:speed"].floatValue = 7.f;
|
||||
configValues["animations:curve"].strValue = "default";
|
||||
configValues["animations:windows_curve"].strValue = "[[f]]";
|
||||
configValues["animations:windows_speed"].floatValue = 0.f;
|
||||
configValues["animations:windows"].intValue = 1;
|
||||
configValues["animations:borders_curve"].strValue = "[[f]]";
|
||||
configValues["animations:borders_speed"].floatValue = 0.f;
|
||||
configValues["animations:borders"].intValue = 1;
|
||||
configValues["animations:fadein_curve"].strValue = "[[f]]";
|
||||
configValues["animations:fadein_speed"].floatValue = 0.f;
|
||||
configValues["animations:fadein"].intValue = 1;
|
||||
|
||||
|
@ -207,6 +211,39 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
|||
m_dMonitorRules.push_back(newrule);
|
||||
}
|
||||
|
||||
void CConfigManager::handleBezier(const std::string& command, const std::string& args) {
|
||||
std::string curitem = "";
|
||||
|
||||
std::string argZ = args;
|
||||
|
||||
auto nextItem = [&]() {
|
||||
auto idx = argZ.find_first_of(',');
|
||||
|
||||
if (idx != std::string::npos) {
|
||||
curitem = argZ.substr(0, idx);
|
||||
argZ = argZ.substr(idx + 1);
|
||||
} else {
|
||||
curitem = argZ;
|
||||
argZ = "";
|
||||
}
|
||||
};
|
||||
|
||||
nextItem();
|
||||
|
||||
std::string bezierName = curitem;
|
||||
|
||||
nextItem();
|
||||
float p1x = std::stof(curitem);
|
||||
nextItem();
|
||||
float p1y = std::stof(curitem);
|
||||
nextItem();
|
||||
float p2x = std::stof(curitem);
|
||||
nextItem();
|
||||
float p2y = std::stof(curitem);
|
||||
|
||||
g_pAnimationManager->addBezierWithName(bezierName, Vector2D(p1x, p1y), Vector2D(p2x, p2y));
|
||||
}
|
||||
|
||||
void CConfigManager::handleBind(const std::string& command, const std::string& value) {
|
||||
// example:
|
||||
// bind=SUPER,G,exec,dmenu_run <args>
|
||||
|
@ -311,6 +348,8 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
|||
handleDefaultWorkspace(COMMAND, VALUE);
|
||||
} else if (COMMAND == "windowrule") {
|
||||
handleWindowRule(COMMAND, VALUE);
|
||||
} else if (COMMAND == "bezier") {
|
||||
handleBezier(COMMAND, VALUE);
|
||||
} else {
|
||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||
}
|
||||
|
@ -379,10 +418,10 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
|
||||
// reset all vars before loading
|
||||
setDefaultVars();
|
||||
|
||||
m_dMonitorRules.clear();
|
||||
m_dWindowRules.clear();
|
||||
g_pKeybindManager->clearKeybinds();
|
||||
g_pAnimationManager->removeAllBeziers();
|
||||
|
||||
const char* const ENVHOME = getenv("HOME");
|
||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
||||
|
|
|
@ -92,6 +92,7 @@ private:
|
|||
void handleUnbind(const std::string&, const std::string&);
|
||||
void handleWindowRule(const std::string&, const std::string&);
|
||||
void handleDefaultWorkspace(const std::string&, const std::string&);
|
||||
void handleBezier(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
|
@ -5,19 +5,20 @@ CAnimatedVariable::CAnimatedVariable() {
|
|||
; // dummy var
|
||||
}
|
||||
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, float* speed, int64_t* enabled, void* pWindow) {
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow) {
|
||||
m_eVarType = type;
|
||||
m_pSpeed = speed;
|
||||
m_pEnabled = enabled;
|
||||
m_pWindow = pWindow;
|
||||
m_pBezier = pBezier;
|
||||
|
||||
g_pAnimationManager->m_lAnimatedVariables.push_back(this);
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, float* speed, int64_t* enabled, void* pWindow) {
|
||||
create(type, speed, enabled, pWindow);
|
||||
void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow) {
|
||||
create(type, speed, enabled, pBezier, pWindow);
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
|
|
|
@ -16,8 +16,8 @@ class CAnimatedVariable {
|
|||
public:
|
||||
CAnimatedVariable(); // dummy var
|
||||
|
||||
void create(ANIMATEDVARTYPE, float* speed, int64_t* enabled, void* pWindow);
|
||||
void create(ANIMATEDVARTYPE, std::any val, float* speed, int64_t* enabled, void* pWindow);
|
||||
void create(ANIMATEDVARTYPE, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow);
|
||||
void create(ANIMATEDVARTYPE, std::any val, float* speed, int64_t* enabled, std::string* pBezier, void* pWindow);
|
||||
|
||||
~CAnimatedVariable();
|
||||
|
||||
|
@ -60,34 +60,46 @@ public:
|
|||
void operator=(const Vector2D& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_VECTOR);
|
||||
m_vGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
}
|
||||
|
||||
void operator=(const float& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_FLOAT);
|
||||
m_fGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_fBegun = m_fValue;
|
||||
}
|
||||
|
||||
void operator=(const CColor& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_COLOR);
|
||||
m_cGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_cBegun = m_cValue;
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const Vector2D& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_VECTOR);
|
||||
m_vValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const float& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_FLOAT);
|
||||
m_fValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
}
|
||||
|
||||
// Sets the actual stored value, without affecting the goal
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const CColor& v) {
|
||||
ASSERT(m_eVarType == AVARTYPE_COLOR);
|
||||
m_cValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
}
|
||||
|
||||
// Sets the actual value and goal
|
||||
|
@ -140,12 +152,19 @@ private:
|
|||
float m_fGoal = 0;
|
||||
CColor m_cGoal;
|
||||
|
||||
Vector2D m_vBegun = Vector2D(0,0);
|
||||
float m_fBegun = 0;
|
||||
CColor m_cBegun;
|
||||
|
||||
float* m_pSpeed = nullptr;
|
||||
int64_t* m_pEnabled = nullptr;
|
||||
void* m_pWindow = nullptr;
|
||||
std::string* m_pBezier = nullptr;
|
||||
|
||||
bool m_bDummy = true;
|
||||
|
||||
std::chrono::system_clock::time_point animationBegin;
|
||||
|
||||
ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID;
|
||||
|
||||
friend class CAnimationManager;
|
||||
|
|
55
src/helpers/BezierCurve.cpp
Normal file
55
src/helpers/BezierCurve.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include "BezierCurve.hpp"
|
||||
|
||||
void CBezierCurve::setup(std::vector<Vector2D>* pVec) {
|
||||
m_dPoints.clear();
|
||||
|
||||
m_dPoints.emplace_back(Vector2D(0,0));
|
||||
|
||||
for (auto& p : *pVec) {
|
||||
m_dPoints.push_back(p);
|
||||
}
|
||||
|
||||
m_dPoints.emplace_back(Vector2D(1,1));
|
||||
|
||||
RASSERT(m_dPoints.size() == 4, "CBezierCurve only supports cubic beziers! (points num: %i)", m_dPoints.size());
|
||||
|
||||
// bake 100 points for faster lookups
|
||||
// T -> X ( / 100 )
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
m_aPointsBaked[i] = getXForT((i + 1) / 100.f);
|
||||
}
|
||||
}
|
||||
|
||||
float CBezierCurve::getYForT(float t) {
|
||||
return 3 * t * pow(1 - t, 2) * m_dPoints[1].y + 3 * pow(t, 2) * (1 - t) * m_dPoints[2].y + pow(t, 3);
|
||||
}
|
||||
|
||||
float CBezierCurve::getXForT(float t) {
|
||||
return 3 * t * pow(1 - t, 2) * m_dPoints[1].x + 3 * pow(t, 2) * (1 - t) * m_dPoints[2].x + pow(t, 3);
|
||||
}
|
||||
|
||||
// Todo: this probably can be done better and faster
|
||||
float CBezierCurve::getYForPoint(float x) {
|
||||
// binary search for the range UPDOWN X
|
||||
float upperX = 1;
|
||||
float lowerX = 0;
|
||||
float mid = 0.5;
|
||||
|
||||
while(std::abs(upperX - lowerX) > 0.01f) {
|
||||
if (m_aPointsBaked[((int)(mid * 100.f))] > x) {
|
||||
upperX = mid;
|
||||
} else {
|
||||
lowerX = mid;
|
||||
}
|
||||
|
||||
mid = (upperX + lowerX) / 2.f;
|
||||
}
|
||||
|
||||
// in the name of performance i shall make a hack
|
||||
const auto PERCINDELTA = (x - m_aPointsBaked[(int)(100.f * lowerX)]) / (m_aPointsBaked[(int)(100.f * upperX)] - m_aPointsBaked[(int)(100.f * lowerX)]);
|
||||
|
||||
if (std::isnan(PERCINDELTA) || std::isinf(PERCINDELTA)) // can sometimes happen for VERY small x
|
||||
return 0.f;
|
||||
|
||||
return getYForT(mid + PERCINDELTA * 0.01f);
|
||||
}
|
24
src/helpers/BezierCurve.hpp
Normal file
24
src/helpers/BezierCurve.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <deque>
|
||||
|
||||
// an implementation of a cubic bezier curve
|
||||
// might do better later
|
||||
// TODO: n-point curves
|
||||
class CBezierCurve {
|
||||
public:
|
||||
// sets up the bezier curve.
|
||||
// this EXCLUDES the 0,0 and 1,1 points,
|
||||
void setup(std::vector<Vector2D>* points);
|
||||
|
||||
float getYForT(float t);
|
||||
float getXForT(float t);
|
||||
float getYForPoint(float x);
|
||||
|
||||
private:
|
||||
// this INCLUDES the 0,0 and 1,1 points.
|
||||
std::deque<Vector2D> m_dPoints;
|
||||
|
||||
std::array<float, 100> m_aPointsBaked;
|
||||
};
|
|
@ -12,4 +12,16 @@ public:
|
|||
|
||||
uint64_t getAsHex();
|
||||
|
||||
CColor operator- (const CColor& c2) const {
|
||||
return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a);
|
||||
}
|
||||
|
||||
CColor operator+ (const CColor& c2) const {
|
||||
return CColor(r + c2.r, g + c2.g, b + c2.b, a + c2.a);
|
||||
}
|
||||
|
||||
CColor operator* (const float& v) const {
|
||||
return CColor(r * v, g * v, b * v, a * v);
|
||||
}
|
||||
|
||||
};
|
|
@ -451,10 +451,10 @@ void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) {
|
|||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||
} else {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)999999)));
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.vec());
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
// we need to adjust the splitratio
|
||||
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
#include "AnimationManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
CAnimationManager::CAnimationManager() {
|
||||
std::vector<Vector2D> points = {Vector2D(0, 0.75f), Vector2D(0.25f, 1.f)};
|
||||
m_mBezierCurves["default"].setup(&points);
|
||||
}
|
||||
|
||||
void CAnimationManager::removeAllBeziers() {
|
||||
m_mBezierCurves.clear();
|
||||
|
||||
// add the default one
|
||||
std::vector<Vector2D> points = {Vector2D(0, 0.75f), Vector2D(0.25f, 1.f)};
|
||||
m_mBezierCurves["default"].setup(&points);
|
||||
}
|
||||
|
||||
void CAnimationManager::addBezierWithName(std::string name, const Vector2D& p1, const Vector2D& p2) {
|
||||
std::vector points = {p1, p2};
|
||||
m_mBezierCurves[name].setup(&points);
|
||||
}
|
||||
|
||||
void CAnimationManager::tick() {
|
||||
|
||||
bool animationsDisabled = false;
|
||||
|
@ -9,61 +27,88 @@ void CAnimationManager::tick() {
|
|||
animationsDisabled = true;
|
||||
|
||||
const float ANIMSPEED = g_pConfigManager->getFloat("animations:speed");
|
||||
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
const auto BEZIERSTR = g_pConfigManager->getString("animations:curve");
|
||||
|
||||
auto DEFAULTBEZIER = m_mBezierCurves.find(BEZIERSTR);
|
||||
if (DEFAULTBEZIER == m_mBezierCurves.end())
|
||||
DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
for (auto& av : m_lAnimatedVariables) {
|
||||
// first, we check if it's disabled, if so, warp
|
||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
continue;
|
||||
}
|
||||
|
||||
// get speed
|
||||
const auto SPEED = *av->m_pSpeed == 0 ? ANIMSPEED : *av->m_pSpeed;
|
||||
|
||||
// window stuff
|
||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||
bool needsDamage = false;
|
||||
wlr_box WLRBOXPREV = {PWINDOW->m_vRealPosition.vec().x - BORDERSIZE - 1, PWINDOW->m_vRealPosition.vec().y - BORDERSIZE - 1, PWINDOW->m_vRealSize.vec().x + 2 * BORDERSIZE + 2, PWINDOW->m_vRealSize.vec().y + 2 * BORDERSIZE + 2};
|
||||
|
||||
// TODO: curves
|
||||
// check if it's disabled, if so, warp
|
||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
g_pHyprRenderer->damageBox(&WLRBOXPREV);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
continue;
|
||||
}
|
||||
|
||||
// parabolic with a switch unforto
|
||||
// beziers are with a switch unforto
|
||||
// TODO: maybe do something cleaner
|
||||
|
||||
// get the spent % (0 - 1)
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - av->animationBegin).count();
|
||||
const float SPENT = std::clamp((DURATIONPASSED / 100.f) / SPEED, 0.f, 1.f);
|
||||
|
||||
switch (av->m_eVarType) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
if (!deltazero(av->m_fValue, av->m_fGoal)) {
|
||||
if (deltaSmallToFlip(av->m_fValue, av->m_fGoal)) {
|
||||
av->warp();
|
||||
} else {
|
||||
av->m_fValue = parabolic(av->m_fValue, av->m_fGoal, SPEED);
|
||||
}
|
||||
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
needsDamage = true;
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
else
|
||||
av->m_fValue = av->m_fBegun + DEFAULTBEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
}
|
||||
} else {
|
||||
continue; // dont process
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_VECTOR: {
|
||||
if (!deltazero(av->m_vValue, av->m_vGoal)) {
|
||||
if (deltaSmallToFlip(av->m_vValue, av->m_vGoal)) {
|
||||
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_vValue = av->m_vBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
} else {
|
||||
av->m_vValue.x = parabolic(av->m_vValue.x, av->m_vGoal.x, SPEED);
|
||||
av->m_vValue.y = parabolic(av->m_vValue.y, av->m_vGoal.y, SPEED);
|
||||
}
|
||||
needsDamage = true;
|
||||
} else {
|
||||
continue; // dont process
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_COLOR: {
|
||||
if (!deltazero(av->m_cValue, av->m_cGoal)) {
|
||||
if (deltaSmallToFlip(av->m_cValue, av->m_cGoal)) {
|
||||
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_cValue = av->m_cBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
} else {
|
||||
av->m_cValue = parabolic(SPEED, av->m_cValue, av->m_cGoal);
|
||||
}
|
||||
needsDamage = true;
|
||||
} else {
|
||||
continue; // dont process
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -72,12 +117,10 @@ void CAnimationManager::tick() {
|
|||
}
|
||||
}
|
||||
|
||||
// invalidate the window
|
||||
if (needsDamage) {
|
||||
// damage the window
|
||||
g_pHyprRenderer->damageBox(&WLRBOXPREV);
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CAnimationManager::deltaSmallToFlip(const Vector2D& a, const Vector2D& b) {
|
||||
|
@ -103,18 +146,3 @@ bool CAnimationManager::deltazero(const float& a, const float& b) {
|
|||
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;
|
||||
}
|
|
@ -2,12 +2,18 @@
|
|||
|
||||
#include "../defines.hpp"
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../helpers/BezierCurve.hpp"
|
||||
|
||||
class CAnimationManager {
|
||||
public:
|
||||
|
||||
CAnimationManager();
|
||||
|
||||
void tick();
|
||||
void addBezierWithName(std::string, const Vector2D&, const Vector2D&);
|
||||
void removeAllBeziers();
|
||||
|
||||
std::list<CAnimatedVariable*> m_lAnimatedVariables;
|
||||
|
||||
|
@ -18,8 +24,8 @@ private:
|
|||
bool deltazero(const Vector2D& a, const Vector2D& b);
|
||||
bool deltazero(const CColor& a, const CColor& b);
|
||||
bool deltazero(const float& a, const float& b);
|
||||
double parabolic(const double, const double, const double);
|
||||
CColor parabolic(const double, const CColor&, const CColor&);
|
||||
|
||||
std::unordered_map<std::string, CBezierCurve> m_mBezierCurves;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CAnimationManager> g_pAnimationManager;
|
Loading…
Reference in a new issue