diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 7a309a8..b5e936a 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -31,6 +31,7 @@ void CConfigManager::init() { m_config.addSpecialConfigValue("input-field", "inner_color", Hyprlang::INT{0xFFDDDDDD}); m_config.addSpecialConfigValue("input-field", "outer_color", Hyprlang::INT{0xFF111111}); m_config.addSpecialConfigValue("input-field", "outline_thickness", Hyprlang::INT{4}); + m_config.addSpecialConfigValue("input-field", "fade_on_empty", Hyprlang::INT{1}); m_config.commence(); @@ -75,6 +76,7 @@ std::vector CConfigManager::getWidgetConfigs() { {"inner_color", m_config.getSpecialConfigValue("input-field", "inner_color", k.c_str())}, {"outer_color", m_config.getSpecialConfigValue("input-field", "outer_color", k.c_str())}, {"outline_thickness", m_config.getSpecialConfigValue("input-field", "outline_thickness", k.c_str())}, + {"fade_on_empty", m_config.getSpecialConfigValue("input-field", "fade_on_empty", k.c_str())}, } }); // clang-format on diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 86285af..4fd1514 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -251,9 +251,9 @@ std::vector>* CRenderer::getOrCreateWidgetsFor(const CS widgets[surf].emplace_back(std::make_unique(surf->size, std::string{"background:"} + std::any_cast(c.values.at("path")))); if (c.type == "input-field") { const auto SIZE = std::any_cast(c.values.at("size")); - widgets[surf].emplace_back(std::make_unique(surf->size, Vector2D{SIZE.x, SIZE.y}, std::any_cast(c.values.at("outer_color")), - std::any_cast(c.values.at("inner_color")), - std::any_cast(c.values.at("outline_thickness")))); + widgets[surf].emplace_back(std::make_unique( + surf->size, Vector2D{SIZE.x, SIZE.y}, std::any_cast(c.values.at("outer_color")), std::any_cast(c.values.at("inner_color")), + std::any_cast(c.values.at("outline_thickness")), std::any_cast(c.values.at("fade_on_empty")))); } } } diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 1b7dbbc..4ca7718 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -3,12 +3,44 @@ #include "../../core/hyprlock.hpp" #include -CPasswordInputField::CPasswordInputField(const Vector2D& viewport, const Vector2D& size_, const CColor& outer_, const CColor& inner_, int out_thick_) { - size = size_; - pos = viewport / 2.f - size_ / 2.f; - inner = inner_; - outer = outer_; - out_thick = out_thick_; +CPasswordInputField::CPasswordInputField(const Vector2D& viewport, const Vector2D& size_, const CColor& outer_, const CColor& inner_, int out_thick_, bool fadeEmpty) { + size = size_; + pos = viewport / 2.f - size_ / 2.f; + inner = inner_; + outer = outer_; + out_thick = out_thick_; + fadeOnEmpty = fadeEmpty; +} + +void CPasswordInputField::updateFade() { + const auto PASSLEN = g_pHyprlock->getPasswordBufferLen(); + + if (!fadeOnEmpty) { + fade.a = 1.0; + return; + } + + if (PASSLEN == 0 && fade.a != 0.0 && (!fade.animated || fade.appearing)) { + fade.a = 1.0; + fade.animated = true; + fade.appearing = false; + fade.start = std::chrono::system_clock::now(); + } else if (PASSLEN > 0 && fade.a != 1.0 && (!fade.animated || !fade.appearing)) { + fade.a = 0.0; + fade.animated = true; + fade.appearing = true; + fade.start = std::chrono::system_clock::now(); + } + + if (fade.animated) { + if (fade.appearing) + fade.a = std::clamp(std::chrono::duration_cast(std::chrono::system_clock::now() - fade.start).count() / 100000.0, 0.0, 1.0); + else + fade.a = std::clamp(1.0 - std::chrono::duration_cast(std::chrono::system_clock::now() - fade.start).count() / 100000.0, 0.0, 1.0); + + if ((fade.appearing && fade.a == 1.0) || (!fade.appearing && fade.a == 0.0)) + fade.animated = false; + } } void CPasswordInputField::updateDots() { @@ -44,10 +76,16 @@ bool CPasswordInputField::draw() { CBox inputFieldBox = {pos, size}; CBox outerBox = {pos - Vector2D{out_thick, out_thick}, size + Vector2D{out_thick * 2, out_thick * 2}}; + updateFade(); updateDots(); - g_pRenderer->renderRect(outerBox, outer, outerBox.h / 2.0); - g_pRenderer->renderRect(inputFieldBox, inner, inputFieldBox.h / 2.0); + CColor outerCol = outer; + outer.a = fade.a; + CColor innerCol = inner; + innerCol.a = fade.a; + + g_pRenderer->renderRect(outerBox, outerCol, outerBox.h / 2.0); + g_pRenderer->renderRect(inputFieldBox, innerCol, inputFieldBox.h / 2.0); constexpr int PASS_SPACING = 3; constexpr int PASS_SIZE = 8; @@ -58,5 +96,5 @@ bool CPasswordInputField::draw() { g_pRenderer->renderRect(box, CColor{0, 0, 0, dots[i].a}, PASS_SIZE / 2.0); } - return std::ranges::any_of(dots.begin(), dots.end(), [](const auto& dot) { return dot.animated; }); + return std::ranges::any_of(dots.begin(), dots.end(), [](const auto& dot) { return dot.animated; }) || fade.animated; } \ No newline at end of file diff --git a/src/renderer/widgets/PasswordInputField.hpp b/src/renderer/widgets/PasswordInputField.hpp index eb98968..8c8d71a 100644 --- a/src/renderer/widgets/PasswordInputField.hpp +++ b/src/renderer/widgets/PasswordInputField.hpp @@ -8,12 +8,13 @@ class CPasswordInputField : public IWidget { public: - CPasswordInputField(const Vector2D& viewport, const Vector2D& size, const CColor& outer, const CColor& inner, int out_thick); + CPasswordInputField(const Vector2D& viewport, const Vector2D& size, const CColor& outer, const CColor& inner, int out_thick, bool fade_empty); virtual bool draw(); private: void updateDots(); + void updateFade(); Vector2D size; Vector2D pos; @@ -30,5 +31,14 @@ class CPasswordInputField : public IWidget { std::chrono::system_clock::time_point start; }; + struct { + std::chrono::system_clock::time_point start; + float a = 0; + bool appearing = true; + bool animated = false; + } fade; + + bool fadeOnEmpty; + std::vector dots; }; \ No newline at end of file