mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-12-22 13:29:48 +01:00
input-field: refactor updateColors and other improvements (#469)
* input-field: refactor updateColors * input-field: fix input-field:invert_numlock * input-field: use updatePlaceholder to request the initial placeholder asset * input-field: allow more gradual color animations * input-field: fix caps and num indicator colors, when borderless and swap_font_color is true
This commit is contained in:
parent
7bb4113a7e
commit
a0af542f9b
2 changed files with 95 additions and 139 deletions
|
@ -1,7 +1,7 @@
|
||||||
#include "PasswordInputField.hpp"
|
#include "PasswordInputField.hpp"
|
||||||
#include "../Renderer.hpp"
|
#include "../Renderer.hpp"
|
||||||
#include "../../core/hyprlock.hpp"
|
#include "../../core/hyprlock.hpp"
|
||||||
#include "src/core/Auth.hpp"
|
#include "../../core/Auth.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
static void replaceAll(std::string& str, const std::string& from, const std::string& to) {
|
static void replaceAll(std::string& str, const std::string& from, const std::string& to) {
|
||||||
|
@ -29,17 +29,17 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
||||||
configPlaceholderText = std::any_cast<Hyprlang::STRING>(props.at("placeholder_text"));
|
configPlaceholderText = std::any_cast<Hyprlang::STRING>(props.at("placeholder_text"));
|
||||||
configFailText = std::any_cast<Hyprlang::STRING>(props.at("fail_text"));
|
configFailText = std::any_cast<Hyprlang::STRING>(props.at("fail_text"));
|
||||||
configFailTimeoutMs = std::any_cast<Hyprlang::INT>(props.at("fail_timeout"));
|
configFailTimeoutMs = std::any_cast<Hyprlang::INT>(props.at("fail_timeout"));
|
||||||
col.transitionMs = std::any_cast<Hyprlang::INT>(props.at("fail_transition"));
|
colorConfig.transitionMs = std::any_cast<Hyprlang::INT>(props.at("fail_transition"));
|
||||||
col.outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
colorConfig.outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
||||||
col.inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
colorConfig.inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
||||||
col.font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
|
colorConfig.font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
|
||||||
col.fail = std::any_cast<Hyprlang::INT>(props.at("fail_color"));
|
colorConfig.fail = std::any_cast<Hyprlang::INT>(props.at("fail_color"));
|
||||||
col.check = std::any_cast<Hyprlang::INT>(props.at("check_color"));
|
colorConfig.check = std::any_cast<Hyprlang::INT>(props.at("check_color"));
|
||||||
col.both = std::any_cast<Hyprlang::INT>(props.at("bothlock_color"));
|
colorConfig.both = std::any_cast<Hyprlang::INT>(props.at("bothlock_color"));
|
||||||
col.caps = std::any_cast<Hyprlang::INT>(props.at("capslock_color"));
|
colorConfig.caps = std::any_cast<Hyprlang::INT>(props.at("capslock_color"));
|
||||||
col.num = std::any_cast<Hyprlang::INT>(props.at("numlock_color"));
|
colorConfig.num = std::any_cast<Hyprlang::INT>(props.at("numlock_color"));
|
||||||
col.invertNum = std::any_cast<Hyprlang::INT>(props.at("invert_numlock"));
|
colorConfig.invertNum = std::any_cast<Hyprlang::INT>(props.at("invert_numlock"));
|
||||||
col.swapFont = std::any_cast<Hyprlang::INT>(props.at("swap_font_color"));
|
colorConfig.swapFont = std::any_cast<Hyprlang::INT>(props.at("swap_font_color"));
|
||||||
viewport = viewport_;
|
viewport = viewport_;
|
||||||
|
|
||||||
auto POS__ = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
auto POS__ = std::any_cast<Hyprlang::VEC2>(props.at("position"));
|
||||||
|
@ -53,31 +53,18 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
||||||
pos = posFromHVAlign(viewport, size, pos, halign, valign);
|
pos = posFromHVAlign(viewport, size, pos, halign, valign);
|
||||||
dots.size = std::clamp(dots.size, 0.2f, 0.8f);
|
dots.size = std::clamp(dots.size, 0.2f, 0.8f);
|
||||||
dots.spacing = std::clamp(dots.spacing, 0.f, 1.f);
|
dots.spacing = std::clamp(dots.spacing, 0.f, 1.f);
|
||||||
col.transitionMs = std::clamp(col.transitionMs, 0, 1000);
|
colorConfig.transitionMs = std::clamp(colorConfig.transitionMs, 0, 1000);
|
||||||
|
|
||||||
col.both = col.both == -1 ? col.outer : col.both;
|
colorConfig.both = colorConfig.both == -1 ? colorConfig.outer : colorConfig.both;
|
||||||
col.caps = col.caps == -1 ? col.outer : col.caps;
|
colorConfig.caps = colorConfig.caps == -1 ? colorConfig.outer : colorConfig.caps;
|
||||||
col.num = col.num == -1 ? col.outer : col.num;
|
colorConfig.num = colorConfig.num == -1 ? colorConfig.outer : colorConfig.num;
|
||||||
|
|
||||||
g_pHyprlock->m_bNumLock = col.invertNum;
|
colorState.inner = colorConfig.inner;
|
||||||
|
colorState.outer = colorConfig.outer;
|
||||||
|
colorState.font = colorConfig.font;
|
||||||
|
|
||||||
// Render placeholder if either placeholder_text or fail_text are non-empty
|
// request the inital placeholder asset
|
||||||
// as placeholder must be rendered to show fail_text
|
updatePlaceholder();
|
||||||
if (!configPlaceholderText.empty() || !configFailText.empty()) {
|
|
||||||
placeholder.currentText = configPlaceholderText;
|
|
||||||
|
|
||||||
replaceAll(placeholder.currentText, "$PROMPT", "");
|
|
||||||
|
|
||||||
placeholder.resourceID = "placeholder:" + placeholder.currentText + std::to_string((uintptr_t)this);
|
|
||||||
CAsyncResourceGatherer::SPreloadRequest request;
|
|
||||||
request.id = placeholder.resourceID;
|
|
||||||
request.asset = placeholder.currentText;
|
|
||||||
request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT;
|
|
||||||
request.props["font_family"] = std::string{"Sans"};
|
|
||||||
request.props["color"] = CColor{1.0 - col.font.r, 1.0 - col.font.g, 1.0 - col.font.b, 0.5};
|
|
||||||
request.props["font_size"] = (int)size.y / 4;
|
|
||||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fadeOutCallback(std::shared_ptr<CTimer> self, void* data) {
|
static void fadeOutCallback(std::shared_ptr<CTimer> self, void* data) {
|
||||||
|
@ -180,11 +167,12 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
|
|
||||||
passwordLength = g_pHyprlock->getPasswordBufferDisplayLen();
|
passwordLength = g_pHyprlock->getPasswordBufferDisplayLen();
|
||||||
checkWaiting = g_pAuth->checkWaiting();
|
checkWaiting = g_pAuth->checkWaiting();
|
||||||
|
displayFail = g_pAuth->m_bDisplayFailText;
|
||||||
|
|
||||||
updateFade();
|
updateFade();
|
||||||
updateDots();
|
updateDots();
|
||||||
updatePlaceholder();
|
|
||||||
updateColors();
|
updateColors();
|
||||||
|
updatePlaceholder();
|
||||||
updateHiddenInputState();
|
updateHiddenInputState();
|
||||||
|
|
||||||
static auto TIMER = std::chrono::system_clock::now();
|
static auto TIMER = std::chrono::system_clock::now();
|
||||||
|
@ -215,11 +203,11 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
shadowData.opacity *= fade.a;
|
shadowData.opacity *= fade.a;
|
||||||
shadow.draw(shadowData);
|
shadow.draw(shadowData);
|
||||||
|
|
||||||
CColor outerCol = col.outer;
|
CColor outerCol = colorState.outer;
|
||||||
outerCol.a *= fade.a * data.opacity;
|
outerCol.a *= fade.a * data.opacity;
|
||||||
CColor innerCol = col.inner;
|
CColor innerCol = colorState.inner;
|
||||||
innerCol.a *= fade.a * data.opacity;
|
innerCol.a *= fade.a * data.opacity;
|
||||||
CColor fontCol = col.font;
|
CColor fontCol = colorState.font;
|
||||||
fontCol.a *= fade.a * data.opacity;
|
fontCol.a *= fade.a * data.opacity;
|
||||||
|
|
||||||
if (outThick > 0) {
|
if (outThick > 0) {
|
||||||
|
@ -302,7 +290,7 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
forceReload = true;
|
forceReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dots.currentAmount != passwordLength || fade.animated || col.animated || redrawShadow || data.opacity < 1.0 || forceReload;
|
return dots.currentAmount != passwordLength || fade.animated || colorState.animated || redrawShadow || data.opacity < 1.0 || forceReload;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void failTimeoutCallback(std::shared_ptr<CTimer> self, void* data) {
|
static void failTimeoutCallback(std::shared_ptr<CTimer> self, void* data) {
|
||||||
|
@ -312,7 +300,7 @@ static void failTimeoutCallback(std::shared_ptr<CTimer> self, void* data) {
|
||||||
|
|
||||||
void CPasswordInputField::updatePlaceholder() {
|
void CPasswordInputField::updatePlaceholder() {
|
||||||
if (passwordLength != 0) {
|
if (passwordLength != 0) {
|
||||||
if (placeholder.asset && /* keep prompt asset cause it is likely to be used again */ placeholder.isFailText) {
|
if (placeholder.asset && /* keep prompt asset cause it is likely to be used again */ displayFail) {
|
||||||
std::erase(placeholder.registeredResourceIDs, placeholder.resourceID);
|
std::erase(placeholder.registeredResourceIDs, placeholder.resourceID);
|
||||||
g_pRenderer->asyncResourceGatherer->unloadAsset(placeholder.asset);
|
g_pRenderer->asyncResourceGatherer->unloadAsset(placeholder.asset);
|
||||||
placeholder.asset = nullptr;
|
placeholder.asset = nullptr;
|
||||||
|
@ -323,17 +311,17 @@ void CPasswordInputField::updatePlaceholder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto AUTHFEEDBACK = g_pAuth->m_bDisplayFailText ? g_pAuth->getLastFailText().value_or("Ups, no fail text?") : g_pAuth->getLastPrompt().value_or("Ups, no prompt?");
|
const auto AUTHFEEDBACK = g_pAuth->m_bDisplayFailText ? g_pAuth->getLastFailText().value_or("Ups, no fail text?") : g_pAuth->getLastPrompt().value_or("Ups, no prompt?");
|
||||||
|
const auto ALLOWCOLORSWAP = outThick == 0 && colorConfig.swapFont;
|
||||||
|
|
||||||
if (placeholder.lastAuthFeedback == AUTHFEEDBACK && g_pHyprlock->getPasswordFailedAttempts() == placeholder.failedAttempts)
|
if (!ALLOWCOLORSWAP && placeholder.lastAuthFeedback == AUTHFEEDBACK && g_pHyprlock->getPasswordFailedAttempts() == placeholder.failedAttempts)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
placeholder.failedAttempts = g_pHyprlock->getPasswordFailedAttempts();
|
placeholder.failedAttempts = g_pHyprlock->getPasswordFailedAttempts();
|
||||||
placeholder.isFailText = g_pAuth->m_bDisplayFailText;
|
|
||||||
placeholder.lastAuthFeedback = AUTHFEEDBACK;
|
placeholder.lastAuthFeedback = AUTHFEEDBACK;
|
||||||
|
|
||||||
placeholder.asset = nullptr;
|
placeholder.asset = nullptr;
|
||||||
|
|
||||||
if (placeholder.isFailText) {
|
if (displayFail) {
|
||||||
g_pHyprlock->addTimer(std::chrono::milliseconds(configFailTimeoutMs), failTimeoutCallback, nullptr);
|
g_pHyprlock->addTimer(std::chrono::milliseconds(configFailTimeoutMs), failTimeoutCallback, nullptr);
|
||||||
placeholder.currentText = configFailText;
|
placeholder.currentText = configFailText;
|
||||||
replaceAll(placeholder.currentText, "$FAIL", AUTHFEEDBACK);
|
replaceAll(placeholder.currentText, "$FAIL", AUTHFEEDBACK);
|
||||||
|
@ -343,7 +331,9 @@ void CPasswordInputField::updatePlaceholder() {
|
||||||
replaceAll(placeholder.currentText, "$PROMPT", AUTHFEEDBACK);
|
replaceAll(placeholder.currentText, "$PROMPT", AUTHFEEDBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
placeholder.resourceID = "placeholder:" + placeholder.currentText + std::to_string((uintptr_t)this);
|
placeholder.resourceID =
|
||||||
|
std::format("placeholder:{}{}{}{}{}{}", placeholder.currentText, (uintptr_t)this, colorState.font.r, colorState.font.g, colorState.font.b, colorState.font.a);
|
||||||
|
|
||||||
if (std::find(placeholder.registeredResourceIDs.begin(), placeholder.registeredResourceIDs.end(), placeholder.resourceID) != placeholder.registeredResourceIDs.end())
|
if (std::find(placeholder.registeredResourceIDs.begin(), placeholder.registeredResourceIDs.end(), placeholder.resourceID) != placeholder.registeredResourceIDs.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -355,7 +345,7 @@ void CPasswordInputField::updatePlaceholder() {
|
||||||
request.asset = placeholder.currentText;
|
request.asset = placeholder.currentText;
|
||||||
request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT;
|
request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT;
|
||||||
request.props["font_family"] = std::string{"Sans"};
|
request.props["font_family"] = std::string{"Sans"};
|
||||||
request.props["color"] = (placeholder.isFailText) ? col.fail : col.font;
|
request.props["color"] = colorState.font;
|
||||||
request.props["font_size"] = (int)size.y / 4;
|
request.props["font_size"] = (int)size.y / 4;
|
||||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||||
}
|
}
|
||||||
|
@ -409,104 +399,60 @@ static void changeColor(const CColor& source, const CColor& target, CColor& subj
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPasswordInputField::updateColors() {
|
void CPasswordInputField::updateColors() {
|
||||||
static auto OUTER = col.outer, TARGET = OUTER, SOURCE = OUTER;
|
|
||||||
static auto INNER = col.inner, ITARGET = INNER, ISOURCE = INNER;
|
|
||||||
static auto FONT = col.font, FTARGET = FONT, FSOURCE = FONT;
|
|
||||||
|
|
||||||
const bool BORDERLESS = outThick == 0;
|
const bool BORDERLESS = outThick == 0;
|
||||||
|
const bool NUMLOCK = g_pHyprlock->m_bNumLock || (colorConfig.invertNum && !g_pHyprlock->m_bNumLock);
|
||||||
if (col.animated) {
|
const auto MULTI = colorConfig.transitionMs == 0 ?
|
||||||
// some cases when events happen too quick (within transitionMs)
|
|
||||||
// TODO: find more?
|
|
||||||
const bool LOCKCHANGED = col.stateNum != (col.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock) || col.stateCaps != g_pHyprlock->m_bCapsLock;
|
|
||||||
const bool ANIMONCHECK = checkWaiting && (TARGET == (BORDERLESS ? INNER : OUTER) || TARGET == col.fail);
|
|
||||||
|
|
||||||
if (LOCKCHANGED || ANIMONCHECK) {
|
|
||||||
const bool EQUALCOLORS = ANIMONCHECK && OUTER == col.check;
|
|
||||||
// to avoid throttle when check_color set to the same as outer.
|
|
||||||
SOURCE = BORDERLESS ? (EQUALCOLORS ? INNER : col.inner) : col.outer;
|
|
||||||
FSOURCE = EQUALCOLORS ? FONT : col.font;
|
|
||||||
ISOURCE = EQUALCOLORS ? INNER : col.inner;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SOURCE = BORDERLESS ? col.inner : col.outer;
|
|
||||||
FSOURCE = col.font;
|
|
||||||
ISOURCE = col.inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
col.stateNum = col.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock;
|
|
||||||
col.stateCaps = g_pHyprlock->m_bCapsLock;
|
|
||||||
|
|
||||||
if (!placeholder.isFailText || passwordLength > 0 || (passwordLength == 0 && checkWaiting)) {
|
|
||||||
if (g_pHyprlock->m_bFadeStarted) {
|
|
||||||
if (TARGET == col.check)
|
|
||||||
SOURCE = BORDERLESS ? col.inner : col.outer;
|
|
||||||
col.transitionMs = 100;
|
|
||||||
TARGET = BORDERLESS ? INNER : OUTER;
|
|
||||||
} else if (checkWaiting) {
|
|
||||||
FTARGET = col.swapFont ? INNER : FONT;
|
|
||||||
const float PASSALPHA = FTARGET.a * 0.5;
|
|
||||||
FTARGET.a = PASSALPHA;
|
|
||||||
|
|
||||||
TARGET = col.check;
|
|
||||||
ITARGET = col.swapFont ? FONT : INNER;
|
|
||||||
} else if (col.stateCaps && col.stateNum && col.both != OUTER) {
|
|
||||||
TARGET = col.both;
|
|
||||||
FTARGET = col.swapFont && BORDERLESS ? INNER : FONT;
|
|
||||||
} else if (col.stateCaps && col.caps != OUTER) {
|
|
||||||
TARGET = col.caps;
|
|
||||||
FTARGET = col.swapFont && BORDERLESS ? INNER : FONT;
|
|
||||||
} else if (col.stateNum && col.num != OUTER) {
|
|
||||||
TARGET = col.num;
|
|
||||||
FTARGET = col.swapFont && BORDERLESS ? INNER : FONT;
|
|
||||||
} else {
|
|
||||||
// if quickly pressed after failure
|
|
||||||
if (col.animated && TARGET == col.fail)
|
|
||||||
SOURCE = BORDERLESS ? col.inner : col.outer;
|
|
||||||
|
|
||||||
TARGET = BORDERLESS ? INNER : OUTER;
|
|
||||||
FTARGET = FONT;
|
|
||||||
ITARGET = INNER;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FSOURCE = col.swapFont ? INNER : FONT;
|
|
||||||
const float PASSALPHA = FSOURCE.a * 0.5;
|
|
||||||
FSOURCE.a = PASSALPHA;
|
|
||||||
FTARGET = FONT;
|
|
||||||
|
|
||||||
SOURCE = col.check;
|
|
||||||
TARGET = col.fail;
|
|
||||||
ISOURCE = FONT;
|
|
||||||
ITARGET = FONT;
|
|
||||||
|
|
||||||
if (fade.animated || fade.a < 1.0) {
|
|
||||||
TARGET = BORDERLESS ? INNER : OUTER;
|
|
||||||
SOURCE = col.fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
col.animated = false;
|
|
||||||
|
|
||||||
const bool SWAPDONE = !BORDERLESS && col.swapFont ? col.inner == ITARGET : true;
|
|
||||||
|
|
||||||
if ((BORDERLESS ? col.inner : col.outer) == TARGET && col.font == FTARGET && SWAPDONE) {
|
|
||||||
col.shouldStart = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col.shouldStart) {
|
|
||||||
col.lastFrame = std::chrono::system_clock::now();
|
|
||||||
col.shouldStart = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto MULTI = col.transitionMs == 0 ?
|
|
||||||
1.0 :
|
1.0 :
|
||||||
std::clamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - col.lastFrame).count() / (double)col.transitionMs, 0.016, 0.5);
|
std::clamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - colorState.lastFrame).count() / (double)colorConfig.transitionMs,
|
||||||
|
0.0016, 0.5);
|
||||||
|
|
||||||
changeColor(SOURCE, TARGET, (BORDERLESS ? col.inner : col.outer), MULTI, col.animated);
|
CColor targetColor;
|
||||||
changeColor(FSOURCE, FTARGET, col.font, MULTI, col.animated);
|
|
||||||
if (col.swapFont && !BORDERLESS)
|
|
||||||
changeColor(ISOURCE, ITARGET, col.inner, MULTI, col.animated);
|
|
||||||
|
|
||||||
col.lastFrame = std::chrono::system_clock::now();
|
if (checkWaiting) {
|
||||||
|
targetColor = colorConfig.check;
|
||||||
|
} else if (displayFail) {
|
||||||
|
targetColor = colorConfig.fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_pHyprlock->m_bCapsLock && NUMLOCK) {
|
||||||
|
targetColor = colorConfig.both;
|
||||||
|
} else if (g_pHyprlock->m_bCapsLock) {
|
||||||
|
targetColor = colorConfig.caps;
|
||||||
|
} else if (NUMLOCK) {
|
||||||
|
targetColor = colorConfig.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor outerTarget = colorConfig.outer;
|
||||||
|
CColor innerTarget = colorConfig.inner;
|
||||||
|
CColor fontTarget = (displayFail) ? colorConfig.fail : colorConfig.font;
|
||||||
|
|
||||||
|
if (checkWaiting || displayFail || g_pHyprlock->m_bCapsLock || NUMLOCK) {
|
||||||
|
if (BORDERLESS && colorConfig.swapFont) {
|
||||||
|
fontTarget = targetColor;
|
||||||
|
} else if (BORDERLESS && !colorConfig.swapFont) {
|
||||||
|
innerTarget = targetColor;
|
||||||
|
// When changing the inner color the font cannot be fail_color
|
||||||
|
fontTarget = colorConfig.font;
|
||||||
|
} else {
|
||||||
|
outerTarget = targetColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetColor != colorState.currentTarget) {
|
||||||
|
colorState.outerSource = colorState.outer;
|
||||||
|
colorState.innerSource = colorState.inner;
|
||||||
|
|
||||||
|
colorState.currentTarget = targetColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
colorState.animated = false;
|
||||||
|
|
||||||
|
changeColor(colorState.outerSource, outerTarget, colorState.outer, MULTI, colorState.animated);
|
||||||
|
changeColor(colorState.innerSource, innerTarget, colorState.inner, MULTI, colorState.animated);
|
||||||
|
|
||||||
|
// Font color is only chaned, when `swap_font_color` is set to true and no boarder is present.
|
||||||
|
// It is not animated, because that does not look good and we would need to rerender the text for each frame.
|
||||||
|
colorState.font = fontTarget;
|
||||||
|
|
||||||
|
colorState.lastFrame = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,13 @@ class CPasswordInputField : public IWidget {
|
||||||
void updateFade();
|
void updateFade();
|
||||||
void updatePlaceholder();
|
void updatePlaceholder();
|
||||||
void updateHiddenInputState();
|
void updateHiddenInputState();
|
||||||
|
void updateInputState();
|
||||||
void updateColors();
|
void updateColors();
|
||||||
|
|
||||||
bool firstRender = true;
|
bool firstRender = true;
|
||||||
bool redrawShadow = false;
|
bool redrawShadow = false;
|
||||||
bool checkWaiting = false;
|
bool checkWaiting = false;
|
||||||
|
bool displayFail = false;
|
||||||
|
|
||||||
size_t passwordLength = 0;
|
size_t passwordLength = 0;
|
||||||
|
|
||||||
|
@ -69,7 +71,6 @@ class CPasswordInputField : public IWidget {
|
||||||
std::string currentText = "";
|
std::string currentText = "";
|
||||||
size_t failedAttempts = 0;
|
size_t failedAttempts = 0;
|
||||||
bool canGetNewText = true;
|
bool canGetNewText = true;
|
||||||
bool isFailText = false;
|
|
||||||
|
|
||||||
std::string lastAuthFeedback;
|
std::string lastAuthFeedback;
|
||||||
|
|
||||||
|
@ -96,15 +97,24 @@ class CPasswordInputField : public IWidget {
|
||||||
|
|
||||||
int transitionMs = 0;
|
int transitionMs = 0;
|
||||||
bool invertNum = false;
|
bool invertNum = false;
|
||||||
bool animated = false;
|
|
||||||
bool stateNum = false;
|
|
||||||
bool stateCaps = false;
|
|
||||||
bool swapFont = false;
|
bool swapFont = false;
|
||||||
bool shouldStart;
|
} colorConfig;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
CColor outer;
|
||||||
|
CColor inner;
|
||||||
|
CColor font;
|
||||||
|
|
||||||
|
CColor outerSource;
|
||||||
|
CColor innerSource;
|
||||||
|
|
||||||
|
CColor currentTarget;
|
||||||
|
|
||||||
|
bool animated = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
std::chrono::system_clock::time_point lastFrame;
|
std::chrono::system_clock::time_point lastFrame;
|
||||||
} col;
|
} colorState;
|
||||||
|
|
||||||
bool fadeOnEmpty;
|
bool fadeOnEmpty;
|
||||||
uint64_t fadeTimeoutMs;
|
uint64_t fadeTimeoutMs;
|
||||||
|
|
Loading…
Reference in a new issue