2024-02-19 00:08:03 +01:00
|
|
|
#include "PasswordInputField.hpp"
|
|
|
|
#include "../Renderer.hpp"
|
|
|
|
#include "../../core/hyprlock.hpp"
|
|
|
|
#include <algorithm>
|
|
|
|
|
2024-02-19 23:39:13 +01:00
|
|
|
CPasswordInputField::CPasswordInputField(const Vector2D& viewport, const std::unordered_map<std::string, std::any>& props) {
|
|
|
|
size = std::any_cast<Hyprlang::VEC2>(props.at("size"));
|
|
|
|
inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
|
|
|
outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
|
|
|
out_thick = std::any_cast<Hyprlang::INT>(props.at("outline_thickness"));
|
|
|
|
fadeOnEmpty = std::any_cast<Hyprlang::INT>(props.at("fade_on_empty"));
|
|
|
|
font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
|
2024-02-19 23:45:59 +01:00
|
|
|
pos = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
|
|
|
|
|
|
|
pos = posFromHVAlign(viewport, size, pos, std::any_cast<Hyprlang::STRING>(props.at("halign")), std::any_cast<Hyprlang::STRING>(props.at("valign")));
|
2024-02-19 02:22:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2024-02-19 00:08:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CPasswordInputField::updateDots() {
|
|
|
|
const auto PASSLEN = g_pHyprlock->getPasswordBufferLen();
|
|
|
|
|
2024-02-19 22:09:00 +01:00
|
|
|
if (PASSLEN == dots.currentAmount)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const auto DELTA = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - dots.lastFrame).count();
|
|
|
|
|
|
|
|
const float TOADD = DELTA / 1000000.0 * (dots.speedPerSecond * std::clamp(std::abs(PASSLEN - dots.currentAmount), 0.5f, INFINITY));
|
2024-02-19 00:08:03 +01:00
|
|
|
|
2024-02-19 22:09:00 +01:00
|
|
|
if (PASSLEN > dots.currentAmount) {
|
|
|
|
dots.currentAmount += TOADD;
|
|
|
|
if (dots.currentAmount > PASSLEN)
|
|
|
|
dots.currentAmount = PASSLEN;
|
|
|
|
} else if (PASSLEN < dots.currentAmount) {
|
|
|
|
dots.currentAmount -= TOADD;
|
|
|
|
if (dots.currentAmount < PASSLEN)
|
|
|
|
dots.currentAmount = PASSLEN;
|
2024-02-19 00:08:03 +01:00
|
|
|
}
|
|
|
|
|
2024-02-19 22:09:00 +01:00
|
|
|
dots.lastFrame = std::chrono::system_clock::now();
|
2024-02-19 00:08:03 +01:00
|
|
|
}
|
|
|
|
|
2024-02-19 17:26:08 +01:00
|
|
|
bool CPasswordInputField::draw(const SRenderData& data) {
|
2024-02-19 00:08:03 +01:00
|
|
|
CBox inputFieldBox = {pos, size};
|
|
|
|
CBox outerBox = {pos - Vector2D{out_thick, out_thick}, size + Vector2D{out_thick * 2, out_thick * 2}};
|
|
|
|
|
2024-02-19 02:22:22 +01:00
|
|
|
updateFade();
|
2024-02-19 00:08:03 +01:00
|
|
|
updateDots();
|
|
|
|
|
2024-02-19 02:22:22 +01:00
|
|
|
CColor outerCol = outer;
|
2024-02-19 17:26:08 +01:00
|
|
|
outer.a = fade.a * data.opacity;
|
2024-02-19 02:22:22 +01:00
|
|
|
CColor innerCol = inner;
|
2024-02-19 17:26:08 +01:00
|
|
|
innerCol.a = fade.a * data.opacity;
|
2024-02-19 02:22:22 +01:00
|
|
|
|
|
|
|
g_pRenderer->renderRect(outerBox, outerCol, outerBox.h / 2.0);
|
|
|
|
g_pRenderer->renderRect(inputFieldBox, innerCol, inputFieldBox.h / 2.0);
|
2024-02-19 00:08:03 +01:00
|
|
|
|
|
|
|
constexpr int PASS_SPACING = 3;
|
|
|
|
constexpr int PASS_SIZE = 8;
|
|
|
|
|
2024-02-19 22:09:00 +01:00
|
|
|
for (size_t i = 0; i < std::floor(dots.currentAmount); ++i) {
|
|
|
|
Vector2D currentPos = inputFieldBox.pos() + Vector2D{PASS_SPACING * 2, inputFieldBox.h / 2.f - PASS_SIZE / 2.f} + Vector2D{(PASS_SIZE + PASS_SPACING) * i, 0};
|
2024-02-19 00:08:03 +01:00
|
|
|
CBox box{currentPos, Vector2D{PASS_SIZE, PASS_SIZE}};
|
2024-02-19 23:39:13 +01:00
|
|
|
CColor fontCol = font;
|
2024-02-19 23:35:13 +01:00
|
|
|
g_pRenderer->renderRect(box, fontCol, PASS_SIZE / 2.0);
|
2024-02-19 00:08:03 +01:00
|
|
|
}
|
|
|
|
|
2024-02-19 22:09:00 +01:00
|
|
|
if (dots.currentAmount != std::floor(dots.currentAmount)) {
|
|
|
|
Vector2D currentPos =
|
|
|
|
inputFieldBox.pos() + Vector2D{PASS_SPACING * 2, inputFieldBox.h / 2.f - PASS_SIZE / 2.f} + Vector2D{(PASS_SIZE + PASS_SPACING) * std::floor(dots.currentAmount), 0};
|
2024-02-19 23:39:13 +01:00
|
|
|
CBox box{currentPos, Vector2D{PASS_SIZE, PASS_SIZE}};
|
2024-02-19 23:35:13 +01:00
|
|
|
CColor fontCol = font;
|
|
|
|
fontCol.a = (dots.currentAmount - std::floor(dots.currentAmount)) * data.opacity;
|
|
|
|
g_pRenderer->renderRect(box, fontCol, PASS_SIZE / 2.0);
|
2024-02-19 22:09:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const auto PASSLEN = g_pHyprlock->getPasswordBufferLen();
|
|
|
|
|
|
|
|
return dots.currentAmount != PASSLEN || data.opacity < 1.0 || fade.a < 1.0;
|
2024-02-19 00:08:03 +01:00
|
|
|
}
|