From 088d23d557a2dc1aa10ce457bdbbfefc16dd30d4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 13 Sep 2017 20:01:23 +0300 Subject: [PATCH] Start new Info section (profile + shared media). --- Telegram/Resources/icons/info_actions.png | Bin 0 -> 136 bytes Telegram/Resources/icons/info_actions@2x.png | Bin 0 -> 242 bytes Telegram/Resources/icons/info_add_member.png | Bin 0 -> 572 bytes .../Resources/icons/info_add_member@2x.png | Bin 0 -> 1224 bytes Telegram/Resources/icons/info_back.png | Bin 0 -> 224 bytes Telegram/Resources/icons/info_back@2x.png | Bin 0 -> 556 bytes Telegram/Resources/icons/info_close.png | Bin 0 -> 275 bytes Telegram/Resources/icons/info_close@2x.png | Bin 0 -> 575 bytes .../Resources/icons/info_common_groups.png | Bin 0 -> 551 bytes .../Resources/icons/info_common_groups@2x.png | Bin 0 -> 1192 bytes Telegram/Resources/icons/info_information.png | Bin 0 -> 593 bytes .../Resources/icons/info_information@2x.png | Bin 0 -> 1552 bytes Telegram/Resources/icons/info_media_audio.png | Bin 0 -> 588 bytes .../Resources/icons/info_media_audio@2x.png | Bin 0 -> 1148 bytes Telegram/Resources/icons/info_media_link.png | Bin 0 -> 398 bytes .../Resources/icons/info_media_link@2x.png | Bin 0 -> 1157 bytes Telegram/Resources/icons/info_media_photo.png | Bin 0 -> 337 bytes .../Resources/icons/info_media_photo@2x.png | Bin 0 -> 486 bytes Telegram/Resources/icons/info_media_round.png | Bin 0 -> 664 bytes .../Resources/icons/info_media_round@2x.png | Bin 0 -> 1326 bytes Telegram/Resources/icons/info_media_voice.png | Bin 0 -> 476 bytes .../Resources/icons/info_media_voice@2x.png | Bin 0 -> 1155 bytes Telegram/Resources/icons/info_members.png | Bin 0 -> 512 bytes Telegram/Resources/icons/info_members@2x.png | Bin 0 -> 1277 bytes .../Resources/icons/info_notifications.png | Bin 0 -> 570 bytes .../Resources/icons/info_notifications@2x.png | Bin 0 -> 1005 bytes Telegram/Resources/icons/top_bar_call.png | Bin 0 -> 436 bytes Telegram/Resources/icons/top_bar_call@2x.png | Bin 0 -> 905 bytes Telegram/Resources/icons/top_bar_profile.png | Bin 0 -> 194 bytes .../Resources/icons/top_bar_profile@2x.png | Bin 0 -> 350 bytes Telegram/Resources/icons/top_bar_search.png | Bin 0 -> 459 bytes .../Resources/icons/top_bar_search@2x.png | Bin 0 -> 1188 bytes Telegram/Resources/langs/lang.strings | 35 +- Telegram/SourceFiles/apiwrap.cpp | 29 +- Telegram/SourceFiles/base/variant.h | 16 + Telegram/SourceFiles/boxes/abstract_box.cpp | 2 +- Telegram/SourceFiles/boxes/abstract_box.h | 2 +- Telegram/SourceFiles/facades.cpp | 14 +- .../history/history_media_types.cpp | 9 +- Telegram/SourceFiles/info/info.style | 166 ++++++ .../info/info_common_groups_inner_widget.cpp | 63 ++ .../info/info_common_groups_inner_widget.h | 65 ++ .../info/info_common_groups_widget.cpp | 92 +++ .../info/info_common_groups_widget.h | 79 +++ Telegram/SourceFiles/info/info_layer_wrap.cpp | 164 ++++++ Telegram/SourceFiles/info/info_layer_wrap.h | 68 +++ .../info/info_media_inner_widget.cpp | 62 ++ .../info/info_media_inner_widget.h | 70 +++ .../SourceFiles/info/info_media_widget.cpp | 95 +++ Telegram/SourceFiles/info/info_media_widget.h | 91 +++ Telegram/SourceFiles/info/info_memento.cpp | 227 +++++++ Telegram/SourceFiles/info/info_memento.h | 223 +++++++ .../SourceFiles/info/info_narrow_wrap.cpp | 158 +++++ Telegram/SourceFiles/info/info_narrow_wrap.h | 112 ++++ .../info/info_profile_inner_widget.cpp | 211 +++++++ .../info/info_profile_inner_widget.h | 76 +++ .../SourceFiles/info/info_profile_lines.cpp | 555 ++++++++++++++++++ .../SourceFiles/info/info_profile_lines.h | 211 +++++++ .../SourceFiles/info/info_profile_widget.cpp | 94 +++ .../SourceFiles/info/info_profile_widget.h | 92 +++ Telegram/SourceFiles/info/info_side_wrap.cpp | 235 ++++++++ Telegram/SourceFiles/info/info_side_wrap.h | 122 ++++ Telegram/SourceFiles/info/info_top_bar.cpp | 84 +++ Telegram/SourceFiles/info/info_top_bar.h | 72 +++ Telegram/SourceFiles/rpl/combine_latest.h | 155 +++++ Telegram/SourceFiles/rpl/map.h | 123 +++- Telegram/SourceFiles/rpl/rpl.h | 1 + .../storage/storage_shared_media.h | 3 +- Telegram/SourceFiles/ui/text/text.cpp | 6 +- Telegram/SourceFiles/ui/widgets/checkbox.h | 7 + Telegram/SourceFiles/ui/widgets/shadow.h | 9 +- Telegram/SourceFiles/ui/widgets/widgets.style | 25 + Telegram/SourceFiles/ui/wrap/slide_wrap.cpp | 29 +- Telegram/SourceFiles/ui/wrap/slide_wrap.h | 14 +- Telegram/SourceFiles/window/section_memento.h | 14 +- .../SourceFiles/window/section_widget.cpp | 22 +- Telegram/SourceFiles/window/section_widget.h | 4 +- Telegram/gyp/Telegram.gyp | 1 + Telegram/gyp/telegram_sources.txt | 24 + Telegram/gyp/tests/tests.gyp | 1 + 80 files changed, 3969 insertions(+), 63 deletions(-) create mode 100644 Telegram/Resources/icons/info_actions.png create mode 100644 Telegram/Resources/icons/info_actions@2x.png create mode 100644 Telegram/Resources/icons/info_add_member.png create mode 100644 Telegram/Resources/icons/info_add_member@2x.png create mode 100644 Telegram/Resources/icons/info_back.png create mode 100644 Telegram/Resources/icons/info_back@2x.png create mode 100644 Telegram/Resources/icons/info_close.png create mode 100644 Telegram/Resources/icons/info_close@2x.png create mode 100644 Telegram/Resources/icons/info_common_groups.png create mode 100644 Telegram/Resources/icons/info_common_groups@2x.png create mode 100644 Telegram/Resources/icons/info_information.png create mode 100644 Telegram/Resources/icons/info_information@2x.png create mode 100644 Telegram/Resources/icons/info_media_audio.png create mode 100644 Telegram/Resources/icons/info_media_audio@2x.png create mode 100644 Telegram/Resources/icons/info_media_link.png create mode 100644 Telegram/Resources/icons/info_media_link@2x.png create mode 100644 Telegram/Resources/icons/info_media_photo.png create mode 100644 Telegram/Resources/icons/info_media_photo@2x.png create mode 100644 Telegram/Resources/icons/info_media_round.png create mode 100644 Telegram/Resources/icons/info_media_round@2x.png create mode 100644 Telegram/Resources/icons/info_media_voice.png create mode 100644 Telegram/Resources/icons/info_media_voice@2x.png create mode 100644 Telegram/Resources/icons/info_members.png create mode 100644 Telegram/Resources/icons/info_members@2x.png create mode 100644 Telegram/Resources/icons/info_notifications.png create mode 100644 Telegram/Resources/icons/info_notifications@2x.png create mode 100644 Telegram/Resources/icons/top_bar_call.png create mode 100644 Telegram/Resources/icons/top_bar_call@2x.png create mode 100644 Telegram/Resources/icons/top_bar_profile.png create mode 100644 Telegram/Resources/icons/top_bar_profile@2x.png create mode 100644 Telegram/Resources/icons/top_bar_search.png create mode 100644 Telegram/Resources/icons/top_bar_search@2x.png create mode 100644 Telegram/SourceFiles/info/info.style create mode 100644 Telegram/SourceFiles/info/info_common_groups_inner_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_common_groups_inner_widget.h create mode 100644 Telegram/SourceFiles/info/info_common_groups_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_common_groups_widget.h create mode 100644 Telegram/SourceFiles/info/info_layer_wrap.cpp create mode 100644 Telegram/SourceFiles/info/info_layer_wrap.h create mode 100644 Telegram/SourceFiles/info/info_media_inner_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_media_inner_widget.h create mode 100644 Telegram/SourceFiles/info/info_media_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_media_widget.h create mode 100644 Telegram/SourceFiles/info/info_memento.cpp create mode 100644 Telegram/SourceFiles/info/info_memento.h create mode 100644 Telegram/SourceFiles/info/info_narrow_wrap.cpp create mode 100644 Telegram/SourceFiles/info/info_narrow_wrap.h create mode 100644 Telegram/SourceFiles/info/info_profile_inner_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_profile_inner_widget.h create mode 100644 Telegram/SourceFiles/info/info_profile_lines.cpp create mode 100644 Telegram/SourceFiles/info/info_profile_lines.h create mode 100644 Telegram/SourceFiles/info/info_profile_widget.cpp create mode 100644 Telegram/SourceFiles/info/info_profile_widget.h create mode 100644 Telegram/SourceFiles/info/info_side_wrap.cpp create mode 100644 Telegram/SourceFiles/info/info_side_wrap.h create mode 100644 Telegram/SourceFiles/info/info_top_bar.cpp create mode 100644 Telegram/SourceFiles/info/info_top_bar.h create mode 100644 Telegram/SourceFiles/rpl/combine_latest.h diff --git a/Telegram/Resources/icons/info_actions.png b/Telegram/Resources/icons/info_actions.png new file mode 100644 index 0000000000000000000000000000000000000000..30c270a73b8e3c48eef4f64d87d3a8570ded7f0e GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdze@_?3kcif|R}HxiC$8QMkW@9JIi^E-#gEIviaX^)9v1W*_!GdEvH=& iy2c13xC9g&4lwhjh}r8kYNrE@X7F_Nb6Mw<&;$VB94wsx literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_actions@2x.png b/Telegram/Resources/icons/info_actions@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..65aa8cf4b3d0645ed16f665ed2c1f5ac7ee6c216 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=J3U<-Ln`LHy=lnBtSG_|$h-6Z z)Vo%iOo^?>ANgp%Fo>ur=`*}$F=M*e1rZ1C46X&NCaf2jW-(k}@P)~ZBkkJ4qEC{=u1d^2@6Fnt*oqUv=s|u6EF@DBnTn$ zZE^9UclWAsSC$1o7#MQCIr%Z?%rFuF;v4nrJAeKHcmccsz6799D4^HtK?ngM1iIZW z^7(wA9DH=-^LcK!Tau)0+ZXd(E_ZL9#{q`JAxW~;YB3UtFdB{0FbtC9U@-VRz)2s) zR8^(pIJ9k>vMm4o9u9{ogrMU%R8{pRz|)%W5BHtk|BY)q0DyzRfFx-c2BXm^W3d?9 z?KVlW-|s(Gf?GQG=5jgOwoQ^0LQn`nlH6=I%x1IC2RK1=IvrY;Ma#0->2!je07@r{ zYju<)>1G|1$s_<^y}IG)*&j6aK5i z;Q-6BkjZ2K0HILms{eRA0st0^1rmt_WLbXa2?Vg;@1ZCPR;$(BH=QI&NTpJ6T^EX? zyo(1q1-5O&_kG0U@gU3KI1YBZ-N%3kumjJ~&wmlU0A2t;9^egNCrW8u239=)0000< KMNUMnLSTY3%Ko?j literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_add_member@2x.png b/Telegram/Resources/icons/info_add_member@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a81e5bd06a080aa5fb67a887b13bb5a191bbef10 GIT binary patch literal 1224 zcmV;(1ULJMP)t3lgcNexvi3|cIO-ZO$ z5@FUtO(#Xk^IP0slG*rjb9(CD`M?8?bLKhU^JSj5p#T8kA4Wu40BHmRNDCm1U;t?W zq!A1tEr2wF0i*?xMlgW10MZBskQP81!2r?%Nb_wB7#kY{yWI}qa2Qgl6eN>L2#3S4 zva$jei-p(RNU|vu3Us+#n9t{ti+nzhPNx&)aycIw$Q7?tD)I2}khAdjxZQ44C=`E> z0c&e(RYhhp8T9-87zhL~lgU)wcRHPahXEFgrRud`UtdR!MuQB)Aj2@&)6;{So10a` zVRUr#=NsT~I4TO;*w{dkNK_Rk5{Ynod%GgmZnu*+pj0YVv}T@V7zQJeNX2WfQmHuO zH5v`FEL)DhxVS)uVScUwQmGV^$z-`8zu%7(MRCT9L?S#tKQG58lS!0Hr7bbw+w22s zfrvm+6fb=fF`!T=!0qjA`MR&K4^%1@XS_zE0j*YBzK+FWP$(2yqJ@Y7#bOb>UT^tY zCX>O!!UBjy)pBT>hQ-B2kVquu|GZu=6pO`{>G|?G007WzHdif!TU%SG)oRPjU~g|P z?(FPT#N=|huU!V;7usyA)wj##s@mvevsnxVgBT13D`x&z91ce-izjPuFR~G>Mp6!p0j^Nj?UvPSQ`Y9b;)HQ&M_r^3@Xgz3}28Lk(;P-0r^77J> ze!2Ko8zHe+3}UgE^O~2Oy!Kv$_V#wr>2#pgYC*5pLw|oiba!_{XJ;qK<#GT3$Ye5* zNF*Q@i$OFRg-9dCbsb2{YL zfT5wGhCX}cayh)ezsFE0gg&1SeLf$CLLp2f5;d2|SKMwl4h{}}odJ!s$;nB4e0=;+ za4MBTkH>>cOG`L4HHB)m8ap~VkYO04X&PyoMuuTfB9Wk4twyWWip$H(=<#?kolbw) zXCjfniHV8tVSvG4s5tY#a&>iuHk%ENMq|xy09=itC>$OhMw`us*Voro{U?)292giN zZ@}K(UWKr`yE~kln``NAPAZk+{QNw|7_0kFs2_EZcA_Z$sdx@U6ZFkU%hiv;fiw29Op&8o>b40!SkmKw1E41OrG5 mAdO%EX#u1W3?MClH2(p{gk79w4K(5a0000yONKtz0+d&62|9$_pO1&E6q=&eP)o6GKz;&$%tL8#re)L@@|53SJdbsqFA@aak%- zbgr|?#-IKBz3c}yje>Gc7Y@ Xg{{+FKaRgZCo_1u`njxgN@xNA{hL?0 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_back@2x.png b/Telegram/Resources/icons/info_back@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..aac5c40e952ed6f714a097ba73c057af9e9b0f0c GIT binary patch literal 556 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVEpXq;uumf=j{yNRfh~jTK%6i zHgOji|Klwc^owb>m}HVr_LS{Tr-Y!Drr(xIX5EM_d~rU0zi06q1?HUl`z}{kkU=NP zr(L$eSL6WS0X41!_5@+p4a^%lnQk!NaAADIkh6%PjKM6B!J0vO7K0+omTMQHoH-75 zF+QkM5USB!n$sB6HR<8TLwOo48lv$V;@00*bkI!wY@;ul-?MS^%{TSjD_-p}Jm#k+ z9QN@c%bwSNK2~g5e6b^PPd%gQyBY}~u_vC9_XUKIXXJgg2SofSXALR+S734DVZjN# zO+|knc&m6aX{Ns1{P}0k)1uD5b^Uew|F2!^l@j^vOLgOMi9b{QmNRRrPEx7-`L1lY zqHpk*D%O0G#@m0;kW$FqQBf37gT=SUBEb5AZ_s~&lLxo4bQll&TH8qy>E8Q<(DbXKUZ3_ zg!mrH+M3ng@Z3{lLeQqJ?dRB)>RmY+- zQ3}H#35Mv{-0v95D{qLdW;O8fC-p@{{ig# zPO3`GT-+-nWM;H&TQvfuGBW@`2m#Feb)SgfI1T`Ssus_ERe2LLBZQDeoWs5MS?Fy* zLc|yW05Qh5fQImTz!gG7TEp)F(rwR(#_;=q&nIsT$M88o)Np(6eX%<#>i2MFu4>UP zfZT7-wP+VWO{-nCXg5F_#iieVZc#Jq2XM|oRjZy>L||rE*R=|;B*myTd=5;&1Wdqi Zz!SAMJ`T)B?&AOe002ovPDHLkV1h-3a^(O3 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_close@2x.png b/Telegram/Resources/icons/info_close@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..94b5089f911446a102197912d195c0fabe92638e GIT binary patch literal 575 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU}E!haSW-L^LFOxqSXchF4pC( z`zB8B4WFTJr1fW}jriQ7YnM!lsFZYEom4t?+v8_nJTlG*Gdybi>YwYdmcxN4LU%nw zkKu-Ei`He&Pi18Ay?h|5Tg7wF^=193JrBQDse1AqK45cx?-kYqhaVm&l<}Mtd;Oxs z)eIzmB~y;L+(y3jK80V9#pH^Tw}t z@$oY-h`AOf|G4K@pnCuN-s@|h$}%v7g&xhE6;|4$T^S#pRm>1y>J%EPsJdUaq1rm} z`IGIeA8z{zsO-0GnC@4wSN7DV5cT~)V{}em`e}7~Q%~i*)syb?Gd#%qm^mx&T&L{h z`{F=OY2v5f%nU#m&lUK!FMZasYI_^`IvKV{VmF?*$Fx7N=v$xsZoVChef9a}nWuD4 zhn?qhWd3oI_xy7aNs)&8cRtkkOmt-2@jP#TS{D!3fmyrvE)f25vfEm*=Sl3`4|hR| zmSyhHIlbzMz20?^ojTm-pBGm!+}iea(x2l`Zv{<1t!l$?Ork9I`>j>cbrPPFRBRX+ zW~gwk-Ma7pcJ&YS-I3X~_BQk5G;CJM)yecRTw%M?MVP2!yX-yT@R8c0DZqrm;OXk; Jvd$@?2>`gP0p$Py literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_common_groups.png b/Telegram/Resources/icons/info_common_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..610fc18c1dbaee1557175571e0981c7407b4473b GIT binary patch literal 551 zcmV+?0@(eDP)~y$R8quuzPpRVphRZN{sH&^d;lH>s8lK#jYbecKnQ{1a0pG) z9)@6)qG=j;yB$f=^Sm#0RaGO+^}9qHFquq9lHG2X$z+nLREoV`k0fcD=6eAWi3EM$ zr{{T;W%*BgJRYYIg1+xFkw`=Wc&Q1=$DWl)#HMMIBzwIcQ>hfw=`{QOK1p&s9>3oM zs;biSJd&gkflMEQIk0N^;zqf_8# zl;CQ$idwA(UDr`87LiV;0RTb>tk-MIW;0BuQ_Sb{NDw!d$uJCBmc_pn1OaW^rfu5{ zg5XP^Wmz-~<24>=G#U)UkR-WSEZA2#uP+s~Wucs#;&U6e{C06;7jySks}^BDlJTCI@F z9)5xr?N8uWU-SSS>*mI{RedORLftJO{M^rMNNq`kcz4-XG(7XGt* zJ|Ai{n(qT(b#=9>$ZR%?p->3J;V@>i*{a_?9?$mxV7J?=9{aVmHPq|%$S@2t41?X> z-MF!_Q8gV#Mn=9q0Jqy+QP}$WI?80Ss&O)z47awnD#p58uCEP%VHk|Z;}ws+R;#T! zUa!|9&-3N+7Z(@EFwEBlpj0Z61ZimEwYCX?a$`FVLf$8o4sDn$kGsWw80 z2oyy%HK(Wmip3(_-rkn`y}iAl)oN>w*X#9QFc`}HWHJfGVo^+s;sOu^0Rn+Qxvx^G zV19lcWU}hCG)=?8!U8B1it=}XKmY_m5Yr+6i2H&;o6T0W3~p|2qQPJ&FM~ZjJ-EHS zT`?w~&wr0)5CG8Y^;T_ka=9EvA`y&4A{B4`lH6{0Gm38x0F6e2KA*3u$XYr$IB4d1 zpeadEtybg8$_nQ5`I?14KR=_(1i|VK+^$~MAI}d3$-w31C7hj|!QS2;gu`KYeSK}TRRCz<8 zKp=pEApG&N_d5xKfPTLpr>3UFI2|@7(BRE5uSsWi9{~Q3!W^=`vzoe_HD|9-YXt7v+c?VFd zQ51zkLqq6vI`R7Yx+*@$aoFGAPaeST?rw##ySqD_ot@l#j-3~ES829{&TZht@!ZpP|lZ1rN{$#f08>sJ{GO`Qad?0Dd*#PzV3K+Z-fxB z{F$OCXlZE?ZCgvzbj6j~``rJkhVBH-W-|l=frc3SNEAhZ$z*D5O!zSm{#ChL4wOn| zgY5jBc%BE9N>x{kx(`D%P1hTOXzseFz|+$cv7;={^L57{b|3Ir^r`+BAt4C>X#=Ds z0U&LFv?Kte4Um=ufV2V9k^qo4Kw1(2(gsLN0zldTY5fN|%Zer46tWEf0000B(QB8+qOw2leF7yR;!ht zHy8}CEbHe0*XF0wiB_u>nyZw;aU9O)vk&njfNHhsH_v1;PmeX5&H51Ka``m?t+nrY z(3f9z@2uT!1F+leux&d!K(pEOJrBwW15ir&J5jIKgLg~Ti|&fK&XFV7RdJ=0l2Ok-GaZRK!D@% zC?X=USnTEE@pxQBL=J~Tbb!TTAtECAeEwyCLZNU|D@b>}X*3!DtX3Zv062~l8KB$k0$_}J?I98oDwPTV=ku9tHv9DT%jI%hE*AhwrP8DP@M43( zz=v=gC(w@T*t^}X-@M=NKLZ?|U|E(Aaovedr$Z{0LTioInshqN*VmWtIY6)1`!m1e zYn01ncDo&qWQ=)c?9l;41lzW$*XvBDQ?}bJuIu8uE}PAU$z(#UR(rH?zuR`Dc$fa& fr}zW#-vImqVW%_*!X(CY00000NkvXXu0mjf*~}J| literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_information@2x.png b/Telegram/Resources/icons/info_information@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dd009125970731e3f43b5cb43c4663a8360527b5 GIT binary patch literal 1552 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 E06|s`9smFU literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_media_link.png b/Telegram/Resources/icons/info_media_link.png new file mode 100644 index 0000000000000000000000000000000000000000..376cdcef33a30aace5b6bc2c8e1b284edd7c0fa7 GIT binary patch literal 398 zcmV;90df9`P)ZrE5JiVb9$Y{{&4paK0&c-_Ny8RMW-a+9P}p+u(gfrr#u!JDqlhp4W_PszX|%KJ zi3svSy}dGg0aySQfCbZCe2b_qtwd+g7Z#VvG@0eF%av$8k*4G>oaQ z8&lIX#Bn@&{)caGsOk`2RTXKP5{BW_VT55wnx<4$1%Pu7-}mPOQW!dcT-dUCbV6B}Ga6X>_zO`>k*R|{Q8i3R3Gz##mW4KzaL`39r zxs29~0_^vD5fRyLx1ZKM&%5huZ8jSb5jh@@cR_Eq#ux)YS(Z;nUEPzyBL901LnZ@b3ZM0dcb{Lj7_JvH$=807*qoM6N<$f|b6fdjJ3c literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_media_link@2x.png b/Telegram/Resources/icons/info_media_link@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0a8acd780967a8daa84dddf82b09d4bfa49e3ad1 GIT binary patch literal 1157 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVDa&EaSW-L^LFN0Z>w05Sk&4vOJ5~ucLxub$_m$Rj;N5?Eem2<|FT{@ZL~>XQEK-Kc@AGCj$0zSAzQ?! zvYhOR+hC+S^RrIXuY(rX9?L$z{&eBb1CevIzt4OB_uQSCJHy!+1nLaAZZTyjOFKj} zQxD|CF zYimG!JipFqr`)w0j=X%Cd2=6MyYq#%jsOi2h1qAF)Fw0bJyyATy1^yAiI@c&Dz@9 zK0J89p#5}pp;l^ry*xWR`|4|d^E=+J3D79W%;b!Zi_;R*Z)NQ0@b~w(u($8$YHjLc z)H%KA`fF7o-KC84*Q{N;FlePnZo`ZA2Y2qs`1tv8-LmX!K781jgROajkJ`hxZ{MCa zjX!nf43ECMOG2briIuE{3}1oO+$Ou=;NS^fOA`_k9q+g}v}DJ|#{T&6Lt}^3@#DuW zY;1Z;OG|^+p0{5Zwz@DSg~i{`kEK*zPHw~I&7ae!HAJmFHg~RUW5?aQu~%M}O!D7j z@}1#(U*@V30}K?{o$iWO(hx^U6cerRP7DW5&OTzkcav2-@l8FDHol2|NZlv z{d@Mf^tydc4*zc~B`s|@(Su`};!BGo9O2-pX8+slRY*weT2lPcCB8m9T&H1txyNA#@(JPSFQ*E#V++uo6#$@kU1KDnuMbECy!gM_V72cH%>=I86*cv}X{LaF`7u4a|q zG%VUVXTjUQe`WLX^A$z792Eo@_TT5fm=VHtQht}C67#?He}3&hMr0O6%Fk!*50vhe V+m~O$0W4k^JYD@<);T3K0RWYO7|H+u literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_media_photo.png b/Telegram/Resources/icons/info_media_photo.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7fea3d88ddd43d77d6674790764125de03e73c GIT binary patch literal 337 zcmV-X0j~auP)7~>4$GyoBy z_kO(g-p}Tydwu8~)A+*xQ=`FPcyd*xF=os$#{6nvhXF`3r9^8jt+h-k&E_8SrZJ}g zJQ`VRS=aTS=F^zd0P;NFT4eVwy3c}DfRqvd?EW7BfUfH{Ar`-nb8c46uc~cZI_LJ+ jz&mv98n^*&fOqH{PWY^81+&GL00000NkvXXu0mjftvZrj literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_media_photo@2x.png b/Telegram/Resources/icons/info_media_photo@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3eeb6242ef0aa2007d1338232d117e9055406924 GIT binary patch literal 486 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU|j3z;uumf=j|-Vyk-Ld*Y;J> zJ6MgT&*xTn=5s=8NaL(=RNUl`Z!-)#`#fOhtk{`{3Q$~Y7DXry_^p0 z4#`Xx7%$9VKo**;y5N0vQrf3`!95!@KHn2I4!-~WrqH5gmd_vAoEJQ6bN-^`@>LI) zzqB$k-t~?9%o?!^f1+-5f1kH&-Q^P7IjNB=a-&1zw>C)R?>6;a%(dX@ijTRXSZ#_> zR+_GEC#Y$(?3H3t?>C$4zApdfguDE!{$s^*N4w7ZP&8+RxV}<(e6=Rybyk~QJ@TUS zKgC^T3VQx&vw!958Ck4L&OM#-XnWtZfLQ*nR&Xp+uxEu=D_Af-`0GT z;=Ib?G57SWN843G6cv`QxbyKLlb2Zi5{BQAe>x1-_khBnxQcQ9tvB_ed=OGM`wt%#F60gOKePgg&ebxsLQ05ko_Bme*a literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_media_round.png b/Telegram/Resources/icons/info_media_round.png new file mode 100644 index 0000000000000000000000000000000000000000..012cd90c52d2c4ce7fae6cc21f52ab573ab2a6b3 GIT binary patch literal 664 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 SyKeyt7Y0vPKbLh*2~7ZjYzglG literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_members.png b/Telegram/Resources/icons/info_members.png new file mode 100644 index 0000000000000000000000000000000000000000..9f3ca1cd05abf70cf6c2493442400c22f8fe860c GIT binary patch literal 512 zcmV+b0{{JqP)1Nm zW-^cFX$7WfVzF4@a=8EiPNx%As})SsyfI&2Usx`enatZ21VKQh6b-|;-Olqo`o8}o z=Isjp+=0ntLeKL^lHG3iN6gy-*8{ZHjN_QT@29@_6((&8SBp<2a|vzRhU>bJQX+~X zBuRoOiXf$g>$+&S+pujLv)K$vsT*@V9wDW~bUH<=)yfn|{Q}i$74!KVjYb3K^BJ4X z22x7w_j{DfWz=dl)a!MWN+kf_TYqH^hr=DSUa!&VbgBKCScRw|X$ z?kbfE`~5znD58||DYM;fUtdC!91e#sEzxK+BFU#rk|e3mijTT!Hk%j>1`oTt#%loKs0s$q78_~4nVX4(bxfqHXs^H15gwN z)6>)V^yw2cO@pRsh{xlYnwml|7;L$YS!hLj`SK-qcXwHj-Q8VIPENK==LXH1!Cz+d z{6KVFztX%_IxP(#5C|}z&l~2}*48*SHbzBJs3-~}kq8rsgzpFgi#8;L}y>pDqtb#;}p zEL*PA@&G&@4>e6ANoKQI_Vo1BtqlYM+}qnDNotx#kH=%VP9v@9ZBUY=W+g1uxhYKr zaB^~j@87=z0Q`PG`uh6n*7o)F!RPY<0Mh9+PEJlN*J+fdzCv%_yfNl(GMQvoSJ#Ca zzu(W#pFbOQQ&Us7rqe)cPN1i!hq+wNFqKFo7>Puvsw!1g<@osc8Pogw`NWrsg4;e4WNd@;egBK0sx$zo4YrH#%o!Y;dDBM>0F0=eaY4Md_IIiA@uh4qQAc%ilV^p_rvS;0swyg{E5B2J$(K8 z70F~0sZefkuE zKmZQM+2w~Mwzjsgw6uhHJdR8zgF>Nz-@ktY06IE4uGJ|Pi+KI|HQv8}Z+1w3`Zm*E zym)aYbxqSaGc&_*I83+OZ8~wc+s)C@QGWRF!FU3!eTva&v}qlZ92*<6ehRFttQZ|E zEG%$fV4&$k$l%~07Z(=|-R0$FI-O2SbSw|x=;(;#pEJ0ss!b2R)>KvH{{B8mvQ#QH z{Cxj^oui{8)AyM^2h`?TsZ_$@;i1{vuI2FX5T#NH06-Gua=B@p^Xto1m_7%P1OT{P zE(C)?xZUm>b#xiJuH(Uj2gYenk|e0AYAk$>>eRfN!SpWh>(?)MJRVdk736X`oSvRG z{VNVhxLhvyd_Kss3|-fe$z*PP607M%QjU9k!1ER455N$v- nb^xLch{g^;v;ool^8x$^&&TeiGIFJp00000NkvXXu0mjfJ5Onj literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_notifications.png b/Telegram/Resources/icons/info_notifications.png new file mode 100644 index 0000000000000000000000000000000000000000..651e78f2c024ea044841d7213662cd01675d19ce GIT binary patch literal 570 zcmV-A0>%A_P)@BOiTz z<*8G1I#18}oz8pS35f{ui!y$5^AErW;O_&JN+q#vTZ+Zvk05w1TYsYyegNL7f7#(~-<8O}TL1t607*qo IM6N<$f<3her~m)} literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/info_notifications@2x.png b/Telegram/Resources/icons/info_notifications@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fecc98ceff2dead09f7cfe7e40c8fff9e4bb92c4 GIT binary patch literal 1005 zcmVHySo0Z<2^)*s4~_xJb1)YKFJ0GytlLZwn6$$=DGEEdCy ziwkT@k|d19ViZ}NZ#>Jgcye-ruT>}%kY(AQ55VvDqoOD#0E(iZ-|u%c3rQ!)^E~)` zK2yEV=YwD{=y)E-Xira1V>X+`QmJIR`c0KeCCp?pI5|1_a~^@w(NWyr-+!~wZ)tCD z4@X8uzBhoSr6s(-zyEOKn<|&fm`Ef(EuW`J;WMW z0D!)}J{TJt13?f>zkPXm0Z|lTcX#(wa()Wg`T2R&G|g}|bzR4NK9BKu9D~82=@_2p zF&>ZO(b19VPS7+B=jP_V$0N|&+l#liw}u8Nih`@FtMB$$TU#>?mDktT7z%~HK7g&Q zEz{LoTwMIHPa=^p-9?+5n_nBi;NT#Z%Vk68_4W0R{Wdl>3|@D4cQ`OG@O1%*qG$+Q zEEbXH`HuZUp%6-vWbj;BS+Omz?f(R4XJ-xNgM$NjdV1>EPnKoK=ktcTnVFf6{a(vf z0A8;bqS0up+-NkQP$*dTJw85$Mx)UxN2AfULu)6p9Y7=!X_f2sI$T{{S@ylWyo7qa z-YQ2Tk*^8BpG~aYT371t%9!Wtun`P;PH4Y`vSPH#9RO_0O|nLasf~W zpq2}OIsmm?0Ct*bng)nyr)66qB50asiH|s=>Qft6?gYvg~ck>aZw^u)V!)TI~r00w76}VItFs7>0pB zAYiEDI1YApc7SDB$Y!&a{4Ehor_-kQc1}vuG)$+{9p|^aE>Nvjp}V`=iiKsVstP?l zJslluxf5)+$mz7KWU$-^3=a=~_~iutXQ;H>@1N%ai;uu}m*d|Eg~MSuJUoP zZ*Fd2VPV0s?}Z!(Aj>j5KR-h_9B#Y+?CcC=S#~s&ZHo-=-6kd`uu`d*hO~!=2NVRs z={(K@000yO0du(=%Cd~IEMqR0!}0NP$8-GpPSBkWQwN}y3xGNRwOjzy0jT8ypbkK- bUk~6f_yZl5yHWcm00000NkvXXu0mjfn{(0Y literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/top_bar_call.png b/Telegram/Resources/icons/top_bar_call.png new file mode 100644 index 0000000000000000000000000000000000000000..7951492693148c6a37ddc4d11ab3a71ef32d8d27 GIT binary patch literal 436 zcmV;l0ZaagP)z00!_cPHGj}L8L>UL0nt}p@@rmQ0N`*qBuUO@GupPD=o3P)*Xyy_Y_e1;F`v)t2M8hP z`+mF=^?E(-n@lG0OOaA?yC3s e3P=I}8t?%_l?Cau)~we60000 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/top_bar_call@2x.png b/Telegram/Resources/icons/top_bar_call@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f15093923961e976f437f874ffa40fd0bc0b20d0 GIT binary patch literal 905 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU=HwfaSW-L^LCb_w^pJ^TYt0E zi5U@w3j!W2TM(P4#K9HCwzap+^P1$F2zJF}~=_2dGl9ed(l6A>ORu6rJUR{SO#>^bXOWYpG z+!Nv)q@o+XFkQOAv_yQuF)@X`4JJ8EN)tKm-n|=WH~)WjY)s6B7cVrfTZA15+!@0c zcI0uPM%N*u{?#}98g9Sc_9ifN>Ks4y>mFh^SVX#APs{Zm|6I&!V{04vjiuQ!D?9tK z)Jdk<4ZnX^pPuKS;4o`hVQ)&K?}4{(*M2o{U07go#&i;^8RPWn(@Veh_Vz*~fBv-G zyLWHox7NdnMLT0+lK)GaF{Y=dfBEns;bwVNmDkgvnb|trIn%qEo115eFLY6AJa^9T zYsC#BqN9!X@|MIdfBroEo#C1dQl%C$H*ViHp4&8YrsPNeU2Y%kO9~1E)~{dx zp2=t?4^v}9$%SK_3QB9%t()a{@Y^>t8NT+C8^<_byn1!$?Acz=Lx2A40r3@-diwjF zuYWCPd|D)V`SRsUjne839UJ!S$+2S9*VmshXU?As#xZ)=zl$!=;97KXg{RZPfEBM* ze*CR-SsW-MFP~gnD;pdf{Nn9fS9f=I8#(?vdF7wE6_hIW#=Uv}ezr=8mZ*-7&J~{e zii(KR)mKVoZ{~=ptE+n~zkK8F-J>T?cocIRFdcpTag{@Kbo7gN@65h#+rC|Srcc<{ zf8DEBuYM-(;1UojI(zo)P{vI+b%5~=jKmr{`Jj~{cONn?h|sCyXLQrm)tz~dk8NcL z*UOS$&JP(C=AW0aGTU%RWs@Gc011lCTRDAR1&4Qqn zTb3~_ZfkEB>^}PH*W8cgT&;)B3nYYSh#Y$JMn|ZV#b{>F(uNql?=K_y4m)jLlqto_ z!xKC)ZZy=CLZk1L;>?`>Fr>|c8aYFgdKfF)U9 d{=`(rm=Pyj;k%Tb2bjeeJYD@<);T3K0RXGPqPPG6 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/top_bar_profile.png b/Telegram/Resources/icons/top_bar_profile.png new file mode 100644 index 0000000000000000000000000000000000000000..0d28dee1e94270059e967877fbb9ac6f731e39a2 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJPEQxdkcif|SADsh40%`{tlaMX zuD-?SrS7rT9fH~NqBZ<;9L)ayEseoP0jwfxg?W$csM=^N1`njxgN@xNA2hBxy literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/top_bar_profile@2x.png b/Telegram/Resources/icons/top_bar_profile@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7bfdc3bcb3af6737ca3b5b04d606defb82c33dd2 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU{v*VaSW-L^LD0TUaJEStFOpU zhJsA5JC_UheHESa&pY$Xzcb+#%DFoYcs#Tp9zAnP?u@vu!(xUl482Sjm`u1FxG!ih zpb2bY-m%-YrPpxHstHqPiU~e@w_PbDUG{k3{6qWRuT3}D9JS`Bdqz*<>s@8r{M3ze zZ*RMHudHF!`CpT_>3C<~H`o1eD*ML$b=I$0Ux+MV%@Ao2TM)<))!@dM!6?OwPvF@{ z#${(&@0n^;erH(rmo?>?Pk;2C!c6uZ>sHrZzB%W4Wp;h`s#ots1*guu5n^Git#s<{ m|2nHb@fCkG7vS~K9|jw{3%k}i2F?M78-u5-pUXO@geCygs*95V literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/top_bar_search.png b/Telegram/Resources/icons/top_bar_search.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1ac34e6a8cc6efa2aa574ac5dac9d5617560d7 GIT binary patch literal 459 zcmV;+0W|)JP)eE!-0I?{}uwe=A2`<+o7-G zI0oljd)AZIhuY!S>lI-b!nSQ#mIWaM*6TIuy6zCh0YMOS!{_t)(~Rr79m4ZGvw$qi z003ba_U57}0sy3GY8D`+1OV8!-J5e92LMo2)gZv6RlF*t6j_!0EI zlv2bw?>q9Lw4dSSav>t3>2%tg6GA-XjR8)l6A=-uR;%7z`}}x34gwHq-jVP70D!u# z;kxeA%wn;??REnIESF33dmxVE4iQBW9LE7;471q`o6V*ho+OF+JwWui30uUgN|FQs zP?jZx5M}{wd!C0hO;J@9nx?_|e8zsi@2FT18OUqLp0< zb&*Ag;i5K17s*l+D)arV8knzH*68mT%>xI{nVIwOyq`I9agYK4gg-0+=>Vj~10WrM zw0Hod1CSOEfOG)T;sKBjKw3Ni(g8?|2S7RiY4HF^2Oup`CCzJUYQShTg2`k8y}=_-=t zi&kF4hK2@QU0p4y@PC!fW^r+G5yfKh?*!1=+KRzouxNqlbQ2rfHN)rP$Wih7%JL==1q7pU)S}^LRWc z5D0z`fRC2_*47rbx3_;ecX)UhqtR%={K?75-vPj4v3z(2X__wCL#b3^AP``A+}+)w zN~Nl90JXKXczAfo3ckI){jK8Pn?|F-%gala*V58bbpz<@>%-UAS0->WnMAEt`(wZH z@o~)Ma*W^g^)<@n^6CZPcDq?;%p;7>Pt!on`^eKu0k%;^6E3sJ28Y3cS&tl>XAdyHgeThT@ zO-)T)EkUVNvc~0DRmH>^Kr|X<`ZP_0!C>HO2_}v7cNnhk=0s);7Q2|6{*W#OXQO(b0jaREl|Kzr4Jl*=#P`d&Sw=8A_$n>U|Ls z2n4vkzRn6Ai^Z_Hx%t~(gM)*Z$z)hw)6>(HES@_60Km@9PRwSrtl&pSN2t+gO7<|D z&3JQj!}2&iJw=&JR{a0~02dY(@LyeAT;SN)*ry*i>g(&#<#H7Oe0+RFy|0VF=D2l?VsVTg=y83qU;cys@ zMk5*whJt+#hvRnucyAhw2A7tWN&<0ma)L86Gt3Q7tJQvZTqRaQ+3o?wq);e8r_(`C zPYxUdGFTe34%@hr{vVO0d~%e**vj;N09?!Ai*I z^M3~b0HED&XNu3|a_IN_{}uoMz}eYZ%;j>pv$InczluKwt6hKoA0j*e(g8?|2S7Ri zY4HF^2OupT0O0000 *v) { return (v && v->template is()) ? &v->template get_unchecked() : nullptr; } +// Simplified visit +template +inline auto visit(Method &&method, const variant &value) { + return value.match(std::forward(method)); +} + +template +inline auto visit(Method &&method, variant &value) { + return value.match(std::forward(method)); +} + +template +inline auto visit(Method &&method, variant &&value) { + return value.match(std::forward(method)); +} + } // namespace base diff --git a/Telegram/SourceFiles/boxes/abstract_box.cpp b/Telegram/SourceFiles/boxes/abstract_box.cpp index 91dd88f7c..e90ce2ee6 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.cpp +++ b/Telegram/SourceFiles/boxes/abstract_box.cpp @@ -424,7 +424,7 @@ void AbstractBox::keyPressEvent(QKeyEvent *e) { BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxLayerTitleShadow) { } -BoxContentDivider::BoxContentDivider(QWidget *parent) : TWidget(parent) { +BoxContentDivider::BoxContentDivider(QWidget *parent) : RpWidget(parent) { } int BoxContentDivider::resizeGetHeight(int newWidth) { diff --git a/Telegram/SourceFiles/boxes/abstract_box.h b/Telegram/SourceFiles/boxes/abstract_box.h index 178629615..3ea435e8d 100644 --- a/Telegram/SourceFiles/boxes/abstract_box.h +++ b/Telegram/SourceFiles/boxes/abstract_box.h @@ -290,7 +290,7 @@ public: }; -class BoxContentDivider : public TWidget { +class BoxContentDivider : public Ui::RpWidget { public: BoxContentDivider(QWidget *parent); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 2abbde103..891fedfef 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "facades.h" #include "profile/profile_section_memento.h" +#include "info/info_memento.h" #include "core/click_handler_types.h" #include "media/media_clip_reader.h" #include "observer_peer.h" @@ -256,8 +257,17 @@ void autoplayMediaInlineAsync(const FullMsgId &msgId) { } void showPeerProfile(const PeerId &peer) { - if (auto main = App::main()) { - main->showWideSection(Profile::SectionMemento(App::peer(peer))); + //if (auto main = App::main()) { + // main->showWideSection(Profile::SectionMemento(App::peer(peer))); + //} + + if (auto window = App::wnd()) { + auto memento = Info::Memento(peer); + if (auto layer = memento.createLayer(window->controller())) { + window->showSpecialLayer(std::move(layer)); + } else { + App::main()->showWideSection(std::move(memento)); + } } } diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index ad69e985e..0de11b89c 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -1616,8 +1616,9 @@ void HistoryDocument::eraseFromOverview() { Storage::SharedMediaTypesMask HistoryDocument::sharedMediaTypes() const { using Type = Storage::SharedMediaType; if (_data->voice()) { - using Mask = Storage::SharedMediaTypesMask; - return Mask {}.added(Type::VoiceFile).added(Type::RoundVoiceFile); + return Storage::SharedMediaTypesMask{} + .added(Type::VoiceFile) + .added(Type::RoundVoiceFile); } else if (_data->song()) { if (_data->isMusic()) { return Type::MusicFile; @@ -2456,7 +2457,9 @@ int32 HistoryGif::addToOverview(AddToOverviewMethod method) { Storage::SharedMediaTypesMask HistoryGif::sharedMediaTypes() const { using Type = Storage::SharedMediaType; if (_data->isRoundVideo()) { - return Type::RoundVoiceFile; + return Storage::SharedMediaTypesMask{} + .added(Type::RoundFile) + .added(Type::RoundVoiceFile); } else if (_data->isGifv()) { return Type::GIF; } diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style new file mode 100644 index 000000000..a68fd297c --- /dev/null +++ b/Telegram/SourceFiles/info/info.style @@ -0,0 +1,166 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +using "basic.style"; + +using "boxes/boxes.style"; +using "ui/widgets/widgets.style"; + +infoScroll: ScrollArea(defaultScrollArea) { + bottomsh: 0px; + topsh: 0px; +} + +infoTopBarBackIcon: icon {{ "info_back", boxTitleCloseFg }}; +infoTopBarBackIconOver: icon {{ "info_back", boxTitleCloseFgOver }}; +infoTopBarHeight: boxLayerTitleHeight; +infoTopBarBack: IconButton(defaultIconButton) { + width: infoTopBarHeight; + height: infoTopBarHeight; + + icon: infoTopBarBackIcon; + iconOver: infoTopBarBackIconOver; + + rippleAreaPosition: point(6px, 6px); + rippleAreaSize: 44px; + ripple: RippleAnimation(defaultRippleAnimation) { + color: windowBgOver; + } +} + +infoLayerTopBarHeight: boxLayerTitleHeight; +infoLayerTopBarBackIcon: icon {{ "info_back", boxTitleCloseFg }}; +infoLayerTopBarBackIconOver: icon {{ "info_back", boxTitleCloseFgOver }}; +infoLayerTopBarBack: IconButton(infoTopBarBack) { + width: infoLayerTopBarHeight; + height: infoLayerTopBarHeight; + + icon: infoLayerTopBarBackIcon; + iconOver: infoLayerTopBarBackIconOver; +} +infoLayerTopBarCloseIcon: icon {{ "info_close", boxTitleCloseFg }}; +infoLayerTopBarCloseIconOver: icon {{ "info_close", boxTitleCloseFgOver }}; +infoLayerTopBarClose: IconButton(infoLayerTopBarBack) { + icon: infoLayerTopBarCloseIcon; + iconOver: infoLayerTopBarCloseIconOver; +} +infoLayerTopBar: InfoTopBar { + height: infoLayerTopBarHeight; + back: infoLayerTopBarBack; + title: boxTitle; + titlePosition: boxLayerTitlePosition; + bg: boxBg; +} + +infoMinimalWidth: 320px; +infoDesiredWidth: 360px; +infoMinimalLayerMargin: 48px; + +infoTabs: SettingsSlider(defaultTabsSlider) { + height: 55px; + barTop: 52px; + labelTop: 19px; +} + +infoProfilePhotoSize: 72px; +infoProfilePhotoLeft: 27px; +infoProfilePhotoTop: 22px; +infoProfilePhotoBottom: 22px; + +infoProfileNameLeft: 111px; +infoProfileNameRight: 20px; +infoProfileNameTop: 32px; +infoProfileNameLabel: FlatLabel(defaultFlatLabel) { + margin: margins(10px, 5px, 10px, 5px); + width: 160px; + maxHeight: 24px; + textFg: windowBoldFg; + style: TextStyle(defaultTextStyle) { + font: font(16px semibold); + linkFont: font(16px semibold); + linkFontOver: font(16px semibold underline); + } +} + +infoProfileStatusLeft: infoProfileNameLeft; +infoProfileStatusRight: infoProfileNameRight; +infoProfileStatusTop: 62px; +infoProfileStatusLabel: FlatLabel(infoProfileNameLabel) { + margin: margins(10px, 5px, 10px, 5px); + width: 160px; + maxHeight: 18px; + textFg: windowSubTextFg; + style: TextStyle(defaultTextStyle) { + font: normalFont; + linkFont: normalFont; + linkFontOver: normalFont; + } + palette: TextPalette(defaultTextPalette) { + linkFg: windowActiveTextFg; + } +} + +infoProfileToggleRight: 12px; +infoProfileToggleTop: 40px; + +infoProfileSkip: 12px; + +infoProfileLabeledPadding: margins(77px, 10px, 10px, 10px); +infoProfileSeparatorPadding: margins( + 73px, + infoProfileSkip, + 0px, + infoProfileSkip); + +infoIconFg: menuIconFg; +infoIconPosition: point(28px, 8px); +infoIconInformation: icon {{ "info_information", infoIconFg }}; +infoIconMembers: icon {{ "info_members", infoIconFg }}; +infoIconNotifications: icon {{ "info_notifications", infoIconFg }}; +infoIconActions: icon {{ "info_actions", infoIconFg }}; + +infoLabel: FlatLabel(defaultFlatLabel) { +} +infoLabeled: FlatLabel(defaultFlatLabel) { +} + +infoProfileButton: InfoProfileButton { + textFg: windowBoldFg; + textFgOver: windowBoldFgOver; + textBg: windowBg; + textBgOver: windowBgOver; + + font: semiboldFont; + + height: 22px; + padding: margins(80px, 8px, 8px, 8px); + + toggle: defaultMenuToggle; + toggleOver: defaultMenuToggleOver; + + ripple: defaultRippleAnimation; +} +infoNotificationsButton: InfoProfileButton(infoProfileButton) { + padding: margins(80px, 11px, 8px, 9px); +} +infoMainButton: InfoProfileButton(infoProfileButton) { + textFg: lightButtonFg; + textFgOver: lightButtonFgOver; +} diff --git a/Telegram/SourceFiles/info/info_common_groups_inner_widget.cpp b/Telegram/SourceFiles/info/info_common_groups_inner_widget.cpp new file mode 100644 index 000000000..48092280f --- /dev/null +++ b/Telegram/SourceFiles/info/info_common_groups_inner_widget.cpp @@ -0,0 +1,63 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_common_groups_inner_widget.h" + +#include "info/info_common_groups_widget.h" +#include "lang/lang_keys.h" +#include "styles/style_info.h" + +namespace Info { +namespace CommonGroups { + +InnerWidget::InnerWidget(QWidget *parent, not_null user) +: RpWidget(parent) +, _user(user) { + base::lambda launch = [this, &launch](int counter) { + QTimer::singleShot(500, this, [this, launch, counter] { + _rowsHeightFake += 300; + resizeToWidth(width(), _minHeight); + launch(counter - 1); + }); + }; + launch(10); +} + +void InnerWidget::visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) { + _visibleTop = visibleTop; + _visibleBottom = visibleBottom; +} + +void InnerWidget::saveState(not_null memento) { +} + +void InnerWidget::restoreState(not_null memento) { +} + +int InnerWidget::resizeGetHeight(int newWidth) { + auto rowsHeight = _rowsHeightFake; + return qMax(rowsHeight, _minHeight); +} + +} // namespace CommonGroups +} // namespace Info + diff --git a/Telegram/SourceFiles/info/info_common_groups_inner_widget.h b/Telegram/SourceFiles/info/info_common_groups_inner_widget.h new file mode 100644 index 000000000..f868ba23a --- /dev/null +++ b/Telegram/SourceFiles/info/info_common_groups_inner_widget.h @@ -0,0 +1,65 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include +#include "ui/rp_widget.h" + +namespace Info { +namespace CommonGroups { + +class Memento; + +class InnerWidget final : public Ui::RpWidget { +public: + InnerWidget(QWidget *parent, not_null user); + + not_null user() const { + return _user; + } + + void resizeToWidth(int newWidth, int minHeight) { + _minHeight = minHeight; + return RpWidget::resizeToWidth(newWidth); + } + + void saveState(not_null memento); + void restoreState(not_null memento); + +protected: + int resizeGetHeight(int newWidth) override; + void visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) override; + +private: + not_null _user; + + int _rowsHeightFake = 0; + int _visibleTop = 0; + int _visibleBottom = 0; + int _minHeight = 0; + +}; + +} // namespace CommonGroups +} // namespace Info + diff --git a/Telegram/SourceFiles/info/info_common_groups_widget.cpp b/Telegram/SourceFiles/info/info_common_groups_widget.cpp new file mode 100644 index 000000000..ac77ed70d --- /dev/null +++ b/Telegram/SourceFiles/info/info_common_groups_widget.cpp @@ -0,0 +1,92 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_common_groups_widget.h" + +#include "info/info_common_groups_inner_widget.h" +#include "ui/widgets/scroll_area.h" + +namespace Info { +namespace CommonGroups { + +object_ptr Memento::createWidget( + QWidget *parent, + Wrap wrap, + not_null controller, + const QRect &geometry) { + auto result = object_ptr( + parent, + wrap, + controller, + App::user(_userId)); + result->setInternalState(geometry, this); + return std::move(result); +} + +Widget::Widget( + QWidget *parent, + Wrap wrap, + not_null controller, + not_null user) +: ContentWidget(parent, wrap, controller) { + _inner = setInnerWidget(object_ptr(this, user)); +} + +not_null Widget::user() const { + return _inner->user(); +} + +bool Widget::showInternal(not_null memento) { + if (auto groupsMemento = dynamic_cast(memento.get())) { + if (groupsMemento->userId() == user()->bareId()) { + restoreState(groupsMemento); + return true; + } + } + return false; +} + +void Widget::setInternalState(const QRect &geometry, not_null memento) { + setGeometry(geometry); + myEnsureResized(this); + restoreState(memento); +} + +std::unique_ptr Widget::createMemento() { + auto result = std::make_unique(user()->bareId()); + saveState(result.get()); + return std::move(result); +} + +void Widget::saveState(not_null memento) { + memento->setScrollTop(scrollTopSave()); + _inner->saveState(memento); +} + +void Widget::restoreState(not_null memento) { + _inner->restoreState(memento); + auto scrollTop = memento->scrollTop(); + scrollTopRestore(memento->scrollTop()); + // TODO is setVisibleTopBottom called? +} + +} // namespace CommonGroups +} // namespace Info + diff --git a/Telegram/SourceFiles/info/info_common_groups_widget.h b/Telegram/SourceFiles/info/info_common_groups_widget.h new file mode 100644 index 000000000..ab742edc5 --- /dev/null +++ b/Telegram/SourceFiles/info/info_common_groups_widget.h @@ -0,0 +1,79 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include +#include "info/info_memento.h" + +namespace Info { +namespace CommonGroups { + +class InnerWidget; + +class Memento final : public ContentMemento { +public: + Memento(UserId userId) : _userId(userId) { + } + + object_ptr createWidget( + QWidget *parent, + Wrap wrap, + not_null controller, + const QRect &geometry) override; + + UserId userId() const { + return _userId; + } + +private: + UserId _userId = 0; + +}; + +class Widget final : public ContentWidget { +public: + Widget( + QWidget *parent, + Wrap wrap, + not_null controller, + not_null user); + + not_null user() const; + + bool showInternal( + not_null memento) override; + std::unique_ptr createMemento() override; + + void setInternalState( + const QRect &geometry, + not_null memento); + +private: + void saveState(not_null memento); + void restoreState(not_null memento); + + InnerWidget *_inner = nullptr; + +}; + +} // namespace CommonGroups +} // namespace Info + diff --git a/Telegram/SourceFiles/info/info_layer_wrap.cpp b/Telegram/SourceFiles/info/info_layer_wrap.cpp new file mode 100644 index 000000000..0788fc398 --- /dev/null +++ b/Telegram/SourceFiles/info/info_layer_wrap.cpp @@ -0,0 +1,164 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_layer_wrap.h" + +#include "info/info_memento.h" +#include "info/info_top_bar.h" +#include "ui/rp_widget.h" +#include "ui/widgets/buttons.h" +#include "window/section_widget.h" +#include "window/window_controller.h" +#include "window/main_window.h" +#include "styles/style_info.h" +#include "styles/style_settings.h" +#include "styles/style_window.h" +#include "styles/style_boxes.h" + +namespace Info { + +LayerWrap::LayerWrap( + not_null controller, + not_null memento) +: _topBar(createTopBar(controller, memento)) +, _content(createContent(controller, memento)) { + _content->desiredHeightValue() + | rpl::on_next([this](int height) { + _desiredHeight = height; + resizeToDesiredHeight(); + }) + | rpl::start(lifetime()); +} + +object_ptr LayerWrap::createTopBar( + not_null controller, + not_null memento) { + auto result = object_ptr( + this, + st::infoLayerTopBar); + result->addButton(object_ptr( + result.data(), + st::infoLayerTopBarClose)); + result->setTitle(TitleValue( + memento->section(), + App::peer(memento->peerId()))); + return result; +} + +object_ptr LayerWrap::createContent( + not_null controller, + not_null memento) { + return memento->content()->createWidget( + this, + Wrap::Layer, + controller, + controller->window()->rect()); +} + +void LayerWrap::showFinished() { +} + +void LayerWrap::parentResized() { + auto parentSize = parentWidget()->size(); + auto windowWidth = parentSize.width(); + auto newWidth = st::settingsMaxWidth; + auto newContentLeft = st::settingsMaxPadding; + if (windowWidth <= st::settingsMaxWidth) { + newWidth = windowWidth; + newContentLeft = st::settingsMinPadding; + if (windowWidth > st::windowMinWidth) { + // Width changes from st::windowMinWidth to st::settingsMaxWidth. + // Padding changes from st::settingsMinPadding to st::settingsMaxPadding. + newContentLeft += ((newWidth - st::windowMinWidth) * (st::settingsMaxPadding - st::settingsMinPadding)) / (st::settingsMaxWidth - st::windowMinWidth); + } + } else if (windowWidth < st::settingsMaxWidth + 2 * st::settingsMargin) { + newWidth = windowWidth - 2 * st::settingsMargin; + newContentLeft = st::settingsMinPadding; + if (windowWidth > st::windowMinWidth) { + // Width changes from st::windowMinWidth to st::settingsMaxWidth. + // Padding changes from st::settingsMinPadding to st::settingsMaxPadding. + newContentLeft += ((newWidth - st::windowMinWidth) * (st::settingsMaxPadding - st::settingsMinPadding)) / (st::settingsMaxWidth - st::windowMinWidth); + } + } + resizeToWidth(newWidth, newContentLeft); +} + +void LayerWrap::resizeToWidth(int newWidth, int newContentLeft) { + resize(newWidth, height()); + + _topBar->resizeToWidth(newWidth); + _topBar->moveToLeft(0, 0, newWidth); + + // Widget height depends on content height, so we + // resize it here, not in the resizeEvent() handler. + _content->resizeToWidth(newWidth); + _content->moveToLeft(0, _topBar->height(), newWidth); + + resizeToDesiredHeight(); +} + +void LayerWrap::resizeToDesiredHeight() { + if (!parentWidget()) return; + + auto parentSize = parentWidget()->size(); + auto windowWidth = parentSize.width(); + auto windowHeight = parentSize.height(); + auto maxHeight = _topBar->height() + _desiredHeight; + auto newHeight = maxHeight + st::boxRadius; + if (newHeight > windowHeight || width() >= windowWidth) { + newHeight = windowHeight; + } + + setRoundedCorners(newHeight < windowHeight); + + setGeometry((windowWidth - width()) / 2, (windowHeight - newHeight) / 2, width(), newHeight); + update(); +} + +void LayerWrap::setRoundedCorners(bool rounded) { + _roundedCorners = rounded; + setAttribute(Qt::WA_OpaquePaintEvent, !_roundedCorners); +} + +void LayerWrap::paintEvent(QPaintEvent *e) { + if (_roundedCorners) { + Painter p(this); + auto clip = e->rect(); + auto r = st::boxRadius; + auto parts = RectPart::None | 0; + if (clip.intersects({ 0, 0, width(), r })) { + parts |= RectPart::FullTop; + } + if (clip.intersects({ 0, height() - r, width(), r })) { + parts |= RectPart::FullBottom; + } + if (parts) { + App::roundRect( + p, + rect(), + st::boxBg, + BoxCorners, + nullptr, + parts); + } + } +} + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_layer_wrap.h b/Telegram/SourceFiles/info/info_layer_wrap.h new file mode 100644 index 000000000..2b499052b --- /dev/null +++ b/Telegram/SourceFiles/info/info_layer_wrap.h @@ -0,0 +1,68 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "layerwidget.h" + +namespace Window { +class Controller; +} // namespace Window + +namespace Info { + +class Memento; +class ContentWidget; +class TopBar; + +class LayerWrap : public LayerWidget { +public: + LayerWrap( + not_null controller, + not_null memento); + + void showFinished() override; + void parentResized() override; + +protected: + void paintEvent(QPaintEvent *e) override; + + void setRoundedCorners(bool roundedCorners); + +private: + object_ptr createTopBar( + not_null controller, + not_null memento); + object_ptr createContent( + not_null controller, + not_null memento); + + void resizeToWidth(int newWidth, int newContentLeft); + void resizeToDesiredHeight(); + + object_ptr _topBar; + object_ptr _content; + + int _desiredHeight = 0; + bool _roundedCorners = false; + +}; + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_media_inner_widget.cpp b/Telegram/SourceFiles/info/info_media_inner_widget.cpp new file mode 100644 index 000000000..068e3356e --- /dev/null +++ b/Telegram/SourceFiles/info/info_media_inner_widget.cpp @@ -0,0 +1,62 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_media_inner_widget.h" + +namespace Info { +namespace Media { + +InnerWidget::InnerWidget( + QWidget *parent, + not_null peer, + Type type) +: RpWidget(parent) +, _peer(peer) +, _type(type) { + base::lambda launch = [this, &launch](int counter) { + QTimer::singleShot(500, this, [this, launch, counter] { + _rowsHeightFake += 300; + resizeToWidth(width(), _minHeight); + launch(counter - 1); + }); + }; + launch(10); +} + +void InnerWidget::visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) { + _visibleTop = visibleTop; + _visibleBottom = visibleBottom; +} + +void InnerWidget::saveState(not_null memento) { +} + +void InnerWidget::restoreState(not_null memento) { +} + +int InnerWidget::resizeGetHeight(int newWidth) { + auto rowsHeight = _rowsHeightFake; + return qMax(rowsHeight, _minHeight); +} + +} // namespace Media +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_media_inner_widget.h b/Telegram/SourceFiles/info/info_media_inner_widget.h new file mode 100644 index 000000000..eae591325 --- /dev/null +++ b/Telegram/SourceFiles/info/info_media_inner_widget.h @@ -0,0 +1,70 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "ui/rp_widget.h" +#include "info/info_media_widget.h" + +namespace Info { +namespace Media { + +class InnerWidget final : public Ui::RpWidget { +public: + using Type = Widget::Type; + InnerWidget( + QWidget *parent, + not_null peer, + Type type); + + not_null peer() const { + return _peer; + } + Type type() const { + return _type; + } + + void resizeToWidth(int newWidth, int minHeight) { + _minHeight = minHeight; + return RpWidget::resizeToWidth(newWidth); + } + + void saveState(not_null memento); + void restoreState(not_null memento); + +protected: + int resizeGetHeight(int newWidth) override; + void visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) override; + +private: + not_null _peer; + Type _type = Type::Photo; + + int _rowsHeightFake = 0; + int _visibleTop = 0; + int _visibleBottom = 0; + int _minHeight = 0; + +}; + +} // namespace Media +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_media_widget.cpp b/Telegram/SourceFiles/info/info_media_widget.cpp new file mode 100644 index 000000000..b6ea88362 --- /dev/null +++ b/Telegram/SourceFiles/info/info_media_widget.cpp @@ -0,0 +1,95 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_media_widget.h" + +#include "info/info_media_inner_widget.h" +#include "ui/widgets/scroll_area.h" + +namespace Info { +namespace Media { + +object_ptr Memento::createWidget( + QWidget *parent, + Wrap wrap, + not_null controller, + const QRect &geometry) { + auto result = object_ptr( + parent, + wrap, + controller, + App::peer(_peerId), + _type); + result->setInternalState(geometry, this); + return std::move(result); +} + +Widget::Widget( + QWidget *parent, + Wrap wrap, + not_null controller, + not_null peer, + Type type) +: ContentWidget(parent, wrap, controller) { + _inner = setInnerWidget(object_ptr(this, peer, type)); +} + +not_null Widget::peer() const { + return _inner->peer(); +} + +Widget::Type Widget::type() const { + return _inner->type(); +} + +bool Widget::showInternal(not_null memento) { + if (auto mediaMemento = dynamic_cast(memento.get())) { + if (mediaMemento->peerId() == peer()->id) { + restoreState(mediaMemento); + return true; + } + } + return false; +} + +void Widget::setInternalState(const QRect &geometry, not_null memento) { + setGeometry(geometry); + myEnsureResized(this); + restoreState(memento); +} + +std::unique_ptr Widget::createMemento() { + auto result = std::make_unique(peer()->id, type()); + saveState(result.get()); + return std::move(result); +} + +void Widget::saveState(not_null memento) { + memento->setScrollTop(scrollTopSave()); + _inner->saveState(memento); +} + +void Widget::restoreState(not_null memento) { + _inner->restoreState(memento); + scrollTopRestore(memento->scrollTop()); +} + +} // namespace Media +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_media_widget.h b/Telegram/SourceFiles/info/info_media_widget.h new file mode 100644 index 000000000..6fa19e163 --- /dev/null +++ b/Telegram/SourceFiles/info/info_media_widget.h @@ -0,0 +1,91 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include +#include "info/info_memento.h" +#include "storage/storage_shared_media.h" + +namespace Info { +namespace Media { + +class InnerWidget; + +class Memento final : public ContentMemento { +public: + using Type = Storage::SharedMediaType; + + Memento(PeerId peerId, Type type) + : _peerId(peerId) + , _type(type) { + } + + object_ptr createWidget( + QWidget *parent, + Wrap wrap, + not_null controller, + const QRect &geometry) override; + + PeerId peerId() const { + return _peerId; + } + Type type() const { + return _type; + } + +private: + PeerId _peerId = 0; + Type _type = Type::Photo; + +}; + +class Widget final : public ContentWidget { +public: + using Type = Memento::Type; + + Widget( + QWidget *parent, + Wrap wrap, + not_null controller, + not_null peer, + Type type); + + not_null peer() const; + Type type() const; + + bool showInternal( + not_null memento) override; + std::unique_ptr createMemento() override; + + void setInternalState( + const QRect &geometry, + not_null memento); + +private: + void saveState(not_null memento); + void restoreState(not_null memento); + + InnerWidget *_inner = nullptr; + +}; + +} // namespace Media +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_memento.cpp b/Telegram/SourceFiles/info/info_memento.cpp new file mode 100644 index 000000000..2f1733b41 --- /dev/null +++ b/Telegram/SourceFiles/info/info_memento.cpp @@ -0,0 +1,227 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_memento.h" + +#include +#include "window/window_controller.h" +#include "ui/widgets/scroll_area.h" +#include "lang/lang_keys.h" +#include "info/info_profile_widget.h" +#include "info/info_media_widget.h" +#include "info/info_common_groups_widget.h" +#include "info/info_layer_wrap.h" +#include "info/info_narrow_wrap.h" +#include "info/info_side_wrap.h" +#include "styles/style_info.h" +#include "styles/style_profile.h" + +namespace Info { + +ContentWidget::ContentWidget( + QWidget *parent, + Wrap wrap, + not_null controller) +: RpWidget(parent) +, _controller(controller) +, _wrap(wrap) +, _scroll(this, st::infoScroll) { + setAttribute(Qt::WA_OpaquePaintEvent); +} + +void ContentWidget::resizeEvent(QResizeEvent *e) { + auto newScrollTop = _scroll->scrollTop() + _topDelta; + auto scrollGeometry = rect().marginsRemoved( + QMargins(0, _scrollTopSkip, 0, 0)); + if (_scroll->geometry() != scrollGeometry) { + _scroll->setGeometry(scrollGeometry); + _inner->setMinimumHeight(_scroll->height()); + _inner->resizeToWidth(_scroll->width()); + } + + if (!_scroll->isHidden()) { + if (_topDelta) { + _scroll->scrollToY(newScrollTop); + } + auto scrollTop = _scroll->scrollTop(); + _inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height()); + } +} + +void ContentWidget::paintEvent(QPaintEvent *e) { + Painter p(this); + p.fillRect(e->rect(), (_wrap == Wrap::Layer) + ? st::boxBg + : st::profileBg); +} + +void ContentWidget::setGeometryWithTopMoved( + const QRect &newGeometry, + int topDelta) { + _topDelta = topDelta; + auto willBeResized = (size() != newGeometry.size()); + if (geometry() != newGeometry) { + setGeometry(newGeometry); + } + if (!willBeResized) { + QResizeEvent fake(size(), size()); + QApplication::sendEvent(this, &fake); + } + _topDelta = 0; +} + +Ui::RpWidget *ContentWidget::doSetInnerWidget( + object_ptr inner, + int scrollTopSkip) { + _inner = _scroll->setOwnedWidget(std::move(inner)); + _inner->move(0, 0); + + scrollTopValue() + | rpl::on_next([this, inner = _inner](int value) { + inner->setVisibleTopBottom( + value, + value + _scroll->height()); // TODO rpl::combine_latest + }) + | rpl::start(_inner->lifetime()); + return _inner; +} + +rpl::producer
ContentWidget::sectionRequest() const { + return rpl::never
(); +} + +rpl::producer ContentWidget::desiredHeightValue() const { + return _inner->desiredHeightValue() + | rpl::map([this](int value) { + return value + _scrollTopSkip; + }); +} + +rpl::producer ContentWidget::scrollTopValue() const { + return _scroll->scrollTopValue(); +} + +void ContentWidget::setWrap(Wrap wrap) { + _wrap = wrap; + update(); +} + +int ContentWidget::scrollTopSave() const { + return _scroll->scrollTop(); +} + +void ContentWidget::scrollTopRestore(int scrollTop) { + _scroll->scrollToY(scrollTop); +} + +bool ContentWidget::wheelEventFromFloatPlayer(QEvent *e) { + return _scroll->viewportEvent(e); +} + +QRect ContentWidget::rectForFloatPlayer() const { + return mapToGlobal(_scroll->geometry()); +} + +std::unique_ptr Memento::Default( + PeerId peerId, + Section section) { + switch (section.type()) { + case Section::Type::Profile: + return std::make_unique(peerId); + case Section::Type::Media: + return std::make_unique( + peerId, + section.mediaType()); + case Section::Type::CommonGroups: + Assert(peerIsUser(peerId)); + return std::make_unique( + peerToUser(peerId)); + } + Unexpected("Wrong section type in Info::Memento::Default()"); +} + +object_ptr Memento::createWidget( + QWidget *parent, + not_null controller, + const QRect &geometry) { + return object_ptr( + parent, + controller, + this); +} + +object_ptr Memento::createLayer( + not_null controller) { + auto layout = controller->computeColumnLayout(); + auto minimalWidthForLayer = st::infoMinimalWidth + + 2 * st::infoMinimalLayerMargin; + if (layout.bodyWidth < minimalWidthForLayer) { + return nullptr; + } + return object_ptr(controller, this); +} + +rpl::producer TitleValue( + const Section §ion, + not_null peer) { + return Lang::Viewer([&] { + switch (section.type()) { + case Section::Type::Profile: + if (auto user = peer->asUser()) { + return user->botInfo + ? lng_info_bot_title + : lng_info_user_title; + } else if (auto channel = peer->asChannel()) { + return channel->isMegagroup() + ? lng_info_group_title + : lng_info_channel_title; + } else if (peer->isChat()) { + return lng_info_group_title; + } + Unexpected("Bad peer type in Info::TitleValue()"); + + case Section::Type::Media: + switch (section.mediaType()) { + case Section::MediaType::Photo: + return lng_media_type_photos; + case Section::MediaType::Video: + return lng_media_type_videos; + case Section::MediaType::MusicFile: + return lng_media_type_songs; + case Section::MediaType::File: + return lng_media_type_files; + case Section::MediaType::VoiceFile: + return lng_media_type_audios; + case Section::MediaType::Link: + return lng_media_type_links; + case Section::MediaType::RoundFile: + return lng_media_type_rounds; + } + Unexpected("Bad media type in Info::TitleValue()"); + + case Section::Type::CommonGroups: + return lng_profile_common_groups_section; + + } + Unexpected("Bad section type in Info::TitleValue()"); + }()); +} + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_memento.h b/Telegram/SourceFiles/info/info_memento.h new file mode 100644 index 000000000..75fa8d058 --- /dev/null +++ b/Telegram/SourceFiles/info/info_memento.h @@ -0,0 +1,223 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/section_memento.h" +#include "ui/rp_widget.h" + +namespace Storage { +enum class SharedMediaType : char; +} // namespace Storage + +namespace Ui { +class ScrollArea; +} // namespace Ui + +namespace Info { + +enum class Wrap { + Layer, + Narrow, + Side, +}; + +class Section final { +public: + enum class Type { + Profile, + Media, + CommonGroups, + }; + using MediaType = Storage::SharedMediaType; + + Section(Type type) : _type(type) { + Expects(type != Type::Media); + } + Section(MediaType mediaType) + : _type(Type::Media) + , _mediaType(mediaType) { + } + + Type type() const { + return _type; + } + MediaType mediaType() const { + Expects(_type == Type::Media); + return _mediaType; + } + +private: + Type _type; + Storage::SharedMediaType _mediaType; + +}; + +class ContentMemento; + +class ContentWidget : public Ui::RpWidget { +public: + ContentWidget( + QWidget *parent, + Wrap wrap, + not_null controller); + + virtual bool showInternal( + not_null memento) = 0; + virtual std::unique_ptr createMemento() = 0; + + virtual rpl::producer
sectionRequest() const; + + virtual void setWrap(Wrap wrap); + + rpl::producer desiredHeightValue() const override; + + virtual void setInnerFocus() { + _inner->setFocus(); + } + + // When resizing the widget with top edge moved up or down and we + // want to add this top movement to the scroll position, so inner + // content will not move. + void setGeometryWithTopMoved( + const QRect &newGeometry, + int topDelta); + + // Float player interface. + bool wheelEventFromFloatPlayer(QEvent *e); + QRect rectForFloatPlayer() const; + +protected: + template + Widget *setInnerWidget( + object_ptr inner, + int scrollTopSkip = 0) { + return static_cast( + doSetInnerWidget(std::move(inner), scrollTopSkip)); + } + + not_null controller() const { + return _controller; + } + Wrap wrap() const { + return _wrap; + } + + void resizeEvent(QResizeEvent *e) override; + void paintEvent(QPaintEvent *e) override; + + rpl::producer scrollTopValue() const; + int scrollTopSave() const; + void scrollTopRestore(int scrollTop); + +private: + RpWidget *doSetInnerWidget( + object_ptr inner, + int scrollTopSkip); + + not_null _controller; + Wrap _wrap = Wrap::Layer; + + int _scrollTopSkip = 0; + object_ptr _scroll; + Ui::RpWidget *_inner = nullptr; + + // Saving here topDelta in setGeometryWithTopMoved() to get it passed to resizeEvent(). + int _topDelta = 0; + +}; + +class ContentMemento { +public: + virtual object_ptr createWidget( + QWidget *parent, + Wrap wrap, + not_null controller, + const QRect &geometry) = 0; + + virtual ~ContentMemento() = default; + + void setScrollTop(int scrollTop) { + _scrollTop = scrollTop; + } + int scrollTop() const { + return _scrollTop; + } + +private: + int _scrollTop = 0; + +}; + +class Memento final : public Window::SectionMemento { +public: + Memento(PeerId peerId) + : Memento(peerId, Section::Type::Profile) { + } + Memento(PeerId peerId, Section section) + : Memento(peerId, section, Default(peerId, section)) { + } + Memento( + PeerId peerId, + Section section, + std::unique_ptr content) + : _peerId(peerId) + , _section(section) + , _content(std::move(content)) { + } + + object_ptr createWidget( + QWidget *parent, + not_null controller, + const QRect &geometry) override; + + object_ptr createLayer( + not_null controller) override; + + void setInner(std::unique_ptr content) { + _content = std::move(content); + } + not_null content() { + return _content.get(); + } + + PeerId peerId() const { + return _peerId; + } + Section section() const { + return _section; + } + +private: + static std::unique_ptr Default( + PeerId peerId, + Section section); + + PeerId _peerId = 0; + Section _section = Section::Type::Profile; + std::unique_ptr _content; + +}; + +rpl::producer TitleValue( + const Section §ion, + not_null peer); + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_narrow_wrap.cpp b/Telegram/SourceFiles/info/info_narrow_wrap.cpp new file mode 100644 index 000000000..620138535 --- /dev/null +++ b/Telegram/SourceFiles/info/info_narrow_wrap.cpp @@ -0,0 +1,158 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_narrow_wrap.h" + +#include +#include "info/info_profile_widget.h" +#include "info/info_media_widget.h" +#include "info/info_memento.h" +#include "ui/widgets/discrete_sliders.h" +#include "ui/widgets/shadow.h" +#include "lang/lang_keys.h" +#include "styles/style_info.h" +#include "styles/style_profile.h" + +namespace Info { + +NarrowWrap::NarrowWrap( + QWidget *parent, + not_null controller, + not_null memento) +: Window::SectionWidget(parent, controller) +, _peer(App::peer(memento->peerId())) { + setInternalState(geometry(), memento); +} + +void NarrowWrap::showInner(object_ptr inner) { + _inner = std::move(inner); + _inner->setGeometry(innerGeometry()); + _inner->show(); + + _desiredHeights.fire(desiredHeightForInner()); +} + +rpl::producer NarrowWrap::desiredHeightForInner() const { + return _inner->desiredHeightValue(); +} + +object_ptr NarrowWrap::createProfileWidget() { + auto result = object_ptr( + this, + Wrap::Narrow, + controller(), + _peer); + return result; +} + +object_ptr NarrowWrap::createMediaWidget() { + auto result = object_ptr( + this, + Wrap::Narrow, + controller(), + _peer, + Media::Widget::Type::Photo); + return result; +} + +QPixmap NarrowWrap::grabForShowAnimation( + const Window::SectionSlideParams ¶ms) { +// if (params.withTopBarShadow) _tabsShadow->hide(); + auto result = myGrab(this); +// if (params.withTopBarShadow) _tabsShadow->show(); + return result; +} + +void NarrowWrap::doSetInnerFocus() { + _inner->setInnerFocus(); +} + +bool NarrowWrap::showInternal( + not_null memento) { + if (auto infoMemento = dynamic_cast(memento.get())) { + if (infoMemento->peerId() == peer()->id) { + restoreState(infoMemento); + return true; + } + } + return false; +} + +void NarrowWrap::setInternalState( + const QRect &geometry, + not_null memento) { + setGeometry(geometry); + restoreState(memento); +} + +std::unique_ptr NarrowWrap::createMemento() { + auto result = std::make_unique(peer()->id); + saveState(result.get()); + return std::move(result); +} + +rpl::producer NarrowWrap::desiredHeight() const { + return + rpl::single(desiredHeightForInner()) + | rpl::then(_desiredHeights.events()) + | rpl::flatten_latest(); +} + +void NarrowWrap::saveState(not_null memento) { + memento->setInner(_inner->createMemento()); +} + +QRect NarrowWrap::innerGeometry() const { + return rect(); +} + +void NarrowWrap::restoreState(not_null memento) { + showInner(memento->content()->createWidget( + this, + Wrap::Narrow, + controller(), + innerGeometry())); +} + +void NarrowWrap::resizeEvent(QResizeEvent *e) { + if (_inner) { + _inner->setGeometry(innerGeometry()); + } +} + +void NarrowWrap::paintEvent(QPaintEvent *e) { + Painter p(this); + p.fillRect(e->rect(), st::profileBg); +} + +bool NarrowWrap::wheelEventFromFloatPlayer( + QEvent *e, + Window::Column myColumn, + Window::Column playerColumn) { + return _inner->wheelEventFromFloatPlayer(e); +} + +QRect NarrowWrap::rectForFloatPlayer( + Window::Column myColumn, + Window::Column playerColumn) const { + return _inner->rectForFloatPlayer(); +} + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_narrow_wrap.h b/Telegram/SourceFiles/info/info_narrow_wrap.h new file mode 100644 index 000000000..9d38ce069 --- /dev/null +++ b/Telegram/SourceFiles/info/info_narrow_wrap.h @@ -0,0 +1,112 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include +#include "window/section_widget.h" + +namespace Ui { +class PlainShadow; +class SettingsSlider; +} // namespace Ui + +namespace Info { +namespace Profile { +class Widget; +} // namespace Profile + +namespace Media { +class Widget; +} // namespace Media + +class Memento; +class ContentWidget; + +class NarrowWrap final : public Window::SectionWidget { +public: + NarrowWrap( + QWidget *parent, + not_null controller, + not_null memento); + + not_null peer() const { + return _peer; + } + PeerData *peerForDialogs() const override { + return _peer; + } + + bool hasTopBarShadow() const override { + return true; + } + + QPixmap grabForShowAnimation( + const Window::SectionSlideParams ¶ms) override; + + bool showInternal( + not_null memento) override; + std::unique_ptr createMemento() override; + + rpl::producer desiredHeight() const override; + + void setInternalState( + const QRect &geometry, + not_null memento); + + // Float player interface. + bool wheelEventFromFloatPlayer( + QEvent *e, + Window::Column myColumn, + Window::Column playerColumn) override; + QRect rectForFloatPlayer( + Window::Column myColumn, + Window::Column playerColumn) const override; + +protected: + void resizeEvent(QResizeEvent *e) override; + void paintEvent(QPaintEvent *e) override; + + void doSetInnerFocus() override; + +private: + void saveState(not_null memento); + void restoreState(not_null memento); + + QRect innerGeometry() const; + rpl::producer desiredHeightForInner() const; + + void showInner(object_ptr inner); + + object_ptr createProfileWidget(); + object_ptr createMediaWidget(); + + not_null _peer; + + object_ptr _tabsShadow = { nullptr }; + object_ptr _inner = { nullptr }; + + rpl::event_stream> _desiredHeights; + + rpl::lifetime _lifetime; + +}; + +} // namespace Info diff --git a/Telegram/SourceFiles/info/info_profile_inner_widget.cpp b/Telegram/SourceFiles/info/info_profile_inner_widget.cpp new file mode 100644 index 000000000..77f21ecd8 --- /dev/null +++ b/Telegram/SourceFiles/info/info_profile_inner_widget.cpp @@ -0,0 +1,211 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "info/info_profile_inner_widget.h" + +#include +#include "boxes/abstract_box.h" +#include "mainwidget.h" +#include "info/info_profile_widget.h" +#include "info/info_profile_lines.h" +#include "lang/lang_keys.h" +#include "styles/style_info.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" + +namespace Info { +namespace Profile { + +InnerWidget::InnerWidget(QWidget *parent, not_null peer) +: RpWidget(parent) +, _peer(peer) +, _content(this) { + setupContent(); +} + +void InnerWidget::setupContent() { + auto hideDetails = (_peer->isChat() || _peer->isMegagroup()); + auto cover = _content->add(object_ptr(this, _peer)); + if (hideDetails) { + auto hiddenDetailsContent = setupDetailsContent(_content); + auto hiddenDetails = _content->add(object_ptr>( + this, + std::move(hiddenDetailsContent))); + cover->setHasToggle(true); + cover->toggled() + | rpl::on_next([=](bool expanded) { + hiddenDetails->toggleAnimated(expanded); + }) | rpl::start(_lifetime); + hiddenDetails->hideFast(); + } else { + _content->add(setupDetailsContent(_content)); + } + _content->add(object_ptr(this)); + + _content->heightValue() + | rpl::on_next([this](int height) { + TWidget::resizeToWidth(width()); + }) | rpl::start(_lifetime); +} + +object_ptr InnerWidget::setupDetailsContent( + RpWidget *parent) const { + auto result = object_ptr(parent); + + result->add(object_ptr(result)); + + auto skipPadding = QMargins(0, 0, 0, st::infoProfileSkip); + result->add(object_ptr>(result, skipPadding)); + + result->add(setupInfoLines(result)); + result->add(setupMuteToggle(result)); + if (auto user = _peer->asUser()) { + setupMainUserButtons(result, user); + } + + result->add(object_ptr>(result, skipPadding)); + + return result; +} + +object_ptr InnerWidget::setupMuteToggle( + RpWidget *parent) const { + auto result = object_ptr(parent); + auto button = result->add(object_ptr