mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-12-22 13:29:48 +01:00
input-field: new color features (#201)
* input-field: new color features * add nix HM * add workaround for faillasset not being shown on empty imput * comment * change cfg option name * remove TODO * small fix * one more edge check * dedup changeColor function * simplify more
This commit is contained in:
parent
1356f113cc
commit
1bf6ffdbe2
4 changed files with 157 additions and 103 deletions
|
@ -407,6 +407,12 @@ in {
|
||||||
type = bool;
|
type = bool;
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
swap_font_color = mkOption {
|
||||||
|
description = "Whether to swap font color with inner color on some events";
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// shadow;
|
// shadow;
|
||||||
});
|
});
|
||||||
|
@ -557,6 +563,7 @@ in {
|
||||||
numlock_color = ${input-field.numlock_color}
|
numlock_color = ${input-field.numlock_color}
|
||||||
bothlock_color = ${input-field.bothlock_color}
|
bothlock_color = ${input-field.bothlock_color}
|
||||||
invert_numlock = ${boolToString input-field.invert_numlock}
|
invert_numlock = ${boolToString input-field.invert_numlock}
|
||||||
|
swap_font_color = ${boolToString input-field.swap_font_color}
|
||||||
|
|
||||||
position = ${toString input-field.position.x}, ${toString input-field.position.y}
|
position = ${toString input-field.position.x}, ${toString input-field.position.y}
|
||||||
halign = ${input-field.halign}
|
halign = ${input-field.halign}
|
||||||
|
|
|
@ -100,6 +100,7 @@ void CConfigManager::init() {
|
||||||
m_config.addSpecialConfigValue("input-field", "numlock_color", Hyprlang::INT{-1});
|
m_config.addSpecialConfigValue("input-field", "numlock_color", Hyprlang::INT{-1});
|
||||||
m_config.addSpecialConfigValue("input-field", "bothlock_color", Hyprlang::INT{-1});
|
m_config.addSpecialConfigValue("input-field", "bothlock_color", Hyprlang::INT{-1});
|
||||||
m_config.addSpecialConfigValue("input-field", "invert_numlock", Hyprlang::INT{0});
|
m_config.addSpecialConfigValue("input-field", "invert_numlock", Hyprlang::INT{0});
|
||||||
|
m_config.addSpecialConfigValue("input-field", "swap_font_color", Hyprlang::INT{0});
|
||||||
SHADOWABLE("input-field");
|
SHADOWABLE("input-field");
|
||||||
|
|
||||||
m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
m_config.addSpecialCategory("label", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||||
|
@ -218,6 +219,7 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
||||||
{"numlock_color", m_config.getSpecialConfigValue("input-field", "numlock_color", k.c_str())},
|
{"numlock_color", m_config.getSpecialConfigValue("input-field", "numlock_color", k.c_str())},
|
||||||
{"bothlock_color", m_config.getSpecialConfigValue("input-field", "bothlock_color", k.c_str())},
|
{"bothlock_color", m_config.getSpecialConfigValue("input-field", "bothlock_color", k.c_str())},
|
||||||
{"invert_numlock", m_config.getSpecialConfigValue("input-field", "invert_numlock", k.c_str())},
|
{"invert_numlock", m_config.getSpecialConfigValue("input-field", "invert_numlock", k.c_str())},
|
||||||
|
{"swap_font_color", m_config.getSpecialConfigValue("input-field", "swap_font_color", k.c_str())},
|
||||||
SHADOWABLE("input-field"),
|
SHADOWABLE("input-field"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) : shadow(this, props, viewport_) {
|
CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::unordered_map<std::string, std::any>& props) : shadow(this, props, viewport_) {
|
||||||
size = std::any_cast<Hyprlang::VEC2>(props.at("size"));
|
size = std::any_cast<Hyprlang::VEC2>(props.at("size"));
|
||||||
inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
|
||||||
outThick = std::any_cast<Hyprlang::INT>(props.at("outline_thickness"));
|
outThick = std::any_cast<Hyprlang::INT>(props.at("outline_thickness"));
|
||||||
dots.size = std::any_cast<Hyprlang::FLOAT>(props.at("dots_size"));
|
dots.size = std::any_cast<Hyprlang::FLOAT>(props.at("dots_size"));
|
||||||
dots.spacing = std::any_cast<Hyprlang::FLOAT>(props.at("dots_spacing"));
|
dots.spacing = std::any_cast<Hyprlang::FLOAT>(props.at("dots_spacing"));
|
||||||
|
@ -13,18 +12,20 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
||||||
dots.rounding = std::any_cast<Hyprlang::INT>(props.at("dots_rounding"));
|
dots.rounding = std::any_cast<Hyprlang::INT>(props.at("dots_rounding"));
|
||||||
fadeOnEmpty = std::any_cast<Hyprlang::INT>(props.at("fade_on_empty"));
|
fadeOnEmpty = std::any_cast<Hyprlang::INT>(props.at("fade_on_empty"));
|
||||||
fadeTimeoutMs = std::any_cast<Hyprlang::INT>(props.at("fade_timeout"));
|
fadeTimeoutMs = std::any_cast<Hyprlang::INT>(props.at("fade_timeout"));
|
||||||
font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
|
|
||||||
hiddenInputState.enabled = std::any_cast<Hyprlang::INT>(props.at("hide_input"));
|
hiddenInputState.enabled = std::any_cast<Hyprlang::INT>(props.at("hide_input"));
|
||||||
rounding = std::any_cast<Hyprlang::INT>(props.at("rounding"));
|
rounding = std::any_cast<Hyprlang::INT>(props.at("rounding"));
|
||||||
configFailText = std::any_cast<Hyprlang::STRING>(props.at("fail_text"));
|
configFailText = std::any_cast<Hyprlang::STRING>(props.at("fail_text"));
|
||||||
outerColor.transitionMs = std::any_cast<Hyprlang::INT>(props.at("fail_transition"));
|
col.transitionMs = std::any_cast<Hyprlang::INT>(props.at("fail_transition"));
|
||||||
outerColor.main = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
col.outer = std::any_cast<Hyprlang::INT>(props.at("outer_color"));
|
||||||
outerColor.fail = std::any_cast<Hyprlang::INT>(props.at("fail_color"));
|
col.inner = std::any_cast<Hyprlang::INT>(props.at("inner_color"));
|
||||||
outerColor.check = std::any_cast<Hyprlang::INT>(props.at("check_color"));
|
col.font = std::any_cast<Hyprlang::INT>(props.at("font_color"));
|
||||||
outerColor.both = std::any_cast<Hyprlang::INT>(props.at("bothlock_color"));
|
col.fail = std::any_cast<Hyprlang::INT>(props.at("fail_color"));
|
||||||
outerColor.caps = std::any_cast<Hyprlang::INT>(props.at("capslock_color"));
|
col.check = std::any_cast<Hyprlang::INT>(props.at("check_color"));
|
||||||
outerColor.num = std::any_cast<Hyprlang::INT>(props.at("numlock_color"));
|
col.both = std::any_cast<Hyprlang::INT>(props.at("bothlock_color"));
|
||||||
outerColor.invertNum = std::any_cast<Hyprlang::INT>(props.at("invert_numlock"));
|
col.caps = std::any_cast<Hyprlang::INT>(props.at("capslock_color"));
|
||||||
|
col.num = std::any_cast<Hyprlang::INT>(props.at("numlock_color"));
|
||||||
|
col.invertNum = std::any_cast<Hyprlang::INT>(props.at("invert_numlock"));
|
||||||
|
col.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"));
|
||||||
|
@ -35,16 +36,16 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
||||||
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
halign = std::any_cast<Hyprlang::STRING>(props.at("halign"));
|
||||||
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
valign = std::any_cast<Hyprlang::STRING>(props.at("valign"));
|
||||||
|
|
||||||
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);
|
||||||
outerColor.transitionMs = std::clamp(outerColor.transitionMs, 0, 1000);
|
col.transitionMs = std::clamp(col.transitionMs, 0, 1000);
|
||||||
|
|
||||||
outerColor.both = outerColor.both == -1 ? outerColor.main : outerColor.both;
|
col.both = col.both == -1 ? col.outer : col.both;
|
||||||
outerColor.caps = outerColor.caps == -1 ? outerColor.main : outerColor.caps;
|
col.caps = col.caps == -1 ? col.outer : col.caps;
|
||||||
outerColor.num = outerColor.num == -1 ? outerColor.main : outerColor.num;
|
col.num = col.num == -1 ? col.outer : col.num;
|
||||||
|
|
||||||
g_pHyprlock->m_bNumLock = outerColor.invertNum;
|
g_pHyprlock->m_bNumLock = col.invertNum;
|
||||||
|
|
||||||
std::string placeholderText = std::any_cast<Hyprlang::STRING>(props.at("placeholder_text"));
|
std::string placeholderText = std::any_cast<Hyprlang::STRING>(props.at("placeholder_text"));
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ CPasswordInputField::CPasswordInputField(const Vector2D& viewport_, const std::u
|
||||||
request.asset = placeholderText;
|
request.asset = placeholderText;
|
||||||
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"] = CColor{1.0 - font.r, 1.0 - font.g, 1.0 - font.b, 0.5};
|
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;
|
request.props["font_size"] = (int)size.y / 4;
|
||||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||||
}
|
}
|
||||||
|
@ -171,13 +172,17 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
|
|
||||||
bool forceReload = false;
|
bool forceReload = false;
|
||||||
|
|
||||||
|
if (passwordLength == 0 && g_pHyprlock->getPasswordFailedAttempts() > failedAttempts)
|
||||||
|
forceReload = true;
|
||||||
|
|
||||||
|
failedAttempts = g_pHyprlock->getPasswordFailedAttempts();
|
||||||
passwordLength = g_pHyprlock->getPasswordBufferDisplayLen();
|
passwordLength = g_pHyprlock->getPasswordBufferDisplayLen();
|
||||||
checkWaiting = g_pHyprlock->passwordCheckWaiting();
|
checkWaiting = g_pHyprlock->passwordCheckWaiting();
|
||||||
|
|
||||||
updateFade();
|
updateFade();
|
||||||
updateDots();
|
updateDots();
|
||||||
updateFailTex();
|
updateFailTex();
|
||||||
updateOuter();
|
updateColors();
|
||||||
updateHiddenInputState();
|
updateHiddenInputState();
|
||||||
|
|
||||||
static auto TIMER = std::chrono::system_clock::now();
|
static auto TIMER = std::chrono::system_clock::now();
|
||||||
|
@ -208,14 +213,12 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
shadowData.opacity *= fade.a;
|
shadowData.opacity *= fade.a;
|
||||||
shadow.draw(shadowData);
|
shadow.draw(shadowData);
|
||||||
|
|
||||||
float passAlpha = checkWaiting ? 0.5 : 1.0;
|
CColor outerCol = col.outer;
|
||||||
|
|
||||||
CColor outerCol = outerColor.main;
|
|
||||||
outerCol.a *= fade.a * data.opacity;
|
outerCol.a *= fade.a * data.opacity;
|
||||||
CColor innerCol = inner;
|
CColor innerCol = col.inner;
|
||||||
innerCol.a *= fade.a * data.opacity;
|
innerCol.a *= fade.a * data.opacity;
|
||||||
CColor fontCol = font;
|
CColor fontCol = col.font;
|
||||||
fontCol.a *= fade.a * data.opacity * passAlpha;
|
fontCol.a *= fade.a * data.opacity;
|
||||||
|
|
||||||
if (outThick > 0) {
|
if (outThick > 0) {
|
||||||
g_pRenderer->renderRect(outerBox, outerCol, rounding == -1 ? outerBox.h / 2.0 : rounding);
|
g_pRenderer->renderRect(outerBox, outerCol, rounding == -1 ? outerBox.h / 2.0 : rounding);
|
||||||
|
@ -304,7 +307,7 @@ bool CPasswordInputField::draw(const SRenderData& data) {
|
||||||
forceReload = true;
|
forceReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dots.currentAmount != passwordLength || fade.animated || outerColor.animated || redrawShadow || data.opacity < 1.0 || forceReload;
|
return dots.currentAmount != passwordLength || fade.animated || col.animated || redrawShadow || data.opacity < 1.0 || forceReload;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPasswordInputField::updateFailTex() {
|
void CPasswordInputField::updateFailTex() {
|
||||||
|
@ -328,7 +331,7 @@ void CPasswordInputField::updateFailTex() {
|
||||||
|
|
||||||
placeholder.failText = configFailText;
|
placeholder.failText = configFailText;
|
||||||
replaceAllFail(placeholder.failText, "$FAIL", FAIL.value());
|
replaceAllFail(placeholder.failText, "$FAIL", FAIL.value());
|
||||||
replaceAllFail(placeholder.failText, "$ATTEMPTS", std::to_string(g_pHyprlock->getPasswordFailedAttempts()));
|
replaceAllFail(placeholder.failText, "$ATTEMPTS", std::to_string(failedAttempts));
|
||||||
|
|
||||||
// query
|
// query
|
||||||
CAsyncResourceGatherer::SPreloadRequest request;
|
CAsyncResourceGatherer::SPreloadRequest request;
|
||||||
|
@ -337,7 +340,7 @@ void CPasswordInputField::updateFailTex() {
|
||||||
request.asset = placeholder.failText;
|
request.asset = placeholder.failText;
|
||||||
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"] = outerColor.fail;
|
request.props["color"] = col.fail;
|
||||||
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);
|
||||||
|
|
||||||
|
@ -371,91 +374,126 @@ void CPasswordInputField::updateHiddenInputState() {
|
||||||
hiddenInputState.lastQuadrant = (hiddenInputState.lastQuadrant + rand() % 3 + 1) % 4;
|
hiddenInputState.lastQuadrant = (hiddenInputState.lastQuadrant + rand() % 3 + 1) % 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPasswordInputField::updateOuter() {
|
static void changeChannel(const float& source, const float& target, float& subject, const double& multi, bool& animated) {
|
||||||
if (outThick == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static auto OUTER = outerColor.main, TARGET = OUTER, SOURCE = OUTER;
|
const float DELTA = target - source;
|
||||||
static auto TIMER = std::chrono::system_clock::now();
|
|
||||||
|
|
||||||
if (outerColor.animated) {
|
if (subject != target) {
|
||||||
if (outerColor.stateNum != (outerColor.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock) || outerColor.stateCaps != g_pHyprlock->m_bCapsLock)
|
subject += DELTA * multi;
|
||||||
SOURCE = outerColor.main;
|
animated = true;
|
||||||
} else
|
|
||||||
SOURCE = outerColor.main;
|
|
||||||
|
|
||||||
outerColor.animated = false;
|
if ((source < target && subject > target) || (source > target && subject < target))
|
||||||
outerColor.stateNum = outerColor.invertNum ? !g_pHyprlock->m_bNumLock : g_pHyprlock->m_bNumLock;
|
subject = target;
|
||||||
outerColor.stateCaps = g_pHyprlock->m_bCapsLock;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void changeColor(const CColor& source, const CColor& target, CColor& subject, const double& multi, bool& animated) {
|
||||||
|
|
||||||
|
changeChannel(source.r, target.r, subject.r, multi, animated);
|
||||||
|
changeChannel(source.g, target.g, subject.g, multi, animated);
|
||||||
|
changeChannel(source.b, target.b, subject.b, multi, animated);
|
||||||
|
changeChannel(source.a, target.a, subject.a, multi, animated);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (col.animated) {
|
||||||
|
// 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.failID.empty()) {
|
if (placeholder.failID.empty()) {
|
||||||
if (g_pHyprlock->m_bFadeStarted) {
|
if (g_pHyprlock->m_bFadeStarted) {
|
||||||
if (TARGET == outerColor.check)
|
if (TARGET == col.check)
|
||||||
SOURCE = outerColor.main;
|
SOURCE = BORDERLESS ? col.inner : col.outer;
|
||||||
outerColor.transitionMs = 100;
|
col.transitionMs = 100;
|
||||||
TARGET = OUTER;
|
TARGET = BORDERLESS ? INNER : OUTER;
|
||||||
} else if (checkWaiting)
|
} else if (checkWaiting) {
|
||||||
TARGET = outerColor.check;
|
FTARGET = col.swapFont ? INNER : FONT;
|
||||||
else if (outerColor.both != OUTER && outerColor.stateCaps && outerColor.stateNum)
|
const float PASSALPHA = FTARGET.a * 0.5;
|
||||||
TARGET = outerColor.both;
|
FTARGET.a = PASSALPHA;
|
||||||
else if (outerColor.caps != OUTER && outerColor.stateCaps)
|
|
||||||
TARGET = outerColor.caps;
|
TARGET = col.check;
|
||||||
else if (outerColor.num != OUTER && outerColor.stateNum)
|
ITARGET = col.swapFont ? FONT : INNER;
|
||||||
TARGET = outerColor.num;
|
} else if (col.stateCaps && col.stateNum && col.both != OUTER) {
|
||||||
else
|
TARGET = col.both;
|
||||||
TARGET = OUTER;
|
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 {
|
} else {
|
||||||
SOURCE = outerColor.check;
|
FSOURCE = col.swapFont ? INNER : FONT;
|
||||||
TARGET = outerColor.fail;
|
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) {
|
if (fade.animated || fade.a < 1.0) {
|
||||||
TARGET = OUTER;
|
TARGET = BORDERLESS ? INNER : OUTER;
|
||||||
SOURCE = outerColor.fail;
|
SOURCE = col.fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outerColor.main == TARGET)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (outerColor.main == SOURCE && !fade.animated)
|
if (col.shouldStart) {
|
||||||
TIMER = std::chrono::system_clock::now();
|
col.lastFrame = std::chrono::system_clock::now();
|
||||||
|
col.shouldStart = false;
|
||||||
|
}
|
||||||
|
|
||||||
const auto MULTI = outerColor.transitionMs == 0 ?
|
const auto MULTI = col.transitionMs == 0 ?
|
||||||
1.0 :
|
1.0 :
|
||||||
std::clamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - TIMER).count() / (double)outerColor.transitionMs, 0.02, 0.5);
|
std::clamp(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - col.lastFrame).count() / (double)col.transitionMs, 0.016, 0.5);
|
||||||
const auto DELTA = TARGET - SOURCE;
|
|
||||||
|
|
||||||
if (outerColor.main.r != TARGET.r) {
|
changeColor(SOURCE, TARGET, (BORDERLESS ? col.inner : col.outer), MULTI, col.animated);
|
||||||
outerColor.main.r += DELTA.r * MULTI;
|
changeColor(FSOURCE, FTARGET, col.font, MULTI, col.animated);
|
||||||
outerColor.animated = true;
|
if (col.swapFont && !BORDERLESS)
|
||||||
|
changeColor(ISOURCE, ITARGET, col.inner, MULTI, col.animated);
|
||||||
|
|
||||||
if ((SOURCE.r < TARGET.r && outerColor.main.r > TARGET.r) || (SOURCE.r > TARGET.r && outerColor.main.r < TARGET.r))
|
col.lastFrame = std::chrono::system_clock::now();
|
||||||
outerColor.main.r = TARGET.r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outerColor.main.g != TARGET.g) {
|
|
||||||
outerColor.main.g += DELTA.g * MULTI;
|
|
||||||
outerColor.animated = true;
|
|
||||||
|
|
||||||
if ((SOURCE.g < TARGET.g && outerColor.main.g > TARGET.g) || (SOURCE.g > TARGET.g && outerColor.main.g < TARGET.g))
|
|
||||||
outerColor.main.g = TARGET.g;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outerColor.main.b != TARGET.b) {
|
|
||||||
outerColor.main.b += DELTA.b * MULTI;
|
|
||||||
outerColor.animated = true;
|
|
||||||
|
|
||||||
if ((SOURCE.b < TARGET.b && outerColor.main.b > TARGET.b) || (SOURCE.b > TARGET.b && outerColor.main.b < TARGET.b))
|
|
||||||
outerColor.main.b = TARGET.b;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outerColor.main.a != TARGET.a) {
|
|
||||||
outerColor.main.a += DELTA.a * MULTI;
|
|
||||||
outerColor.animated = true;
|
|
||||||
|
|
||||||
if ((SOURCE.a < TARGET.a && outerColor.main.a > TARGET.a) || (SOURCE.a > TARGET.a && outerColor.main.a < TARGET.a))
|
|
||||||
outerColor.main.a = TARGET.a;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIMER = std::chrono::system_clock::now();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,14 @@ class CPasswordInputField : public IWidget {
|
||||||
void updateFade();
|
void updateFade();
|
||||||
void updateFailTex();
|
void updateFailTex();
|
||||||
void updateHiddenInputState();
|
void updateHiddenInputState();
|
||||||
void updateOuter();
|
void updateColors();
|
||||||
|
|
||||||
bool firstRender = true;
|
bool firstRender = true;
|
||||||
bool redrawShadow = false;
|
bool redrawShadow = false;
|
||||||
bool checkWaiting = false;
|
bool checkWaiting = false;
|
||||||
|
|
||||||
size_t passwordLength = 0;
|
size_t passwordLength = 0;
|
||||||
|
size_t failedAttempts = 0;
|
||||||
|
|
||||||
Vector2D size;
|
Vector2D size;
|
||||||
Vector2D pos;
|
Vector2D pos;
|
||||||
|
@ -42,8 +43,6 @@ class CPasswordInputField : public IWidget {
|
||||||
|
|
||||||
int outThick, rounding;
|
int outThick, rounding;
|
||||||
|
|
||||||
CColor inner, font;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float currentAmount = 0;
|
float currentAmount = 0;
|
||||||
float speedPerSecond = 5; // actually per... something. I am unsure xD
|
float speedPerSecond = 5; // actually per... something. I am unsure xD
|
||||||
|
@ -81,18 +80,26 @@ class CPasswordInputField : public IWidget {
|
||||||
} hiddenInputState;
|
} hiddenInputState;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CColor main;
|
CColor outer;
|
||||||
|
CColor inner;
|
||||||
|
CColor font;
|
||||||
CColor fail;
|
CColor fail;
|
||||||
CColor check;
|
CColor check;
|
||||||
CColor caps;
|
CColor caps;
|
||||||
CColor num;
|
CColor num;
|
||||||
CColor both;
|
CColor both;
|
||||||
|
|
||||||
int transitionMs = 0;
|
int transitionMs = 0;
|
||||||
bool invertNum = false;
|
bool invertNum = false;
|
||||||
bool animated = false;
|
bool animated = false;
|
||||||
bool stateNum = false;
|
bool stateNum = false;
|
||||||
bool stateCaps = false;
|
bool stateCaps = false;
|
||||||
} outerColor;
|
bool swapFont = false;
|
||||||
|
bool shouldStart;
|
||||||
|
|
||||||
|
//
|
||||||
|
std::chrono::system_clock::time_point lastFrame;
|
||||||
|
} col;
|
||||||
|
|
||||||
bool fadeOnEmpty;
|
bool fadeOnEmpty;
|
||||||
uint64_t fadeTimeoutMs;
|
uint64_t fadeTimeoutMs;
|
||||||
|
|
Loading…
Reference in a new issue