input-field: add fade_on_empty

This commit is contained in:
Vaxry 2024-02-19 01:22:22 +00:00
parent 80d6dff563
commit 8287baca11
4 changed files with 63 additions and 13 deletions

View file

@ -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::SWidgetConfig> 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

View file

@ -251,9 +251,9 @@ std::vector<std::unique_ptr<IWidget>>* CRenderer::getOrCreateWidgetsFor(const CS
widgets[surf].emplace_back(std::make_unique<CBackground>(surf->size, std::string{"background:"} + std::any_cast<Hyprlang::STRING>(c.values.at("path"))));
if (c.type == "input-field") {
const auto SIZE = std::any_cast<Hyprlang::VEC2>(c.values.at("size"));
widgets[surf].emplace_back(std::make_unique<CPasswordInputField>(surf->size, Vector2D{SIZE.x, SIZE.y}, std::any_cast<Hyprlang::INT>(c.values.at("outer_color")),
std::any_cast<Hyprlang::INT>(c.values.at("inner_color")),
std::any_cast<Hyprlang::INT>(c.values.at("outline_thickness"))));
widgets[surf].emplace_back(std::make_unique<CPasswordInputField>(
surf->size, Vector2D{SIZE.x, SIZE.y}, std::any_cast<Hyprlang::INT>(c.values.at("outer_color")), std::any_cast<Hyprlang::INT>(c.values.at("inner_color")),
std::any_cast<Hyprlang::INT>(c.values.at("outline_thickness")), std::any_cast<Hyprlang::INT>(c.values.at("fade_on_empty"))));
}
}
}

View file

@ -3,12 +3,44 @@
#include "../../core/hyprlock.hpp"
#include <algorithm>
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::microseconds>(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::microseconds>(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;
}

View file

@ -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<dot> dots;
};