From e0fdafb1bb5bac4da6ddc6f6877cb0f528ef3965 Mon Sep 17 00:00:00 2001 From: Felix Salcher Date: Sun, 29 Jun 2025 14:07:07 +0200 Subject: [PATCH] render two different eye images, depending on if the password is shown or not --- src/renderer/widgets/PasswordInputField.cpp | 44 +++++++++++++------- src/renderer/widgets/PasswordInputField.hpp | 14 ++++--- src/renderer/widgets/icons/eye-closed.png | Bin 0 -> 4631 bytes src/renderer/widgets/icons/eye-open.png | Bin 0 -> 4579 bytes 4 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 src/renderer/widgets/icons/eye-closed.png create mode 100644 src/renderer/widgets/icons/eye-open.png diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index ee66035..2e73e17 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -226,7 +226,7 @@ void CPasswordInputField::updatePassword() { offset = (inputFieldBox.h - assetSize.y) / 2.0; // It can be safely assumed that the eye asset is always available - if (!eye.asset || assetSize.x <= (inputFieldBox.w - offset * 2 - eye.margin - eye.asset->texture.m_vSize.x)) { + if (!eye.openAsset || assetSize.x <= (inputFieldBox.w - offset * 2 - eye.margin - eye.openAsset->texture.m_vSize.x)) { break; } @@ -255,17 +255,22 @@ void CPasswordInputField::renderPasswordUpdate() { } void CPasswordInputField::updateEye() { + // TODO: embed these images + std::string eyeOpenImagePath = "/home/felix/Projects/hyprlock/src/renderer/widgets/icons/eye-open.png"; + std::string eyeClosedImagePath = "/home/felix/Projects/hyprlock/src/renderer/widgets/icons/eye-closed.png"; CAsyncResourceGatherer::SPreloadRequest request; - std::string textResourceID = std::format("eye:{}", (uintptr_t)this); - request.id = textResourceID; - request.asset = "👁"; - request.type = CAsyncResourceGatherer::eTargetType::TARGET_TEXT; - request.props["font_family"] = fontFamily; - request.props["color"] = colorConfig.font; - request.props["font_size"] = (int)(std::nearbyint(configSize.y * eye.size * 0.5f) * 2.f); + eye.openRescourceID = std::format("eye-open:{}", (uintptr_t)this); + request.id = eye.openRescourceID; + request.asset = eyeOpenImagePath; + request.type = CAsyncResourceGatherer::eTargetType::TARGET_IMAGE; - eye.resourceID = textResourceID; + g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + + eye.closedRescourceID = std::format("eye-closed:{}", (uintptr_t)this); + request.id = eye.closedRescourceID; + request.asset = eyeClosedImagePath; + request.type = CAsyncResourceGatherer::eTargetType::TARGET_IMAGE; g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); } @@ -333,9 +338,16 @@ bool CPasswordInputField::draw(const SRenderData& data) { const int ROUND = roundingForBox(inputFieldBox, rounding); g_pRenderer->renderRect(inputFieldBox, innerCol, ROUND); - eye.asset = g_pRenderer->asyncResourceGatherer->getAssetByID(eye.resourceID); - if (!hiddenInputState.enabled && eye.asset) { - Vector2D eyeSize = eye.asset->texture.m_vSize; + eye.openAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(eye.openRescourceID); + if (!hiddenInputState.enabled) { + if (!eye.openAsset) + eye.openAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(eye.openRescourceID); + if (!eye.closedAsset) + eye.closedAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(eye.closedRescourceID); + + auto eyeAsset = showPassword ? eye.closedAsset : eye.openAsset; + double eyeHeight = (int)(std::nearbyint(configSize.y * eye.size * 0.5f) * 2.f); + auto eyeSize = Vector2D{eyeHeight, eyeHeight}; if (!showPassword) { const int RECTPASSSIZE = std::nearbyint(inputFieldBox.h * dots.size * 0.5f) * 2.f; @@ -406,7 +418,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { if (password.asset) { auto passSize = password.asset->texture.m_vSize; - auto eyeSize = eye.asset->texture.m_vSize; + auto eyeSize = eye.openAsset->texture.m_vSize; double padding = (inputFieldBox.h - passSize.y) / 2.0; double xstart = password.center ? (inputFieldBox.w - passSize.x - eyeSize.x + eye.margin) / 2.0 : padding; @@ -424,7 +436,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { auto padding = (inputFieldBox.h - eyeSize.y) / 2.0; auto eyePosition = inputFieldBox.pos() + Vector2D{inputFieldBox.w - eyeSize.x - padding, (inputFieldBox.h - eyeSize.y) / 2}; CBox box = {eyePosition, eyeSize}; - g_pRenderer->renderTexture(box, eye.asset->texture, fontCol.a); + g_pRenderer->renderTexture(box, eyeAsset->texture, fontCol.a); } } @@ -614,11 +626,11 @@ void CPasswordInputField::onHover(const Vector2D& pos) { void CPasswordInputField::onClick(uint32_t button, bool down, const Vector2D& pos) { - if (!password.asset || !eye.asset || !down) + if (!password.asset || !eye.openAsset || !down) return; CBox inputFieldBox = getBoundingBoxWl(); - auto eyeSize = eye.asset->texture.m_vSize; + auto eyeSize = eye.openAsset->texture.m_vSize; auto passwordSize = password.asset->texture.m_vSize; double offset = (inputFieldBox.h - passwordSize.y) / 2.0; diff --git a/src/renderer/widgets/PasswordInputField.hpp b/src/renderer/widgets/PasswordInputField.hpp index c97d288..8321593 100644 --- a/src/renderer/widgets/PasswordInputField.hpp +++ b/src/renderer/widgets/PasswordInputField.hpp @@ -86,11 +86,15 @@ class CPasswordInputField : public IWidget { } password; struct { - int margin = 4; - double size = 0.25; - std::string resourceID = ""; - std::string placement = "right"; - SPreloadedAsset* asset = nullptr; + int margin = 4; + double size = 0.25; + std::string placement = "right"; + + std::string openRescourceID = ""; + SPreloadedAsset* openAsset = nullptr; + + std::string closedRescourceID = ""; + SPreloadedAsset* closedAsset = nullptr; } eye; struct { diff --git a/src/renderer/widgets/icons/eye-closed.png b/src/renderer/widgets/icons/eye-closed.png new file mode 100644 index 0000000000000000000000000000000000000000..71ddc2952c973f3e7a24444c80b0287dab73fb1f GIT binary patch literal 4631 zcmeHLdr(tX8c(FCq@opBbP#P!6?vHC-kTS>CJH7%q6QEc9#vLva&O=Yd5~O4peWWZ zE)SPlYl|pdWUbW|#g-WsELNZep@LR-m#WjM3~t@BbrxL*u)@|o_a?k%JF~;g_CJz2 zIp00!_x;W}zw@0hIVp*YiT39Bb66~vw^pN$2lX<#%%2NB`y9$=pt?b%XpLHJ2x~rg z07&*rEH;e+g+0Zd!}ef#fVKmm_yC*6(8Zta$msa_vec1kDO_3kG zGGOGv-OoDjt`E;hI%*thXX`Fh4&a-59wv3PhCYW5aL0e2YY_?Bxlj9I|ucO z?$K|n4dK_eFL+$io^3oT>G$rhymqWDuR5$}bN%Lm7zOrc&yrU!)-{b?x%mCZt)efC zfy&r`K)HkEWt?s3+F0B{TRyBrYzK3Ssf42oXax3}$i!pXz?K-`ek2>hg z$%CBT#W&Bst6!xX^;-0z_(4V2sYA63qRKrJYa(*T`U)R6Z?Af&XsZL6SPfA}cpZO4dXWO%SLw{RoXVmoa~-ct`k z&`BnyP${~tsKH_qV7Nt32%IJ>yQwR=UKH4LvyjJSAXKK3mjc2_ zWw8-lu|O<<_>oRB7vXK-a1}P(h{mg<+!WwR$;+T9D=HK^91ej)B(T`hg|J*M7ea^- zLHGc{x96ED%*i*~U!y5p9BRUDu#r}Zw3xXxC#JXLP)Z&T^mE7OXR_*a6ZB@gTLqwp z(1}@vumBR8Ov0%ib}BL#khmxGvmW-uJS!oLC+wCSn}LYTCCt=oQz>x6gugY%mc=Xw zHwcL=!UUjpFe*H4NczA{c+e80lO`+U1;n0)q)6kWSkvZ4_b|(uIuYPL!8;8-zIFx- zP&yr|wit5g>1owU9z8yaTMQ(QGNvAq>5YgO;|FZW*jf+GOx*+FKc z@2p(2a?MDA8G&b`YgVoqDKI1OY;^tKdp=(}V?{{@`edD2x9S4evJk6`M zB1ik@J?pwM_WG6QztMc_Gd$?@<>&d;_Urb0_RCKT7MGbatjpiN@%p;`e;OPv_(b!1 z<=Fj0yL?3@d)hsATzM(!-vaHt<4+69?hSk0f{>su7ZzOa8~8LW<<0ZA%W99t-d}XP zSNLPhrS5%qB8>Zonkp~v%syA~AgbrogF9!_gdf*@RpG45_~xJHm_{E(+O@wC@V80T z3wLPmpH7LNv&8Gt=k+1qo42L5f9l1ptr=j7=nZnXW#;EHy?b`nz Dh9hhX literal 0 HcmV?d00001 diff --git a/src/renderer/widgets/icons/eye-open.png b/src/renderer/widgets/icons/eye-open.png new file mode 100644 index 0000000000000000000000000000000000000000..d2390775ba234e5c045e375e25b51da310af36e1 GIT binary patch literal 4579 zcmeHKe^3)w9^YX3Axd>DVvnkgQK-sovf2FHy+pwzO4J}?h974+-Ry2)CBH~EBv2Hn zwf?N_S*bu7!J@X+6BW->(F%-;OwWp1QO~I!gC{*^>Oucd&dQzlb`yThb>@bd>wj$K z<$d?P&-e4*`@HY_CU1Lc%Ce})*hmP1qKwJUrL;LW!;+7X$xO1n7X>{2L2a= zVP@X+9jS9}M;^l~-u@}n6uT#8#)GpeJr4_p0^;h{YUSVH`n!A zG=F~aT@9J|&DzO*+b`!^D->N(U6tQdwG`HKhZ3^ zWR2IZni(InGy4y$G@&x~M|r-!gZ+9&gZOCm8FgMcp7+;}n~=SCGd?+&;)yo?+A?vP ze*PDAyCOGiyLsee%N)~-iBn!~d$h0Z&__onFWnt#K9E!}&{@)Ve(h02(G$OAT4L`` zdx^fRS$t!|y=VO=?PpS;monEO-#|w^^1@hDS7+E=+G6kQYOGuEPV?hekpZgh@DItG zs+JspF4WvqJuW@4R(Q7i*`0@1dnSBzpgv92+%gCG-N7HcANu-z{m*(U3rZHVP43T~ z85KawCYxzmiIYydn4p{%TI{#Gxc!1Oi~TNw%%fSMh0b9dT2b%$CXtY#w4w}! z2{E~JbS{%zW?U@ebO^bSu@ z1)zt-Pq-vfF(R?sB_lmNtf2sq1Sj;f9v*X{i_i}wOzk3zDHby%!XbK`pW<&2yNa3A6wg&tfx z4+bcc3D-MGFE>4-UMu3p$0;YtPQ!)m$33S*dzQYZ;huC~ZWP^@w@ASwyl z$XRhz6rhr;*vWr)PMcOVlyrx>P2f0D1WV`% zmIkClY1llNh7%Bwj|0=^=uA$Eu@?R>Gs;c8FpcP8iaQp-BzZdk-}zE|ykhA!Rl$ z4M(!eqFpNo)FDf|#EZV4z6lCH92Ek8qB}gR>iYz10(|jrm1j!tydJ(G^iN+kUa8r2 zX+IOU{#U|q&D!qLlg+2PI;On0^R3c%TTYjLu&-w$-sh;=6gIE;#QNHZ+u;U`%&NVM z=KWUOr-U+EyNg{pmW7{r`&)}N$L{`dYedQYdmqf}2)$tLK6bX^%s}?7r>ezB@6+q$ z%xd43n7GmlC!bHPexstkYwm|(53{~)Z`w$0el2WW*~-iDpEpnHi>TIrS39{c#(Tc_ z+atb4Z!OlU%L`FnXnedpRJQ;5P34mb_n*WnLuMs5Y3tu=Up(D6JFZMy8%^FQFU=M{ y|1|$WJcC=_UU#qU`ilGc*B{*ZckxTrB0>7?Q(NoKu1Mjw&uB=|*DqQB?tcI@flJ2# literal 0 HcmV?d00001