From 94ac7fef1abf0786655e1691fffa7d34147a2536 Mon Sep 17 00:00:00 2001 From: bvr-yr <130279855+bvr-yr@users.noreply.github.com> Date: Mon, 26 Feb 2024 03:33:19 +0300 Subject: [PATCH] input-field: dots improvements (#84) * input-field: dots improvements * fix stuff --- src/renderer/widgets/PasswordInputField.cpp | 30 +++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 3b75fe4..63ad6f5 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -135,24 +135,38 @@ bool CPasswordInputField::draw(const SRenderData& data) { g_pRenderer->renderRect(inputFieldBox, innerCol, inputFieldBox.h / 2.0); - const int PASS_SIZE = std::nearbyint(inputFieldBox.h * dt_size * 0.5f) * 2.f; - const int PASS_SPACING = std::floor(PASS_SIZE * dt_space); - const int DOT_AREA_WIDTH = inputFieldBox.w - PASS_SPACING * 2; // avail width for dots - const int MAX_DOTS = DOT_AREA_WIDTH / (PASS_SIZE + PASS_SPACING); // max amount of dots that can fit in the area + const int PASS_SIZE = std::nearbyint(inputFieldBox.h * dt_size * 0.5f) * 2.f; + const int PASS_SPACING = std::floor(PASS_SIZE * dt_space); + const int DOT_PAD = (inputFieldBox.h - PASS_SIZE) / 2; + const int DOT_AREA_WIDTH = inputFieldBox.w - DOT_PAD * 2; // avail width for dots + const int MAX_DOTS = std::round(DOT_AREA_WIDTH * 1.0 / (PASS_SIZE + PASS_SPACING)); // max amount of dots that can fit in the area + const int DOT_FLOORED = std::floor(dots.currentAmount); + const float DOT_ALPHA = fontCol.a; // Calculate the total width required for all dots including spaces between them const int TOTAL_DOTS_WIDTH = (PASS_SIZE + PASS_SPACING) * dots.currentAmount - PASS_SPACING; if (!hiddenInputState.enabled) { // Calculate starting x-position to ensure dots stay centered within the input field - int xstart = dots.center ? (DOT_AREA_WIDTH - TOTAL_DOTS_WIDTH) / 2 : PASS_SPACING; + int xstart = dots.center ? (DOT_AREA_WIDTH - TOTAL_DOTS_WIDTH) / 2 + DOT_PAD : DOT_PAD; - // Clamp xstart to be no less than PASS_SPACING to avoid drawing outside - xstart = std::max(xstart, PASS_SPACING); + if (dots.currentAmount > MAX_DOTS) + xstart = (inputFieldBox.w + MAX_DOTS * (PASS_SIZE + PASS_SPACING) - PASS_SPACING - 2 * TOTAL_DOTS_WIDTH) / 2; + + for (int i = 0; i < dots.currentAmount; ++i) { + if (i < DOT_FLOORED - MAX_DOTS) + continue; + + if (dots.currentAmount != DOT_FLOORED) { + if (i == DOT_FLOORED) + fontCol.a *= (dots.currentAmount - DOT_FLOORED) * data.opacity; + else if (i == DOT_FLOORED - MAX_DOTS) + fontCol.a *= (1 - dots.currentAmount + DOT_FLOORED) * data.opacity; + } - for (size_t i = 0; i < dots.currentAmount && i < MAX_DOTS; ++i) { Vector2D dotPosition = inputFieldBox.pos() + Vector2D{xstart + i * (PASS_SIZE + PASS_SPACING), inputFieldBox.h / 2.f - PASS_SIZE / 2.f}; CBox box{dotPosition, Vector2D{PASS_SIZE, PASS_SIZE}}; g_pRenderer->renderRect(box, fontCol, PASS_SIZE / 2.0); + fontCol.a = DOT_ALPHA; } }