From 1d8e76aa086d4863c38bbca5c73d16a8e7eb7afe Mon Sep 17 00:00:00 2001 From: John Preston <johnprestonmail@gmail.com> Date: Thu, 29 Dec 2016 13:03:51 +0400 Subject: [PATCH] New empty user/chat photos: with filled background and initials. --- Telegram/Resources/colors.palette | 25 +- Telegram/Resources/icons/userpic_channel.png | Bin 1199 -> 0 bytes .../Resources/icons/userpic_channel@2x.png | Bin 4994 -> 0 bytes Telegram/Resources/icons/userpic_chat.png | Bin 1978 -> 0 bytes Telegram/Resources/icons/userpic_chat@2x.png | Bin 8906 -> 0 bytes Telegram/Resources/icons/userpic_person.png | Bin 1847 -> 0 bytes .../Resources/icons/userpic_person@2x.png | Bin 7707 -> 0 bytes Telegram/Resources/sample.tdesktop-theme | 25 +- Telegram/SourceFiles/boxes/addcontactbox.cpp | 2 +- Telegram/SourceFiles/boxes/confirmbox.cpp | 12 +- Telegram/SourceFiles/boxes/confirmbox.h | 1 + Telegram/SourceFiles/boxes/contactsbox.cpp | 4 +- Telegram/SourceFiles/boxes/contactsbox.h | 2 +- Telegram/SourceFiles/boxes/members_box.cpp | 2 +- Telegram/SourceFiles/boxes/send_files_box.cpp | 6 +- Telegram/SourceFiles/boxes/send_files_box.h | 1 + Telegram/SourceFiles/core/utils.h | 17 +- .../SourceFiles/dialogs/dialogs_layout.cpp | 2 +- Telegram/SourceFiles/dialogswidget.cpp | 4 +- .../history/field_autocomplete.cpp | 4 +- Telegram/SourceFiles/history/history.style | 19 +- .../history/history_media_types.cpp | 17 +- .../SourceFiles/history/history_media_types.h | 1 + Telegram/SourceFiles/historywidget.cpp | 2 +- .../inline_bots/inline_bot_layout_item.cpp | 6 +- Telegram/SourceFiles/localstorage.cpp | 6 +- .../profile/profile_block_peer_list.cpp | 2 +- .../profile/profile_common_groups_section.cpp | 2 +- .../profile/profile_userpic_button.cpp | 2 +- Telegram/SourceFiles/structs.cpp | 225 +++++++++++++----- Telegram/SourceFiles/structs.h | 34 ++- .../ui/buttons/peer_avatar_button.cpp | 2 +- Telegram/SourceFiles/ui/images.h | 5 + .../window/notifications_manager_default.cpp | 4 +- .../window/window_theme_preview.cpp | 112 ++++++--- 35 files changed, 370 insertions(+), 176 deletions(-) delete mode 100644 Telegram/Resources/icons/userpic_channel.png delete mode 100644 Telegram/Resources/icons/userpic_channel@2x.png delete mode 100644 Telegram/Resources/icons/userpic_chat.png delete mode 100644 Telegram/Resources/icons/userpic_chat@2x.png delete mode 100644 Telegram/Resources/icons/userpic_person.png delete mode 100644 Telegram/Resources/icons/userpic_person@2x.png diff --git a/Telegram/Resources/colors.palette b/Telegram/Resources/colors.palette index 581147caf..325e91020 100644 --- a/Telegram/Resources/colors.palette +++ b/Telegram/Resources/colors.palette @@ -258,29 +258,22 @@ historyForwardChooseBg: #0000004c; historyForwardChooseFg: windowFgActive; historyPeer1NameFg: #c03d33; // red -historyPeer1UserpicBg: #ed9482; -historyPeer1UserpicFg: #d3644b; +historyPeer1UserpicBg: #e57979; historyPeer2NameFg: #4fad2d; // green -historyPeer2UserpicBg: #a8db92; -historyPeer2UserpicFg: #75c057; +historyPeer2UserpicBg: #80d066; historyPeer3NameFg: #d09306; // yellow -historyPeer3UserpicBg: #efd289; -historyPeer3UserpicFg: #e4a861; +historyPeer3UserpicBg: #ecd074; historyPeer4NameFg: windowActiveTextFg; // blue -historyPeer4UserpicBg: #8fbfe9; -historyPeer4UserpicFg: #649fd3; +historyPeer4UserpicBg: #6fb1e4; historyPeer5NameFg: #8544d6; // purple -historyPeer5UserpicBg: #9992e4; -historyPeer5UserpicFg: #7b72cf; +historyPeer5UserpicBg: #cc90e2; historyPeer6NameFg: #cd4073; // pink -historyPeer6UserpicBg: #ffa9c3; -historyPeer6UserpicFg: #e87497; +historyPeer6UserpicBg: #f078ae; historyPeer7NameFg: #2996ad; // sea -historyPeer7UserpicBg: #8eccdb; -historyPeer7UserpicFg: #5eb2c7; +historyPeer7UserpicBg: #73cdd0; historyPeer8NameFg: #ce671b; // orange -historyPeer8UserpicBg: #f7b37c; -historyPeer8UserpicFg: #de8d62; +historyPeer8UserpicBg: #fba76f; +historyPeerUserpicFg: windowFgActive; historyScrollBarBg: #556e837a; historyScrollBarBgOver: #556e83bc; diff --git a/Telegram/Resources/icons/userpic_channel.png b/Telegram/Resources/icons/userpic_channel.png deleted file mode 100644 index 1f5fd21f26656e57ddd87e0eb5cb9e51169c84b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1199 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q}r7u#|baIEGZrc{^7(;Io%VoB#Ve zol)VUTUQAM`-Em4XmD~}I&a0Ji8EGdh-idlcO4W33L7jqV6tomPg>~JxP#Yc-kW(k zcaqxflP`at+0(>WRQ7G=<h0M%#RM~%a(<rv#^A8k!Jt@ShNZw68ICkQ7Gw6Nnal^z zG$uTwOxXKSp$ymI36Ct)mWnLR^t$|Vip}}WwkDTO)CoGhxS6x8KG{O%mdyOWoLN<Q z`T6xzcOU$0!;zO1bN%Y;uT{$*ye#25=zHew-MfA}qq65N(_}H%o%cL-((Z%DB%-BH zE66)>RMpll^;<sqXMNP#uvX<?`5Sz+JVab~KDl+|*Sd9?oJ|VX*WG-kC)HH^?8y_A z%Ynu$<_353!k1@8dFZiRx0(0+t*Ura_8bL{EkRlOI|X76Z@HcO_rr$`+aoyEMamq% zm?-gXuXo#nS*{!l4;x%L{d7~vMu8klpb74QOTt%&swU-f{hOWD@_N^kU3p7Qrv!cZ z``34GT>rUq=U)8zGiS+^sn@pje&yS>W5<O;nebb-r3Wtkxpmj{-~G7)cPumxCQ3}( zv@J)7UHQkaU$?%+L?1jBBfVel&2PKj<H?g%vzvQgA9Q2&)_nQ*@7xxFWnR~~zKQ>F zUwrZ4sjaOW`KAS3D%xohxN6&mcM12u`%YzwmJqI~s>)g=a^uj92g~j(IL4bi|KRJd zvt*7Nf>izEVJkCG`|<kq=@88gt%e8Z&!4}{t5LUybKcoB5TjtxVTCpPn<l9&JeiWT zO6CW%o|!~TDZB9Bl8;xfPCYq^z5iqBhrfSq@7}pHL$CV6gK4tP5wo(bn>q_F%T^zp z{b1Y8S3#@GOFT4J-p%{}t6Gue?DNleZrj?~{kwjC`t<205<ETee>N0~_=Ys|otu0# zDbVY=ho*OJ(S{cmtNb3XQ?s?VpT23Xif4v_#D$9&1%Vo;Z92OvX|ML@CD&g+eI>Ot z<k{PE&p&rneP{PBPK%Ga_oR}`;Jx&-n)}BeFWzP>*RL(?^X2oL4;dy}f6Qb#?iufU zAFfp~Id1*(`}giC+$f2;ZmKln#q!yk_vlG9dHY>^8Wfpd`L(wGeei0tXDbU&FX2tq zoxaIvrq7D|?}I0)xV@g%_%%;w(wfstuV#g2#cHNLT%6-woEjf?F(pz@clzl|ue~(C z9zX7`%wk?9?(6d9)2B_J^QQzYz3w}y<=5Z3<aZ)l?{&IPPTeWO;+Xo?damEI$$Aw_ z>l@!h>COD1)U#&2cwJRh(*vcSZ~uHu+IYc<Lpk}t^;aPhiY;<{?Nu8iGL}vW^LnY# z)pPQ04`X~!szTr6jN^rCt^#GP`jXd9xs*BU)ytBs&BdmHXWzYGczXFos?ZHys^wfz c_W#KqA0~3SCA{SaupnaaboFyt=akR{0B+Sqg#Z8m diff --git a/Telegram/Resources/icons/userpic_channel@2x.png b/Telegram/Resources/icons/userpic_channel@2x.png deleted file mode 100644 index d3301baaf828330a9d6489bb527674863c304907..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4994 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 diff --git a/Telegram/Resources/icons/userpic_chat.png b/Telegram/Resources/icons/userpic_chat.png deleted file mode 100644 index 778e505c770b30458773f940138a57e7b7f9bc17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1978 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 JHeL!M{R6;vyDk6# diff --git a/Telegram/Resources/icons/userpic_chat@2x.png b/Telegram/Resources/icons/userpic_chat@2x.png deleted file mode 100644 index cc2492297abe6e42738a22348ad90414ea648e79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8906 zcmdsdhd<SS^#8SGZ$jC7uZWOYmz!D0>e@5eglx&qCM2_jtdNmx$qE&+cd`?*zvq5_ zzdz#p`1X))F899Q=XK8WJclS9ty`o-j6?_of)sgMRS*8%!Tcq}htCT4){+niRs>R2 z>8@|~=Jb76{joEGo$b`J?`b}o*9<Prh>mwNkUSL(4sq+Fx_z4`nL7pfMUsz`3pwc^ zv00eY{GR;rulE;ZnS<|Dey$~@6>_o3SrEHbVuhKB#_T>7>Z=xVsw#WZaCkAN5pgXB zYtcXc?@9l^OH_erTZb<_hP?3*RD^7%dY{b@Y)e0MgD=f9;AK$6|6hJ!^kNF{vl0dF zo9~XlJY^Y3@Zsavz8^e>&-RjxgrNvz64k{WPO6Zx^@yHDB~b=dUK)+l@D2-Ac1qO( z-A+rf%Rv%Jj(Wna#^rQsYHGX!0xC8(TpF61Vs?Yf);2b592_|Cl!JrA1vOfiX8!PG z-n$9&v3E4*DJv!;^DHlqEjBh59T33mQqPo}oJ^sn+dZ397@cydQm-U@!nyl}lvAbm zrt!BQKk`3(V7Pz(epD+_=uXi^uDxWmy(Ez?4P{K%+`gYht?}^WWX#K#SO4zs=QTAk zO;1l(PHsw1;Sy##U<Vhrv`aFQ(g_)d^W+9l9nJ<R5)lzmg?!X!Pb4%Irf+O)bY1AY z#4PJcxVgExb8<$ZmZ*Hk7BzxzRHT<zSxG^DV+Y~AF&@&`DEsF7@B0-UYo6_vRdfBB z5;C5@C}d@2(KQnkgt)&RXHL}>lDKMVk);WlJl&kEw;C<J!^_M2yqpf1#2U?>Kg_$~ zEvJ<u8^Lia{#8*Co|%~$Aue|HclCeio>;>C{Ov!=O?Eq}wO_q^M`m1Zu$6QkIl9)_ zo6NKO!{pKY=R^($Mn+{$s>CM2b~diy^d(`-;tUjbz#`LZ>tK$Yu8B#XwJ+Aq*Q0sO z&CGr2B0cR9#FRu4qBm~D>hN;<ID|_esptCpQO?tiv~oUMs(0>?*38FI<6_~5VWp;~ zz9}zP^YfF%Cm;~JejOQRYW*{by_GQzztpgz`<+>n&VvW!Ia)kE$kAdQUL75s;1@3# z8RFE9$_-?4v>4~uN86tS(-Ps)37bAMYx1_3ZuI*6`SbIp!Ypn=?2*yYD*It}s2BlV z3?2su2aV;Qq7NjMtb{teG&=mLym0Rao0C-!C$GUvHfS~pX%tcItq$F?uwW}Q5OBW6 zlt27t%7*f(TMd;a1#V$c5u1Pjv3ddJ(a{mFuyD8h;Z#_y(^!6GrRc5?7qYQ{SZa$i zLOFz#>DtXCPUzP6@87dBll7U=S<uj98StlyGR7Ibx2H5HGYaX7p<fhua76THZ!a+? zhcv7$`2BmPAley~W`|MkXZg?49|T^0t({v;kv!BH5IhQZV%<ySJYI=)=gyrsWo6-Q z=wRjDBRRImq+9#AO06pcS!_tE!1KM_g7WgXYqy^daaJ8$i82)0y?m^Gyp*h6SXCv) z#~7zk!c9Yj3_4w8DXOj(pZG+6Y_T0Vp;VTg&Ac&DLolRpBKWqnG%+!8H=^97S`TU@ zEc|q6RmI<5&a0@GG=s#|)|UI_<CV)dE>8D&1qD&PbLQHm-`N!vS<cSRer;|RMO@_! zX+V^Icifn2pq@RMIn*&S%AgslsfP+KEiYpspcC;DdN@4P!f8=b4;^b6nXWmvQfuFE z>v&I*`Sa?;*RR1`nrVdr3E`&%`i7ys)|md(y>}0<NRQ9wdcRoKfW5PG;mb=%G<PeU z7qpO3qbHxCQ>I<AdV!La6^Emf(}mqkRw1`7c6Lrq+|#G{83VQrnigq#C7q#o#FYU@ z?!sdM$(cQ>!J{K1ItB($i!{?mB96E`Wv`?On-LWZ-=4N_R}Zc=7JB>kt&YAvPMkW2 z&vg{EEG;c<hMbQuUdCq@v=YUuv2|So1N@o^6i3-8T9Q#$S62z=iRw85=cc+kesoMs z;>(x9K76KM*F4|6eVgAy${rMqr*so42&cX*9Ki%2#mmRnHr3z(|ND$OK;Y=h#aCBX zFA0Y+5k+8gCtq4#UUpAcw(eF9mSQCR>-TZW##JRxhZWkesHh0@47Y#qBG1FG?cr<s zyfmT=B;O*q{}3?z8@g<0?MFj|2P4p+h!Z=dz^x}SEsc|O@zt^Rb6;P<kWiNxCE9&& zWMt%dPR<=HEjJo;{O}FYyhM(82gw&Hjv<Sm)(1`pcSkjo_GzfOu?3NOBY~|xdi=OX z0N;1{0k8i**siUu>6F}!nl(E<q-=+)4rS#uUu7i31%w351%#p?!KaK;P5RBXj>0vf zQS*!YECdxnUO}g7;3fBl;}O%ndi$0L?iBh-)xf}DVTJb7QP1o*ER>n{yeq@i1Oo4- zD+L7wl@rdD#^oQpHyH)#h`G7BlNK_}F&9RK_m7U#iMY(5)B?`H&@l2|sX<;#%T?$M zfWZ%I(~fyMgbKOj)YR1Q62I2g+Lrs$het<~3Ez*dEggJ+S4|*u)!dKZ>wrFgDpES= zWoBj+G|i1apE>O9?OWk=sLfVP@`mkS4ck9YPR6O3hy_f>4O2pCX<2%D(yR{U_9SxL z`Z_g5k~Pq6ro!$Yj0I!w;ZKmFFJ9XMB>~95G<ki?zL4O9mH_nxgJ?y~p4`_S9v*IE zW<D0X3tdLFj<i32{&fBIm5o{6FQt@Kf_m;IE341tDdbZ-88m-0?7Dx)W1r%4<b3kq zzWtqMGL=;{Y%dyg9?+j9O&%8)XYb(9R$9>#ZPgR+=5|MX_<|@x*)+hY4EeN&Oo`%o zR#wcz$vTU}t!aRu;j)OsV@6m{(4-jn+nB5;7isy&PJc3LLte>=B#cmYZJI{9DGe68 z%Je@G$WBd-7|4=d?B&VDjF5Fuu_2&YCdzj{g5GuMGi90i#}{kK+ScTv2wZF|8D_G7 zXMqix^BOYDE8YtF(6G|d^q39ky*(2LciEX+wIj!us!?WCh3$X1)dh<yL;iP0l-(R! zl(1=<tYVBftnK;TFbN;31QA(HO-&WdJVi%W2A=r^>}AcWs;G2aoXSTf9?BUS8ZH*4 zn}-^gcl&RDB&Zk@@IgvHmv7w_en0IJ*|!Y%VcFQ%PGycQNT_Ui;r{sXb$$T>T{E*d zo4z!Q^V6dX>brEIOgx0xj*gBy9W3V*Nu2W^4`;%LR+F2`a3^p`5Q(>O$s%#!W7s|g z`^KF-oo7*7EA+a&G{8MNitl87{q`*!z;tP4g<W3$ig9^b%(ijK-Tb;bI{$->wxuP` z_^a|?`UjGu5Vs0+KbQ(bd0bXzjpp`_GFUp_R#f!pYs*K(F-f;ui@W*%i8d}*S5d)f z*~{5(b*#;=sY#B?;-Sth=8c9EVPIi-jnGc!jo$ISfihLiwObo0^4;yCuY$q|7hAW) zsu#5VtaZX1DG3>wrKP3vR?;{_L_EQ`Oa18G5lJ<6N^ap-L;8App}A)pcH_;DJ@mq* zg#k{;<^NL9iI@wXq|mqO1YaQ|cp4d*`M3^kCdv>#xoKOCH`w3bnXIi41sCeR8|z;~ zCukH5WJ5x%wo^4Yq=b0Hwr1FLNAh-3_)XSUYvM8;-b%lHN6Zk_wB$S10lAZulCt>z z_MUrsyH>E8Zusb0c+X;D6U|DOr5LmeRHZ?)A%v9>vz4K$Xz|R97i2FSJXQz0;;+bA zZ(E2`qY+Vw_H<1Vf|P1vRi9G1fF_WVk{VT8BS${j=#|`EXgS$ZF*ko%<|RstPUs1n zpSSpF{Ey4BilMuwCzIF}x(LI^9`CL6&WH~@ZEsiZ&sBWzqfM|Fdt>j&b^rIh@lEfQ zRq16K5`18HV&dZLK77)Esu-3D$fW0!yLgwM78(eH?33GlcZ1IY75)7D&{anEvTMWu z2n$etAc5}b?qPrbdeYF*aX&e{u0?^18Pe<5uUFT$qws*>vC+k}E$)8x9HGz1&hGsB zmBIt-hhy#6^?g)-!eH9Mg5}cE(&xJN*r-$^*l`gN5r9NDpFELwcX!vzC-yD{Xoqd} z-dITAglKV9yC^9?pB)<T%R#@0KZXyr{7J1qPu4xOcXSM$a8_4RQW_a#8^i_Z!Zg~l zdmivW;6#bHRky0C?6iug3WlF$XJ>yS#q9SNFJA17TO~}p(&_QXTF&qTIr&~{*kLc3 z-`L1_a=6_C`_ejS14tC#_b2$lQ&Xn!*2OOLjfI7{>thwS?%kvPxOBp8ZEcO7sI~zN zZtd(;UD$EIUbJAsO^S~LJlLAJa-+U)WJE6|CFN$hL7y2>dcUoNL4`SK&4i#2A0M*Z zfP;tUR^2Uv2^>>XQ{d|)w)mF51v<RwYgrhk-=K-?^)ZDd*oGD@bP4uwcYkG2s=pPJ zi*&4g5!I7mB$(!Y(g2kZ7Z<l?s!5b@E%6<D=}?9nnJR0mZ*0u?*YC;iy4E%{1x$6C z)(pOZOK1rL8vT|ar8>-L*j|$B)89<0pzF-UxfYyM$O*1WzNVBU<C#hNIQ2{!LN=<X z*3~^RH;GK4Bu+Nqcn5NQSLcibyHyVp>~_a&z6enewl2FD-4$StQ>P@s*OzVu+;|!C zD2x-ia}<EWm0=)hU-SIZ!tQ)6D*u_iB>&_c%>%^ASs?e1-9H*hoG=dD*vv!`bFMP5 zKlO_Zxd^e@6Q4PgKHtEKpRLk=cxeU|rOFNq5!L)sikZv`<P2yTK3dos&l`nyT3ZpY zBK1~?a~*`!iQ%Z*&^lXs6j7?8*RJ8$Pv(dxsKRb_sW++X!Joi!t}+r86}^eoqGn}f z)t`-~g6|U-53Q=IO1ZSNv}C=IW9|;13e^IQ!zZ;PmJIy3ySqChqcKXoAPVvN%i(n~ zv5=^!sBc#y;=3$?2-<ALTA70|YICWVpqyLR?n9*}tI1y_Z#IAQo6HiK6yDOJVEWN7 zwQ*P)Nu!pn7<3g@JjydK<RW`)dEZZe;UqgF<GB}Q+y)k%8f8aE$G^X$+L?ZC;^e1+ zidwk}qzOG8{StP(H0^V9tfs<-8n}RQ9h=^-w<JVGzmqz+xO7Jl(`Ps!eKAVp{5-HY zlpRS0s3s;U*?HH@CzLn3(nt_SwOU?WloF2a>ENJNz~A9psIs-?5Z-7RuirG(qqi;w z*7v{2ip!aRYIDApRkmGg%ih}hEnp>zn#XnXrxa|t&@RiiwlIQBr)8MOFMWN9$;ll{ z12)BLp0X2lRM;eVMoFBejh>fyv|kn){L=&>%d8m4JTNeTs&#K@Xc%ww61W<4>LzI3 zEVDLrebipksK%BQgT<3gp{WS-q~!<aB)f5>-@kvy5bg#Jjn}0W7381JHXpeiY}~gs zMwc7JG;Oyq&7L3BSGi0#b|T|?TU6^_y+Qy!8kEv5E-uyts@U+i=JUejE0uoF&(Fu6 zn3zBYVND5EjK$Q?_z}ZYM^0|0H8CUf*F%Vjh$?OR=$t32@!$`iM`szVmF(*ttc2Jg z)8;*8?Yz{3OMtBUYY5R12Pm+lXmF|OhVw>K;9_YMiE{}@4^b21?(FukEc$#pxgu=V z*x9*2ivDf-CMk(3VAJV=ikTT;SNRmz0HYEG)pmFza5_JKe>*Q#<Abp2i!4qg12c1H z%afCx;ae<u06Lm!f^C16`*ij7!=|RDQr3-o4o~aq>K4d@{^9(boXq?gdRZ}Z7?5Cz zNeZCx&!0cfb8{8fBPYe^(dgfyUJa(M4W=Lb_W6xXOoqqC2vRj7VEq^M6Tc5_V+ASw zb#|7#^n3J=9|n@r(jAMtqI(;}s9I&<=X}#DNu0>EEc#@u7IRUCPM9k)7KPZiZ~5;U z8oovaKfJ~ic+~eGzqXb(pO-srv#R>{Z@;qaSUv(UGO~{CPMRzfpkL;G{QAY)*wjQx zhzopM$Ol=I4`)a~#(YzfF@lw_AD=T2>lQnuty6O{CsJ9GF?IP~#ncVd@mb)w^EGa* zml>o$V4pmB66J6yEzIo<uitVTeGOcZ`|(r@+^tncBrf%GTy&3N`|j?#{XIBv-)))p zCGH=|PnzIFQZ<{402tVwNz8G>wHQc&{PMZ%V;W!;aO)O<gudDX)g(?>!S@flzVN|f zT6VYa^z{5;NAQ8DvTwP4eB5YccCBET7at$r_5Ad)Fg9B>`;?21hBNw~AoSF{E85pL z1N&4B-bR8)bOs5)0x;n!o8z7?4)6$z4sC56UUIZHL8Tbg=~6#*OqyPb=rMF?n06^9 z@NyXgj`Ys7p<V6px-bn<n{ADlo5H>`afC9%l`E;syYZz6C=G_sz^jzToY+n{Un3zQ zaUFgVpUip5yD2BjyaN?=r~m>$FoE0@PbM&Qd1uE}kKo@(ktP7-)V}zF$9{?Xt1F_k zb0CBN{{8#;&$b8c9N0NCGv-h&?#-ICX_ub0(br<vu63IQ_jGrE9T^F2YilcPX)_n0 zi<yU4`nA5Eyga+g4;ADK9(!k|`2}YOycJnFIX6sEv}?e_u?N)obiQ9v__6K09!?_r z#$zhsbj`G&+$Ka!{xb=?!MQJ~0;cjDT9HGm9q@i&AoV>Y{xLlrx3Xeud%!=71o{bz z0|R#Yhu`_@7r;#!{}dE7LYe`F2OJCdR@qHk9;VQXuX6)2E$i|~d6bp}e|J!B`&C7S zcHMSN1L@f)NG^bM1nh25J3L+IbGJD|lX<ikYRAkwK7W2TwLFyuWc$-BIY_YU9xI&7 zSLXo(4-UMWPyh4*&rB~T6UHGyc}X`lHtGOhJlb3JxMHbG<977N=5+SrjAbzUddJzG zl??OK0b3PqZEZ_)86hE3{#1Ux0}_HTB@Chiw^#G<s3}WupTcLzFy4U+3XYB@0xqPz z<?fORC4UsS#{_1?Mex{qYE$+kH<Ahl66D?BOZgbMmJib|;2E$<OQ-kIU2j?Z;!?jj zUS;LGoNBl;AIb8irQvDJS!?bs8nySewezWl=D>5Xz`s})UMmKw+r0n7#P@7}OiWCS z&F8v=dQzdP<_%fd=#UUBpjYUb=EqZ4qy>;vFdMGB3u+kfmvNm#fHRkovArVO+8Q)? z``x>D>Vbg@DDLDbuIZHcc(Uf>-=)x0K=68=<%3v>kD(W7U*BgJ5YXI8a?y}vRP*tX zKL3;cX>LGzw)696LW!{0Qw16Go;A;fX`flBhlJr?M?SCR#rfH<U%#F=rN{|W5Mm~% zFOGNEo<>DQMaE}~*@M^_d@vYnd3ky0suf4a-qpSN4syk%Klv^9cZDKvC@e;HSQrV? zk&u##)gQ3(VUwWZNaEw-dKKQdN`QBDd~&iZZ1n@W21sqOapf8?P1Q$_M3VRRkksfn zbwE;67p<~b*w)+ItG}OmG(jEEwZ@qYr<w13hw>^a5_%hx*;_%s0{?vT?%j%QFlV3) zmXlevT<`jRetkVXS!7s4+Qwd|57T`?x(3Z76p|7|eFPk_pjjhLW@e^)`d*Q$Zs*cc zVVQvM62&Z;W36$+eOtb0_T%GYQCV4jAHG~ZKJ2owb&S0wX!_xKj2d=6FFOUHtJK^z zYUMnNcjh07Kvmzt5N!bJ40%-I34%B@xWQv};idmpNE`ZjQ?>)>0XGr{{wT#mA1|-o zI{#H$FK_P!F#h^owwDw@M==T*zU!>E>01)E`3XaN<Er)-JO;##tK^_YGnj|Z9_8~c ze9cq&_4~J_cUkBOB0W8Q5jsrW#pT^p5h_bL?{-xBgCIIxnqk0&`q{v&Bg%iEE}HiS z<xsQs4P=#VXp9+J<-V-(uKkr>39wXMJ-zmQ;kPDIKtG<G9ON}LWKQH5f}0TpF5U3N z1fLJz1C51U9u5u_zkl<QTv-F$yS!k|^(3&QgPq57V#n8$pq%#{NU>0DeZA(e{oSpK zMf^OS+dn@AeY$IG%zv`_*GAFQg{OaTu)8~sX?HaDoaR4U$U_r0a;!QBXceg02jdQT zYEEQ3s0`TED?_;n&CNG#{W$1_O<OAh_XV=${nIAwW@Wapv%w^Yyy{1&c)ptej$7Bg zv7=8Vclqxc7${eaEdng{D^d?iB9k!dveq~bmLT`a4sg1I?b!tB8Q-uNmER3SmBaR( ziwTPHET?k>ydom2vdwO?Ib>2&QXm9w!oH!WA3#N`vJ*yjyeTPBx_>{jY}P@Nu?xuB z&QGU``Gu|+)8^GEm}_V}E-o(Ll}x+JCnw$vaotSkrpJe#xD_E7EsA*ypc5O@P4rN) z$gy>sz!x^fuoAg{TqeNAGHnUC434B}IQ<-JD_B%-Kxgj_DJFDxt7D{<*~pc=(X~pK zX;}~;bGa9%JeYfcVNdyGU}tN~4%*{@$(5C&74|(d8NuFAiyMkSMnr@>LE)J9W#F+x zN?KariWbL=$?SU9n5W{&MvYOEx6nB_G?*#xf*+F>Y9ELe2?M_dT8Nc_#1eqJ^pIJC zX%6Jw#>_`1ZN;;{^mUEB6jSS$LJ=R$6KDktFix1y>=P*FA}L^6@1OGtxpMg0gR|d; znKDFtpc)o;UA=0og)!czjg8HCjU73p1Z@Kct#TlRFq#i@tH4foj@K&+ii#p8BKD;< z^K{UAD+5Li?pzq&wam&G$Id|FUNel17Q{?PZEdaZR>Nwg*SZ0BG3`?Eu)U71ZU|hb zpz(V`0`jY!z;E3^9&_Udy4(T_<*M%-mTk8buF~z(ozP6gx~J?ExG$J%`BCv80fcXZ zre(Bw#Vt^*U%q^)v>jkPJ=+fI!8kO~<~|PfoM1U5-1tMt&(EK6DOT&X3SjIvM=9yB zNK`+Lot>T4`j7H|z1o4HQcgcyJp>1x!QBLPoFV<_DyY-vFrL0AA)Lr5lw8SoN9UjK zFAd2bGJ`|3B+R2!q{l^eg@K7_(Uw)S&MTWgRl~R?pyBUp#WSRPgQ@ttz~ywHx?ueC zl$+FReHk1~OVKFeBn;hf@>JaB5fZxN=<J+=@oc6T?U65zZv>sKKhX4<_DV0*;kCYK zZrQk%Mh6nU&02gO=xLXx$j9*FV(wp_jT6EgeD<}N+-PCOe_IVwgy5275pW+kk(R}@ zl(<-zFJH#^d@U!_+xb;hiM`U2@a-w7sTfZF`Za+<Zo-;U`F+w#<-D6v4@M@YU8ow1 zw){Q~<Xf4K@fT9z8FTZin4kx?dI9Kd@Q8t7ExY$B2<6}9x44$II~PW73G@U^@^JHt z^x9&Pe6Xp_%s^O^z_w5C>)M!@#x8!bAjf?^Wh=>8g>J*1@)(l$-DxAxg{bSjq;2=t zq`~oV28E*~YG#E1hIC;w<p&Q~K<?R|@iKwfz+@Kyj@@t>zznccHKa<Vrucyxtc`Fn z-|(ei3E05`S_Gk6CZp2_D=fPIvL5ixKOD~ZyUjj1%quR&hn@1dzkg|A=lV>9G8@=p zu*dSs%Sj{2S-MN~UxWM<7bvd=;ZcyF5Pe0?8{M14^?7h`rMg}UlqTd%i(%vntyzy+ zqTsQFNAXxJzER0t?xza^0s_=+If_BBv#D!8h$nJhGOwTqD6n^OQgLz;0J#99%fH8% z1}1L0$;S$6#VaIaV_UIZPNhZ(HlL7?5QYW-%_k}S&hPJZgX6#KCKL7M&70OFF3m~+ z`MdY-<^8{G@Y_#ucDfj@A14r<y|1tT@2Vzh?8E?gt#HgiX8kvzn?EDKp%FHj9%45; z{PIm(;RqLFd;$ZsA>9?iGolFZY;*4F>UvXJ+R^B>4)Np9&XWhp^LI9SHI5In-2~~v zAd{=I>T#WG4N*OmWhR^bqvimoUBGfim>_?^;O^m({D<*bkT-~ge_bMhAz-(%V5q0p z?@^+i{Sc|F0i%z8QZPJ~mR&?Nw6riLN=cl&sTx~N8YR4RF_6jvRmhh0BErmjo=PMp zUW`(0@l3oOfYbf<Ug^&1-jLP63n^6D!<VE$OhCZ?gZ4~-RFRV|xZj}kv;lL{pqVg+ z89zU$Cq7K09v}N*Py}x7o0OI^n5m%iKe#Uwy~xTMo|=k<_!PX3aAh{tf?+0MtsJdL zV54(+kyqQn^{aH9Z%<)be|~;;UWmD&N1x8F!I~v#ntu7Od8=@Uq|%_Y3zR8@G-0U% zhWU_S0wzMtb{h!kghZTv1Sj&DdI2zV(E9d|9^EoAVZu;L2p74%RUmS}1cttIAr!CJ zHxUTz2+Z#S5MbbHX?6AWUoX%(z@pqv|GB|?;M)ymW0HgIU(D5rn^d@1fSWMTpvgNy z9So0;KRelKA_ttH|K{kW5hPY3IP;`#aueetU~YAKniOGFWr<h!aPlemUM?%%c74DO zwX$VG3T`DVfGmKRwH;LAY2ZcdyLf7dfeOL(!Zcb{73Kc^J|^`Wwhz~OT`)(5&{vB8 z^n75`8wUYhuHVyE%?*ase?pAG@SUj=^f@N*1!_7tF4o>oEYi%nyt-Nd<$*61i-bSF z3``r?70^WC2Q9IXc^1^vP-B9O*4CSr(i7zrp!GOmKp?k;u*cEuQiF=BE-L#NW*U-{ zFvu9@VF9ZH)nz8@xudOiDW6w^##q@lmp2*~I}}^SeTi`9@#>ZLb#>r#X*H?QaW;&F zQYs@*@)G3a<cpnA)c+=D&!1BBXmJkyI&RL;3%+E53TRlt<jx0^kDy67#6qt`sk)5k zqOiEbb)n<H$dK_r5Cq{7MocgK3a&UTEG(+QhDel+84~SZTU*`m)0pG(^zs7LsRO@K zp%!5BX27-sVp>T5`C7wwpw;g@RL(<Cw~H9Ns}c6_wuZaLVx#`oJUC}zk-KNeFLNRZ QzoUXcs%fddQ$~mW4>#hz`2YX_ diff --git a/Telegram/Resources/icons/userpic_person.png b/Telegram/Resources/icons/userpic_person.png deleted file mode 100644 index fb28bf3c53389b788fc37e861c6557f102015702..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1847 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 diff --git a/Telegram/Resources/icons/userpic_person@2x.png b/Telegram/Resources/icons/userpic_person@2x.png deleted file mode 100644 index 4b63a71011dd03f857319b498ab60dcdc05cae22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7707 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 YzJ(3Gw2QIutrEUg>Y3=i(sl^@KS|t8RsaA1 diff --git a/Telegram/Resources/sample.tdesktop-theme b/Telegram/Resources/sample.tdesktop-theme index 05c99a2d6..a1f2d88b2 100644 --- a/Telegram/Resources/sample.tdesktop-theme +++ b/Telegram/Resources/sample.tdesktop-theme @@ -214,29 +214,22 @@ historyUnreadBarFg: #538bb4; historyForwardChooseBg: #0000004c; historyForwardChooseFg: #ffffff; // windowActiveTextFg; historyPeer1NameFg: #c03d33; -historyPeer1UserpicBg: #ed9482; -historyPeer1UserpicFg: #d3644b; +historyPeer1UserpicBg: #e57979; historyPeer2NameFg: #4fad2d; -historyPeer2UserpicBg: #a8db92; -historyPeer2UserpicFg: #75c057; +historyPeer2UserpicBg: #80d066; historyPeer3NameFg: #d09306; -historyPeer3UserpicBg: #efd289; -historyPeer3UserpicFg: #e4a861; +historyPeer3UserpicBg: #ecd074; historyPeer4NameFg: #168acd; // windowShadowFg; -historyPeer4UserpicBg: #8fbfe9; -historyPeer4UserpicFg: #649fd3; +historyPeer4UserpicBg: #6fb1e4; historyPeer5NameFg: #8544d6; -historyPeer5UserpicBg: #9992e4; -historyPeer5UserpicFg: #7b72cf; +historyPeer5UserpicBg: #cc90e2; historyPeer6NameFg: #cd4073; -historyPeer6UserpicBg: #ffa9c3; -historyPeer6UserpicFg: #e87497; +historyPeer6UserpicBg: #f078ae; historyPeer7NameFg: #2996ad; -historyPeer7UserpicBg: #8eccdb; -historyPeer7UserpicFg: #5eb2c7; +historyPeer7UserpicBg: #73cdd0; historyPeer8NameFg: #ce671b; -historyPeer8UserpicBg: #f7b37c; -historyPeer8UserpicFg: #de8d62; +historyPeer8UserpicBg: #fba76f; +historyPeerUserpicFg: #ffffff; // windowActiveTextFg; historyScrollBarBg: #556e837a; historyScrollBarBgOver: #556e83bc; historyScrollBg: #556e834c; diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index 037a5e19d..02a570031 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -1201,7 +1201,7 @@ void RevokePublicLinkBox::resizeEvent(QResizeEvent *e) { void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selected) const { auto peer = row.peer; - peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width()); + peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize); p.setPen(st::contactsNameFg); diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp index f11226cf3..cba2f8959 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.cpp +++ b/Telegram/SourceFiles/boxes/confirmbox.cpp @@ -462,7 +462,6 @@ void RichDeleteMessageBox::deleteAndClear() { ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChatPhoto &photo, int count, const QVector<UserData*> &participants) : _title(this, st::confirmInviteTitle) , _status(this, st::confirmInviteStatus) -, _photo(chatDefPhoto(0)) , _participants(participants) { _title->setText(title); QString status; @@ -483,6 +482,9 @@ ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChat } } } + if (!_photo) { + _photoEmpty.set(0, title); + } } void ConfirmInviteBox::prepare() { @@ -528,12 +530,16 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) { Painter p(this); - p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize)); + if (_photo) { + p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize)); + } else { + _photoEmpty.paint(p, (width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, width(), st::confirmInvitePhotoSize); + } int sumWidth = _participants.size() * _userWidth; int left = (width() - sumWidth) / 2; for_const (auto user, _participants) { - user->paintUserpicLeft(p, st::confirmInviteUserPhotoSize, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width()); + user->paintUserpicLeft(p, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width(), st::confirmInviteUserPhotoSize); left += _userWidth; } } diff --git a/Telegram/SourceFiles/boxes/confirmbox.h b/Telegram/SourceFiles/boxes/confirmbox.h index f14b1ac80..068577d6a 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.h +++ b/Telegram/SourceFiles/boxes/confirmbox.h @@ -207,6 +207,7 @@ private: object_ptr<Ui::FlatLabel> _title; object_ptr<Ui::FlatLabel> _status; ImagePtr _photo; + EmptyUserpic _photoEmpty; QVector<UserData*> _participants; int _userWidth = 0; diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 12b908698..2e656a255 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -955,7 +955,7 @@ void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Cont checkedRatio = data->checkbox->checkedAnimationRatio(); data->checkbox->paint(p, ms, st::contactsPadding.left(), st::contactsPadding.top(), width()); } else { - peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width()); + peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize); } int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(); @@ -1013,7 +1013,7 @@ void ContactsBox::Inner::paintDisabledCheckUserpic(Painter &p, PeerData *peer, i auto iconBorderPen = st::contactsPhotoCheckbox.check.border->p; iconBorderPen.setWidth(st::contactsPhotoCheckbox.selectWidth); - peer->paintUserpicLeft(p, userpicRadius * 2, userpicLeft, userpicTop, width()); + peer->paintUserpicLeft(p, userpicLeft, userpicTop, width(), userpicRadius * 2); { PainterHighQualityEnabler hq(p); diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 89bd546c0..6078ec410 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -43,7 +43,7 @@ QString cantInviteError(); inline Ui::RoundImageCheckbox::PaintRoundImage PaintUserpicCallback(PeerData *peer) { return [peer](Painter &p, int x, int y, int outerWidth, int size) { - peer->paintUserpicLeft(p, size, x, y, outerWidth); + peer->paintUserpicLeft(p, x, y, outerWidth, size); }; } diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index e3a6054a6..daccc73fb 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -271,7 +271,7 @@ void MembersBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Membe data->ripple.reset(); } } - peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width()); + peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize); p.setPen(st::contactsNameFg); diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index a12e23b28..8848a29e3 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -127,9 +127,11 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstn : _contactPhone(phone) , _contactFirstName(firstname) , _contactLastName(lastname) { - _nameText.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName), _textNameOptions); + auto name = lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName); + _nameText.setText(st::semiboldTextStyle, name, _textNameOptions); _statusText = _contactPhone; _statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText)); + _contactPhotoEmpty.set(0, name); } void SendFilesBox::prepare() { @@ -280,7 +282,7 @@ void SendFilesBox::paintEvent(QPaintEvent *e) { auto &icon = _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument; icon.paintInCenter(p, inner); } else { - p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixCircled(st::msgFileSize)); + _contactPhotoEmpty.paint(p, x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), st::msgFileSize); } } else { QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width())); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index cca2759f3..62ab8a922 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -89,6 +89,7 @@ private: QString _contactPhone; QString _contactFirstName; QString _contactLastName; + EmptyUserpic _contactPhotoEmpty; base::lambda<void(const QStringList &files, bool compressed, const QString &caption, bool ctrlShiftEnter)> _confirmedCallback; base::lambda<void()> _cancelledCallback; diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index 1f6433dd2..7626b9efc 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -320,21 +320,24 @@ inline T snap(const T &v, const T &_min, const T &_max) { template <typename T> class ManagedPtr { public: - ManagedPtr() : ptr(0) { - } - ManagedPtr(T *p) : ptr(p) { + ManagedPtr() = default; + ManagedPtr(T *p) : _data(p) { } T *operator->() const { - return ptr; + return _data; } T *v() const { - return ptr; + return _data; + } + + explicit operator bool() const { + return _data != nullptr; } protected: + using Parent = ManagedPtr<T>; + T *_data = nullptr; - T *ptr; - typedef ManagedPtr<T> Parent; }; QString translitRusEng(const QString &rus); diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index ba405597f..5cf0f3451 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -66,7 +66,7 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i if (onlyBackground) return; auto userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer); - userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth); + userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth, st::dialogsPhotoSize); auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 01e73622d..9f985aa0a 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -297,7 +297,7 @@ void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *res auto peer = result->peer; auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer); - userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth()); + userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth(), st::dialogsPhotoSize); auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); @@ -344,7 +344,7 @@ void DialogsInner::paintSearchInPeer(Painter &p, int fullWidth, bool onlyBackgro p.fillRect(fullRect, st::dialogsBg); if (onlyBackground) return; - _searchInPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth()); + _searchInPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth(), st::dialogsPhotoSize); auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; auto namewidth = fullWidth - nameleft - st::dialogsPadding.x() * 2 - st::dialogsCancelSearch.width; diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index b78c84945..69e606dac 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -618,7 +618,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) { } } user->loadUserpic(); - user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width()); + user->paintUserpicLeft(p, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width(), st::mentionPhotoSize); p.setPen(selected ? st::mentionNameFgOver : st::mentionNameFg); user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth); @@ -663,7 +663,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) { toHighlight += '@' + user->username; } user->loadUserpic(); - user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width()); + user->paintUserpicLeft(p, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width(), st::mentionPhotoSize); auto commandText = '/' + toHighlight; diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index b5c7d2c6e..d029356fd 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -145,23 +145,6 @@ historyViewsOutIcon: icon {{ "history_views", historyOutIconFg }}; historyViewsOutSelectedIcon: icon {{ "history_views", historyOutIconFgSelected }}; historyViewsInvertedIcon: icon {{ "history_views", historySendingInvertedIconFg }}; -historyPeer1UserpicPerson: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_person", historyPeer1UserpicFg }}; -historyPeer1UserpicChat: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_chat", historyPeer1UserpicFg }}; -historyPeer1UserpicChannel: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_channel", historyPeer1UserpicFg }}; -historyPeer2UserpicPerson: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_person", historyPeer2UserpicFg }}; -historyPeer2UserpicChat: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_chat", historyPeer2UserpicFg }}; -historyPeer2UserpicChannel: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_channel", historyPeer2UserpicFg }}; -historyPeer3UserpicPerson: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_person", historyPeer3UserpicFg }}; -historyPeer3UserpicChat: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_chat", historyPeer3UserpicFg }}; -historyPeer3UserpicChannel: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_channel", historyPeer3UserpicFg }}; -historyPeer4UserpicPerson: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_person", historyPeer4UserpicFg }}; -historyPeer4UserpicChat: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_chat", historyPeer4UserpicFg }}; -historyPeer4UserpicChannel: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_channel", historyPeer4UserpicFg }}; -historyPeer5UserpicPerson: icon {{ size(120px, 120px), historyPeer5UserpicBg }, { "userpic_person", historyPeer5UserpicFg }}; -historyPeer6UserpicPerson: icon {{ size(120px, 120px), historyPeer6UserpicBg }, { "userpic_person", historyPeer6UserpicFg }}; -historyPeer7UserpicPerson: icon {{ size(120px, 120px), historyPeer7UserpicBg }, { "userpic_person", historyPeer7UserpicFg }}; -historyPeer8UserpicPerson: icon {{ size(120px, 120px), historyPeer8UserpicBg }, { "userpic_person", historyPeer8UserpicFg }}; - historyComposeField: FlatTextarea { textColor: historyComposeAreaFg; bgColor: historyComposeAreaBg; @@ -391,6 +374,8 @@ historyBubbleTailInRightSelected: icon {{ "bubble_tail-flip_horizontal", msgInBg historyBubbleTailOutRight: icon {{ "bubble_tail-flip_horizontal", msgOutBg }}; historyBubbleTailOutRightSelected: icon {{ "bubble_tail-flip_horizontal", msgOutBgSelected }}; +historyPeerUserpicFont: semiboldFont; + historyStatusFg: windowSubTextFg; historyStatusFgActive: windowActiveTextFg; historyStatusFgTyping: historyStatusFgActive; diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 8c0f92b93..a41fb4daa 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -2235,16 +2235,17 @@ HistoryContact::HistoryContact(HistoryItem *parent, int32 userId, const QString , _lname(last) , _phone(App::formatPhone(phone)) { _name.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions); - _phonew = st::normalFont->width(_phone); } void HistoryContact::initDimensions() { _maxw = st::msgFileMinWidth; - _contact = _userId ? App::userLoaded(_userId) : 0; + _contact = _userId ? App::userLoaded(_userId) : nullptr; if (_contact) { _contact->loadUserpic(); + } else { + _photoEmpty.set(qAbs(_userId ? _userId : _parent->id) % kUserColorsCount, _name.originalText()); } if (_contact && _contact->contact > 0) { _linkl = sendMessageClickHandler(_contact); @@ -2305,12 +2306,15 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width)); if (_contact) { - _contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y()); + _contact->paintUserpic(p, rthumb.x(), rthumb.y(), st::msgFileThumbSize); } else { - p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % kUserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize)); + _photoEmpty.paint(p, st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, width, st::msgFileThumbSize); } if (selected) { - App::roundRect(p, rthumb, p.textPalette().selectOverlay, SelectedOverlaySmallCorners); + PainterHighQualityEnabler hq(p); + p.setBrush(p.textPalette().selectOverlay); + p.setPen(Qt::NoPen); + p.drawEllipse(rthumb); } bool over = ClickHandler::showAsActive(_linkl); @@ -2323,8 +2327,7 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T nameright = st::msgFilePadding.left(); statustop = st::msgFileStatusTop - topMinus; - QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width)); - p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(_parent->id) % kUserColorsCount)->pixCircled(st::msgFileSize, st::msgFileSize)); + _photoEmpty.paint(p, st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, width, st::msgFileSize); } int32 namewidth = width - nameleft - nameright; diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index 0e9dc6f62..e16987a65 100644 --- a/Telegram/SourceFiles/history/history_media_types.h +++ b/Telegram/SourceFiles/history/history_media_types.h @@ -636,6 +636,7 @@ private: int _phonew = 0; QString _fname, _lname, _phone; Text _name; + EmptyUserpic _photoEmpty; ClickHandlerPtr _linkl; int _linkw = 0; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 10fe2546b..fcd03cf5e 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -553,7 +553,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > r.top()) { - message->from()->paintUserpicLeft(p, st::msgPhotoSize, st::historyPhotoLeft, userpicTop, message->history()->width); + message->from()->paintUserpicLeft(p, st::historyPhotoLeft, userpicTop, message->history()->width, st::msgPhotoSize); } return true; }); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp index 4b9675248..3ccb9c1c4 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp @@ -146,7 +146,11 @@ ImagePtr ItemBase::getResultThumb() const { QPixmap ItemBase::getResultContactAvatar(int width, int height) const { if (_result->_type == Result::Type::Contact) { - return userDefPhoto(qHash(_result->_id) % kUserColorsCount)->pixCircled(width, height); + auto result = EmptyUserpic(qHash(_result->_id) % kUserColorsCount, _result->getLayoutTitle()).generate(width); + if (result.height() != height * cIntRetinaFactor()) { + result = result.scaled(QSize(width, height) * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + return std_::move(result); } return QPixmap(); } diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index be4196344..ba0780a9c 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -3874,7 +3874,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access)); } - user->setUserpic(photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc)); + user->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc)); } } else if (result->isChat()) { ChatData *chat = result->asChat(); @@ -3902,7 +3902,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); chat->inputChat = MTP_int(peerToChat(chat->id)); - chat->setUserpic(photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc)); + chat->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc)); } } else if (result->isChannel()) { ChannelData *channel = result->asChannel(); @@ -3924,7 +3924,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) { channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); - channel->setUserpic(photoLoc.isNull() ? ImagePtr((channel->isMegagroup() ? chatDefPhoto(channel->colorIndex) : channelDefPhoto(channel->colorIndex))) : ImagePtr(photoLoc)); + channel->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc)); } } if (!wasLoaded) { diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp index 069b413c3..c4ddcc820 100644 --- a/Telegram/SourceFiles/profile/profile_block_peer_list.cpp +++ b/Telegram/SourceFiles/profile/profile_block_peer_list.cpp @@ -96,7 +96,7 @@ void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool select } int skip = st::profileMemberPhotoPosition.x(); - item->peer->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width()); + item->peer->paintUserpicLeft(p, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width(), st::profileMemberPhotoSize); if (item->name.isEmpty()) { item->name.setText(st::msgNameStyle, App::peerName(item->peer), _textNameOptions); diff --git a/Telegram/SourceFiles/profile/profile_common_groups_section.cpp b/Telegram/SourceFiles/profile/profile_common_groups_section.cpp index 4930077ab..3b5849397 100644 --- a/Telegram/SourceFiles/profile/profile_common_groups_section.cpp +++ b/Telegram/SourceFiles/profile/profile_common_groups_section.cpp @@ -236,7 +236,7 @@ void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) { x += st::profileCommonGroupsPadding.left(); y += st::profileCommonGroupsPadding.top(); - item->peer->paintUserpic(p, st::profileCommonGroupsPhotoSize, rtl() ? (width() - x - st::profileCommonGroupsPhotoSize) : x, y); + item->peer->paintUserpic(p, rtl() ? (width() - x - st::profileCommonGroupsPhotoSize) : x, y, st::profileCommonGroupsPhotoSize); x += st::profileCommonGroupsPhotoSize + st::profileCommonGroupsNameLeft; y += st::profileCommonGroupsNameTop; diff --git a/Telegram/SourceFiles/profile/profile_userpic_button.cpp b/Telegram/SourceFiles/profile/profile_userpic_button.cpp index 3d346493a..fa401d104 100644 --- a/Telegram/SourceFiles/profile/profile_userpic_button.cpp +++ b/Telegram/SourceFiles/profile/profile_userpic_button.cpp @@ -115,7 +115,7 @@ QPixmap UserpicButton::prepareUserpicPixmap() const { image.fill(Qt::transparent); { Painter p(&image); - _peer->paintUserpic(p, width(), 0, 0); + _peer->paintUserpic(p, 0, 0, width()); } return App::pixmapFromImageInPlace(std_::move(image)); } diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index b0bc174ed..8d894744e 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -74,40 +74,140 @@ style::color peerColor(int index) { return peerColors[index]; } -ImagePtr userDefPhoto(int index) { - static const ImagePtr userDefPhotos[kUserColorsCount] = { - generateUserpicImage(st::historyPeer1UserpicPerson), - generateUserpicImage(st::historyPeer2UserpicPerson), - generateUserpicImage(st::historyPeer3UserpicPerson), - generateUserpicImage(st::historyPeer4UserpicPerson), - generateUserpicImage(st::historyPeer5UserpicPerson), - generateUserpicImage(st::historyPeer6UserpicPerson), - generateUserpicImage(st::historyPeer7UserpicPerson), - generateUserpicImage(st::historyPeer8UserpicPerson), +style::color peerUserpicColor(int index) { + static style::color peerColors[kUserColorsCount] = { + st::historyPeer1UserpicBg, + st::historyPeer2UserpicBg, + st::historyPeer3UserpicBg, + st::historyPeer4UserpicBg, + st::historyPeer5UserpicBg, + st::historyPeer6UserpicBg, + st::historyPeer7UserpicBg, + st::historyPeer8UserpicBg, }; - return userDefPhotos[index]; + return peerColors[index]; } -ImagePtr chatDefPhoto(int index) { - static const ImagePtr chatDefPhotos[kChatColorsCount] = { - generateUserpicImage(st::historyPeer1UserpicChat), - generateUserpicImage(st::historyPeer2UserpicChat), - generateUserpicImage(st::historyPeer3UserpicChat), - generateUserpicImage(st::historyPeer4UserpicChat), - }; - return chatDefPhotos[index]; +class EmptyUserpic::Impl { +public: + Impl(int index, const QString &name) : _color(peerUserpicColor(index)) { + fillString(name); + } + + void paint(Painter &p, int x, int y, int size); + +private: + void fillString(const QString &name); + + style::color _color; + QString _string; + +}; + +void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) { + auto fontsize = (size * 13) / 33; + auto font = st::historyPeerUserpicFont->f; + font.setPixelSize(fontsize); + + PainterHighQualityEnabler hq(p); + p.setBrush(_color); + p.setPen(Qt::NoPen); + p.drawEllipse(x, y, size, size); + + p.setFont(font); + p.setBrush(Qt::NoBrush); + p.setPen(st::historyPeerUserpicFg); + p.drawText(QRect(x, y, size, size), _string, QTextOption(style::al_center)); } -ImagePtr channelDefPhoto(int index) { - static const ImagePtr channelDefPhotos[kChannelColorsCount] = { - generateUserpicImage(st::historyPeer1UserpicChannel), - generateUserpicImage(st::historyPeer2UserpicChannel), - generateUserpicImage(st::historyPeer3UserpicChannel), - generateUserpicImage(st::historyPeer4UserpicChannel), - }; - return channelDefPhotos[index]; +void EmptyUserpic::Impl::fillString(const QString &name) { + QList<QString> letters; + QList<int> levels; + auto level = 0; + auto letterFound = false; + auto ch = name.constData(), end = ch + name.size(); + while (ch != end) { + auto emojiLength = 0; + if (auto emoji = emojiFromText(ch, end, &emojiLength)) { + ch += emojiLength; + } else if (ch->isHighSurrogate()) { + ++ch; + if (ch != end && ch->isLowSurrogate()) { + ++ch; + } + } else if (!letterFound && ch->isLetterOrNumber()) { + letterFound = true; + if (ch + 1 != end && chIsDiac(*(ch + 1))) { + letters.push_back(QString(ch, 2)); + levels.push_back(level); + ++ch; + } else { + letters.push_back(QString(ch, 1)); + levels.push_back(level); + } + ++ch; + } else { + if (*ch == ' ') { + level = 0; + letterFound = false; + } else if (letterFound && *ch == '-') { + level = 1; + letterFound = true; + } + ++ch; + } + } + + // We prefer the second letter to be after ' ', but it can also be after '-'. + _string = QString(); + if (!letters.isEmpty()) { + _string += letters.front(); + auto bestIndex = 0; + auto bestLevel = 2; + for (auto i = letters.size(); i != 1;) { + if (levels[--i] < bestLevel) { + bestIndex = i; + bestLevel = levels[i]; + } + } + if (bestIndex > 0) { + _string += letters[bestIndex]; + } + } + _string = _string.toUpper(); } +EmptyUserpic::EmptyUserpic() = default; + +EmptyUserpic::EmptyUserpic(int index, const QString &name) : _impl(std_::make_unique<Impl>(index, name)) { +} + +void EmptyUserpic::set(int index, const QString &name) { + _impl = std_::make_unique<Impl>(index, name); +} + +void EmptyUserpic::clear() { + _impl.reset(); +} + +void EmptyUserpic::paint(Painter &p, int x, int y, int outerWidth, int size) const { + t_assert(_impl != nullptr); + _impl->paint(p, rtl() ? (outerWidth - x - size) : x, y, size); +} + +QPixmap EmptyUserpic::generate(int size) { + auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(cRetinaFactor()); + result.fill(Qt::transparent); + { + Painter p(&result); + paint(p, 0, 0, size, size); + } + return App::pixmapFromImageInPlace(std_::move(result)); +} + +EmptyUserpic::~EmptyUserpic() = default; + using UpdateFlag = Notify::PeerUpdate::Flag; NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats; @@ -115,9 +215,9 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP PeerData::PeerData(const PeerId &id) : id(id) , colorIndex(peerColorIndex(id)) -, color(peerColor(colorIndex)) -, _userpic(isUser() ? userDefPhoto(colorIndex) : ((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))) { +, color(peerColor(colorIndex)) { nameText.setText(st::msgNameStyle, QString(), _textNameOptions); + _userpicEmpty.set(colorIndex, QString()); } void PeerData::updateNameDelayed(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) { @@ -138,6 +238,9 @@ void PeerData::updateNameDelayed(const QString &newName, const QString &newNameO ++nameVersion; name = newName; nameText.setText(st::msgNameStyle, name, _textNameOptions); + if (!_userpic) { + _userpicEmpty.set(colorIndex, name); + } Notify::PeerUpdate update(this); update.flags |= UpdateFlag::NameChanged; @@ -170,39 +273,55 @@ void PeerData::updateNameDelayed(const QString &newName, const QString &newNameO void PeerData::setUserpic(ImagePtr userpic) { _userpic = userpic; + if (!_userpic || !_userpic->loaded()) { + _userpicEmpty.set(colorIndex, name); + } else { + _userpicEmpty.clear(); + } } ImagePtr PeerData::currentUserpic() const { - if (_userpic->loaded()) { - return _userpic; + if (_userpic) { + _userpic->load(); + if (_userpic->loaded()) { + _userpicEmpty.clear(); + return _userpic; + } } - _userpic->load(); - - if (isUser()) { - return userDefPhoto(colorIndex); - } else if (isMegagroup() || isChat()) { - return chatDefPhoto(colorIndex); - } - return channelDefPhoto(colorIndex); + return ImagePtr(); } -void PeerData::paintUserpic(Painter &p, int size, int x, int y) const { - p.drawPixmap(x, y, currentUserpic()->pixCircled(size, size)); +void PeerData::paintUserpic(Painter &p, int x, int y, int size) const { + if (auto userpic = currentUserpic()) { + p.drawPixmap(x, y, userpic->pixCircled(size, size)); + } else { + _userpicEmpty.paint(p, x, y, x + size + x, size); + } } StorageKey PeerData::userpicUniqueKey() const { - if (photoLoc.isNull() || !_userpic->loaded()) { + if (photoLoc.isNull() || !_userpic || !_userpic->loaded()) { return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex); } return storageKey(photoLoc); } void PeerData::saveUserpic(const QString &path, int size) const { - currentUserpic()->pixRounded(size, size, ImageRoundRadius::Small).save(path, "PNG"); + genUserpic(size).save(path, "PNG"); } QPixmap PeerData::genUserpic(int size) const { - return currentUserpic()->pixRounded(size, size, ImageRoundRadius::Small); + if (auto userpic = currentUserpic()) { + return userpic->pixRounded(size, size, ImageRoundRadius::Small); + } + auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(cRetinaFactor()); + result.fill(Qt::transparent); + { + Painter p(&result); + paintUserpic(p, 0, 0, size); + } + return App::pixmapFromImageInPlace(std_::move(result)); } const Text &BotCommand::descriptionText() const { @@ -225,17 +344,17 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a const auto &d(p.c_userProfilePhoto()); newPhotoId = d.vphoto_id.v; newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small); - newPhoto = newPhotoLoc.isNull() ? userDefPhoto(colorIndex) : ImagePtr(newPhotoLoc); + newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc); //App::feedPhoto(App::photoFromUserPhoto(peerToUser(id), MTP_int(unixtime()), p)); } break; default: { newPhotoId = 0; if (id == ServiceUserId) { - if (_userpic.v() == userDefPhoto(colorIndex).v()) { + if (!_userpic) { newPhoto = ImagePtr(App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation)), "PNG"); } } else { - newPhoto = userDefPhoto(colorIndex); + newPhoto = ImagePtr(); } newPhotoLoc = StorageImageLocation(); } break; @@ -423,13 +542,13 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Loc newPhotoId = phId; } newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small); - newPhoto = newPhotoLoc.isNull() ? chatDefPhoto(colorIndex) : ImagePtr(newPhotoLoc); -// photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex)); + newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc); +// photoFull = newPhoto ? ImagePtr(640, 640, d.vphoto_big, ImagePtr()) : ImagePtr(); } break; default: { newPhotoId = 0; newPhotoLoc = StorageImageLocation(); - newPhoto = chatDefPhoto(colorIndex); + newPhoto = ImagePtr(); // photoFull = ImagePtr(); } break; } @@ -479,13 +598,13 @@ void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see newPhotoId = phId; } newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small); - newPhoto = newPhotoLoc.isNull() ? (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex)) : ImagePtr(newPhotoLoc); -// photoFull = ImagePtr(640, 640, d.vphoto_big, (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))); + newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc); +// photoFull = newPhoto ? ImagePtr(640, 640, d.vphoto_big, newPhoto) : ImagePtr(); } break; default: { newPhotoId = 0; newPhotoLoc = StorageImageLocation(); - newPhoto = (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex)); + newPhoto = ImagePtr(); // photoFull = ImagePtr(); } break; } diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index f30c21c4e..854d17175 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -204,9 +204,30 @@ static constexpr int kChatColorsCount = 4; static constexpr int kChannelColorsCount = 4; style::color peerColor(int index); -ImagePtr userDefPhoto(int index); -ImagePtr chatDefPhoto(int index); -ImagePtr channelDefPhoto(int index); + +class EmptyUserpic { +public: + EmptyUserpic(); + EmptyUserpic(int index, const QString &name); + + void set(int index, const QString &name); + void clear(); + + explicit operator bool() const { + return (_impl != nullptr); + } + + void paint(Painter &p, int x, int y, int outerWidth, int size) const; + QPixmap generate(int size); + + ~EmptyUserpic(); + +private: + class Impl; + std_::unique_ptr<Impl> _impl; + friend class Impl; + +}; static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL; @@ -292,9 +313,9 @@ public: style::color color; void setUserpic(ImagePtr userpic); - void paintUserpic(Painter &p, int size, int x, int y) const; - void paintUserpicLeft(Painter &p, int size, int x, int y, int w) const { - paintUserpic(p, size, rtl() ? (w - x - size) : x, y); + void paintUserpic(Painter &p, int x, int y, int size) const; + void paintUserpicLeft(Painter &p, int x, int y, int w, int size) const { + paintUserpic(p, rtl() ? (w - x - size) : x, y, size); } void loadUserpic(bool loadFirst = false, bool prior = true) { _userpic->load(loadFirst, prior); @@ -331,6 +352,7 @@ protected: ImagePtr _userpic; ImagePtr currentUserpic() const; + mutable EmptyUserpic _userpicEmpty; private: void fillNames(); diff --git a/Telegram/SourceFiles/ui/buttons/peer_avatar_button.cpp b/Telegram/SourceFiles/ui/buttons/peer_avatar_button.cpp index 136c04817..7b264c806 100644 --- a/Telegram/SourceFiles/ui/buttons/peer_avatar_button.cpp +++ b/Telegram/SourceFiles/ui/buttons/peer_avatar_button.cpp @@ -36,7 +36,7 @@ PeerAvatarButton::PeerAvatarButton(QWidget *parent, PeerData *peer, const style: void PeerAvatarButton::paintEvent(QPaintEvent *e) { if (_peer) { Painter p(this); - _peer->paintUserpic(p, _st.photoSize, (_st.size - _st.photoSize) / 2, (_st.size - _st.photoSize) / 2); + _peer->paintUserpic(p, (_st.size - _st.photoSize) / 2, (_st.size - _st.photoSize) / 2, _st.photoSize); } } diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index bf54efad0..ac338b93b 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -444,6 +444,11 @@ public: ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr()); ImagePtr(int32 width, int32 height) : Parent(internal::getImage(width, height)) { } + + explicit operator bool() const { + return (_data != nullptr) && !_data->isNull(); + } + }; inline QSize shrinkToKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index cfed32531..b83406a61 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -612,7 +612,7 @@ void Notification::updateNotifyDisplay() { if (!options.hideNameAndPhoto) { _history->peer->loadUserpic(true, true); - _history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); + _history->peer->paintUserpicLeft(p, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width(), st::notifyPhotoSize); } else { static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); icon.setDevicePixelRatio(cRetinaFactor()); @@ -680,7 +680,7 @@ void Notification::updatePeerPhoto() { auto img = _cache.toImage(); { Painter p(&img); - _peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); + _peer->paintUserpicLeft(p, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width(), st::notifyPhotoSize); } _cache = App::pixmapFromImageInPlace(std_::move(img)); update(); diff --git a/Telegram/SourceFiles/window/window_theme_preview.cpp b/Telegram/SourceFiles/window/window_theme_preview.cpp index 19b717f1f..3f1bc9d08 100644 --- a/Telegram/SourceFiles/window/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/window_theme_preview.cpp @@ -34,6 +34,63 @@ namespace Window { namespace Theme { namespace { +QString fillLetters(const QString &name) { + QList<QString> letters; + QList<int> levels; + auto level = 0; + auto letterFound = false; + auto ch = name.constData(), end = ch + name.size(); + while (ch != end) { + auto emojiLength = 0; + if (auto emoji = emojiFromText(ch, end, &emojiLength)) { + ch += emojiLength; + } else if (ch->isHighSurrogate()) { + ++ch; + if (ch != end && ch->isLowSurrogate()) { + ++ch; + } + } else if (!letterFound && ch->isLetterOrNumber()) { + letterFound = true; + if (ch + 1 != end && chIsDiac(*(ch + 1))) { + letters.push_back(QString(ch, 2)); + levels.push_back(level); + ++ch; + } else { + letters.push_back(QString(ch, 1)); + levels.push_back(level); + } + ++ch; + } else { + if (*ch == ' ') { + level = 0; + letterFound = false; + } else if (letterFound && *ch == '-') { + level = 1; + letterFound = true; + } + ++ch; + } + } + + // We prefer the second letter to be after ' ', but it can also be after '-'. + auto result = QString(); + if (!letters.isEmpty()) { + result += letters.front(); + auto bestIndex = 0; + auto bestLevel = 2; + for (auto i = letters.size(); i != 1;) { + if (levels[--i] < bestLevel) { + bestIndex = i; + bestLevel = levels[i]; + } + } + if (bestIndex > 0) { + result += letters[bestIndex]; + } + } + return result.toUpper(); +} + class Generator { public: Generator(const Instance &theme, const CurrentData ¤t); @@ -48,6 +105,7 @@ private: }; struct Row { Text name; + QString letters; enum class Type { User, Group, @@ -107,7 +165,7 @@ private: void paintBubble(const Bubble &bubble); void paintService(QString text); - void paintUserpic(int x, int y, Row::Type type, int index); + void paintUserpic(int x, int y, Row::Type type, int index, QString letters); void setTextPalette(const style::TextPalette &st); void restoreTextPalette(); @@ -156,6 +214,9 @@ void Generator::prepare() { void Generator::addRow(QString name, int peerIndex, QString date, QString text) { Row row; row.name.setText(st::msgNameStyle, name, _textNameOptions); + + row.letters = fillLetters(name); + row.peerIndex = peerIndex; row.date = date; row.text.setRichText(st::dialogsTextStyle, text, _textDlgOptions); @@ -503,7 +564,7 @@ void Generator::paintRow(const Row &row) { if (row.active || row.selected) { _p->fillRect(fullRect, row.active ? st::dialogsBgActive[_palette] : st::dialogsBgOver[_palette]); } - paintUserpic(x + st::dialogsPadding.x(), y + st::dialogsPadding.y(), row.type, row.peerIndex); + paintUserpic(x + st::dialogsPadding.x(), y + st::dialogsPadding.y(), row.type, row.peerIndex, row.letters); auto nameleft = x + st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; auto namewidth = x + fullWidth - nameleft - st::dialogsPadding.x(); @@ -763,38 +824,33 @@ void Generator::paintService(QString text) { _historyBottom = bubbleTop - st::msgServiceMargin.top(); } -void Generator::paintUserpic(int x, int y, Row::Type type, int index) { - const style::icon *userIcons[] = { - &st::historyPeer1UserpicPerson, - &st::historyPeer2UserpicPerson, - &st::historyPeer3UserpicPerson, - &st::historyPeer4UserpicPerson, - &st::historyPeer5UserpicPerson, - &st::historyPeer6UserpicPerson, - &st::historyPeer7UserpicPerson, - &st::historyPeer8UserpicPerson, +void Generator::paintUserpic(int x, int y, Row::Type type, int index, QString letters) { + style::color colors[] = { + st::historyPeer1UserpicBg, + st::historyPeer2UserpicBg, + st::historyPeer3UserpicBg, + st::historyPeer4UserpicBg, + st::historyPeer5UserpicBg, + st::historyPeer6UserpicBg, + st::historyPeer7UserpicBg, + st::historyPeer8UserpicBg, }; - const style::icon *chatIcons[] = { - &st::historyPeer1UserpicChat, - &st::historyPeer2UserpicChat, - &st::historyPeer3UserpicChat, - &st::historyPeer4UserpicChat, - }; - const style::icon *channelIcons[] = { - &st::historyPeer1UserpicChannel, - &st::historyPeer2UserpicChannel, - &st::historyPeer3UserpicChannel, - &st::historyPeer4UserpicChannel, - }; - auto userpic = (type == Row::Type::User) ? userIcons[index % base::array_size(userIcons)] : (type == Row::Type::Group) ? chatIcons[index % base::array_size(chatIcons)] : channelIcons[index % base::array_size(channelIcons)]; + auto color = colors[index % base::array_size(colors)]; - auto image = QImage(userpic->width() * cIntRetinaFactor(), userpic->height() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + auto image = QImage(st::dialogsPhotoSize * cIntRetinaFactor(), st::dialogsPhotoSize * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(cRetinaFactor()); + image.fill(color[_palette]->c); { Painter p(&image); - userpic->paint(p, 0, 0, userpic->width()); + auto fontsize = (st::dialogsPhotoSize * 13) / 33; + auto font = st::historyPeerUserpicFont->f; + font.setPixelSize(fontsize); + + p.setFont(font); + p.setBrush(Qt::NoBrush); + p.setPen(st::historyPeerUserpicFg[_palette]); + p.drawText(QRect(0, 0, st::dialogsPhotoSize, st::dialogsPhotoSize), letters, QTextOption(style::al_center)); } - image = std_::move(image).scaled(st::dialogsPhotoSize * cIntRetinaFactor(), st::dialogsPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); Images::prepareCircle(image); _p->drawImage(rtl() ? (_rect.width() - x - st::dialogsPhotoSize) : x, y, image); }