Skip to content

Commit

Permalink
input-field: Add fade out timeout #3 (#142)
Browse files Browse the repository at this point in the history
* input-field: add fade out timeout

* input-field: let dots reset themselfs

Now the dots kind of fade into the placeholder text on a failure.

* Nix/HM module: add input-field:fade_timeout option
  • Loading branch information
PaideiaDilemma authored Mar 6, 2024
1 parent 624f497 commit 3d6162e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
7 changes: 7 additions & 0 deletions nix/hm-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ in {
default = true;
};

fade_timeout = mkOption {
description = "Milliseconds before the input field should be faded (0 to fade immediately)";
type = int;
default = 1000;
};

placeholder_text = mkOption {
description = "The placeholder text of the input field";
type = str;
Expand Down Expand Up @@ -367,6 +373,7 @@ in {
inner_color = ${input-field.inner_color}
font_color = ${input-field.font_color}
fade_on_empty = ${boolToString input-field.fade_on_empty}
fade_timeout = ${toString input-field.fade_timeout}
placeholder_text = ${input-field.placeholder_text}
hide_input = ${boolToString input-field.hide_input}
rounding = ${toString input-field.rounding}
Expand Down
2 changes: 2 additions & 0 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void CConfigManager::init() {
m_config.addSpecialConfigValue("input-field", "dots_spacing", Hyprlang::FLOAT{0.2});
m_config.addSpecialConfigValue("input-field", "dots_rounding", Hyprlang::INT{-1});
m_config.addSpecialConfigValue("input-field", "fade_on_empty", Hyprlang::INT{1});
m_config.addSpecialConfigValue("input-field", "fade_timeout", Hyprlang::INT{1000});
m_config.addSpecialConfigValue("input-field", "font_color", Hyprlang::INT{0xFF000000});
m_config.addSpecialConfigValue("input-field", "halign", Hyprlang::STRING{"center"});
m_config.addSpecialConfigValue("input-field", "valign", Hyprlang::STRING{"center"});
Expand Down Expand Up @@ -156,6 +157,7 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
{"dots_center", m_config.getSpecialConfigValue("input-field", "dots_center", k.c_str())},
{"dots_rounding", m_config.getSpecialConfigValue("input-field", "dots_rounding", k.c_str())},
{"fade_on_empty", m_config.getSpecialConfigValue("input-field", "fade_on_empty", k.c_str())},
{"fade_timeout", m_config.getSpecialConfigValue("input-field", "fade_timeout", k.c_str())},
{"font_color", m_config.getSpecialConfigValue("input-field", "font_color", k.c_str())},
{"halign", m_config.getSpecialConfigValue("input-field", "halign", k.c_str())},
{"valign", m_config.getSpecialConfigValue("input-field", "valign", k.c_str())},
Expand Down
47 changes: 36 additions & 11 deletions src/renderer/widgets/PasswordInputField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
dots.center = std::any_cast<Hyprlang::INT>(props.at("dots_center"));
dots.rounding = std::any_cast<Hyprlang::INT>(props.at("dots_rounding"));
fadeOnEmpty = std::any_cast<Hyprlang::INT>(props.at("fade_on_empty"));
fadeTimeoutMs = std::any_cast<Hyprlang::INT>(props.at("fade_timeout"));
font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
pos = std::any_cast<Hyprlang::VEC2>(props.at("position"));
hiddenInputState.enabled = std::any_cast<Hyprlang::INT>(props.at("hide_input"));
Expand All @@ -37,6 +38,21 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
}
}

static void fadeOutCallback(std::shared_ptr<CTimer> self, void* data) {
CPasswordInputField* p = (CPasswordInputField*)data;

p->onFadeOutTimer();

for (auto& o : g_pHyprlock->m_vOutputs) {
o->sessionLockSurface->render();
}
}

void CPasswordInputField::onFadeOutTimer() {
fade.allowFadeOut = true;
fade.fadeOutTimer.reset();
}

void CPasswordInputField::updateFade() {
const auto PASSLEN = g_pHyprlock->getPasswordBufferLen();

Expand All @@ -45,12 +61,26 @@ void CPasswordInputField::updateFade() {
return;
}

if (PASSLEN > 0 && fade.allowFadeOut)
fade.allowFadeOut = false;

if (PASSLEN > 0 && fade.fadeOutTimer.get()) {
fade.fadeOutTimer->cancel();
fade.fadeOutTimer.reset();
}

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)) {
if (fade.allowFadeOut || fadeTimeoutMs == 0) {
fade.a = 1.0;
fade.animated = true;
fade.appearing = false;
fade.start = std::chrono::system_clock::now();
fade.allowFadeOut = false;
} else if (!fade.fadeOutTimer.get())
fade.fadeOutTimer = g_pHyprlock->addTimer(std::chrono::milliseconds(fadeTimeoutMs), fadeOutCallback, this);
}

if (PASSLEN > 0 && fade.a != 1.0 && (!fade.animated || !fade.appearing)) {
fade.a = 0.0;
fade.animated = true;
fade.appearing = true;
Expand Down Expand Up @@ -79,11 +109,6 @@ void CPasswordInputField::updateDots() {
dots.lastFrame = std::chrono::system_clock::now();
}

if (PASSLEN == 0 && !placeholder.failID.empty()) {
dots.currentAmount = PASSLEN;
return;
}

const auto DELTA = std::clamp((int)std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - dots.lastFrame).count(), 0, 20000);

const float TOADD = DELTA / 1000000.0 * dots.speedPerSecond;
Expand Down Expand Up @@ -216,7 +241,7 @@ bool CPasswordInputField::draw(const SRenderData& data) {
forceReload = true;
}

return dots.currentAmount != PASSLEN || data.opacity < 1.0 || forceReload;
return dots.currentAmount != PASSLEN || fade.animated || data.opacity < 1.0 || forceReload;
}

void CPasswordInputField::updateFailTex() {
Expand Down
11 changes: 8 additions & 3 deletions src/renderer/widgets/PasswordInputField.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "IWidget.hpp"
#include "../../helpers/Vector2D.hpp"
#include "../../helpers/Color.hpp"
#include "../../core/Timer.hpp"
#include "Shadowable.hpp"
#include <chrono>
#include <vector>
Expand All @@ -16,6 +17,7 @@ class CPasswordInputField : public IWidget {
CPasswordInputField(const Vector2D& viewport, const std::unordered_map<std::string, std::any>& props);

virtual bool draw(const SRenderData& data);
void onFadeOutTimer();

private:
void updateDots();
Expand Down Expand Up @@ -45,9 +47,11 @@ class CPasswordInputField : public IWidget {

struct {
std::chrono::system_clock::time_point start;
float a = 0;
bool appearing = true;
bool animated = false;
float a = 0;
bool appearing = true;
bool animated = false;
std::shared_ptr<CTimer> fadeOutTimer = nullptr;
bool allowFadeOut = false;
} fade;

struct {
Expand All @@ -67,6 +71,7 @@ class CPasswordInputField : public IWidget {
} hiddenInputState;

bool fadeOnEmpty;
uint64_t fadeTimeoutMs;

CShadowable shadow;
};

0 comments on commit 3d6162e

Please sign in to comment.