From 34ef54e40be1f872037e3fa50ce33e4590a5fa85 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 23 Jun 2020 13:20:38 +0400 Subject: [PATCH] Display check on the active account. --- Telegram/Resources/icons/account_check.png | Bin 0 -> 263 bytes Telegram/Resources/icons/account_check@2x.png | Bin 0 -> 363 bytes Telegram/Resources/icons/account_check@3x.png | Bin 0 -> 525 bytes Telegram/Resources/icons/menu_add_account.png | Bin 0 -> 740 bytes .../Resources/icons/menu_add_account@2x.png | Bin 0 -> 1506 bytes .../Resources/icons/menu_add_account@3x.png | Bin 0 -> 2548 bytes Telegram/SourceFiles/main/main_session.cpp | 9 ++ Telegram/SourceFiles/main/main_session.h | 3 + Telegram/SourceFiles/mainwidget.cpp | 9 -- Telegram/SourceFiles/mainwidget.h | 3 - Telegram/SourceFiles/window/window.style | 14 +++- .../SourceFiles/window/window_main_menu.cpp | 78 +++++++++++++++--- Telegram/lib_ui | 2 +- 13 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 Telegram/Resources/icons/account_check.png create mode 100644 Telegram/Resources/icons/account_check@2x.png create mode 100644 Telegram/Resources/icons/account_check@3x.png create mode 100644 Telegram/Resources/icons/menu_add_account.png create mode 100644 Telegram/Resources/icons/menu_add_account@2x.png create mode 100644 Telegram/Resources/icons/menu_add_account@3x.png diff --git a/Telegram/Resources/icons/account_check.png b/Telegram/Resources/icons/account_check.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2cd905895bf900cbf78f761f4ec53268d03ab6 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6=0JY5_^ zECioUw&iP45NIuomKK&;Xi^f>*_K?vJHuDJ9hnp|FnWR3G;bcv| zoU;apqJWWg+|4IU|0X+xhPr6Fp4zmhhd2JAq2^Kp9_ECMwdc3qPt4A3nOoeDw7hM0 zg84Il}wC2iJAKFTjI)p0@|b*=wKlFTcArkCUXmnU7=}i};R{VC`(QAD?RE=d zyWMWETCH?hx`WU2T(G~6bzQ@3Hq()CFMySAgBKQQntrbU!XFL?!PHJF4&c=V=JPq= zGx~k2stST2Xq9jTuP(6L?cUj6=WP-W;nf9>$KwmSdGapd7+zf&5xwE1$gxY(AM{T*laculxo8gyq5t(VKC>KFgZb^a6Jap>p9{|j}U8z;aC5G%k_h*&^!cTRv@LgD~-C3;uUsF^DN P00000NkvXXu0mjfb_nVy literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu_add_account.png b/Telegram/Resources/icons/menu_add_account.png new file mode 100644 index 0000000000000000000000000000000000000000..25de7ef7156ba1d63af5f0be260c7040d7085713 GIT binary patch literal 740 zcmV4WNaseAPB@MLoSz#9nn?r!#@k}WlJV3 z7K<{U&lOL0yPb?iBdOJDF;H~ov8xbAd+LuqHEC}hNea)&?hxa4yOpo6FR4^2c0@dr3<060U09lGG?2zGa# zXK=s+*R{pkV6|Gcoo2t^8=tsrHXA$9YPDhp)z$7A!7-!(xW0s|U{!P)(wr9OIavLt*{c}ffvfs!j7YQ26laL@)Tt7rovE=$q+}VAl)bKB-sfD| zn^vdwdR@ljv8+}rx!>=0VR}Pn9y@;Sf^yYqQb%gH+hLbdqO_6jgFnQ%I}*-r?=|HR z5>6%)X*QcuDwSfpL1!L20x@y9d#}D4{mNXgR|^E7+OkF^*0{8cki7BqZJ`VDiJ4-Av6vt;(R1ie4QY;m*w-pO(K`s0Y79uv5mR9-+`~(Wx zSP3>_r}zPUAXb8f5AglY&2O)fvoV>;WM_rD*8@v3lk@ohCz<3Vv!x_Sl>XJdG}JxA zPlCTh>#e7Md-S(Q1D`-sQ&TcFHkPcdttE$thspi@ee(A9mVA7Clz-H@M;kimVpB_D zc`4-A+}y0Drl!>H?yh=&e^+@08*K4`ucB~$`l+5|sZ>%kGc)S(@i8wquRgx;iSL34 zS4UJ2Idyq?=><%K9k{1^jYI1Ti7Q{C@eBsj;VuK-qY&cP#rcIJ3zp=3q6FA5Q-*)eUA);r) zi1L2e!xaGY^YcM~BYNP=FEMPgV9EK;h7q+V9s-9kB?Wp zDtUWyWMo7wFE6Wug9CMYdt3fd=N@et0KeK@J)2|cNhivJZLgD|?_^(JpW5Euu6RhU z3v|#8Axvy3U<*tt(utCtNMR-n0W>r;q^_>6q-km$U2H;p+p{qk1MK`n$v0(M$B+$K zLg<}5B+V1RCZuPi4k9wrxC78VwqO99IRZMK9=P+*Y))+nNSZ&2 zgeC{9lTvsmvp}OG1s_>9w1Y{CKB-8va}(7^9A7?|;X(qV^OHo0Cud(U`*3diMRFT3$?Cuo=mC#fl{g z09Ss?5>jNsP#95t?rI)X`B2L^4k>G$0!j=VvKaxhY_sa_9@U4-#=d-7XBnkAEVtD% zsh3zdNi+gx*=E(71T*4Pyh$lzFyk(m!=Mm!vH(TGvgK#aBvb!r=191XaYw z+xA^Z!VsGR+F)vVT}TQTo7C5mnC&}HQtw^K`P#L=zps7&mA1CFL~o7ErMK+v?oOts zr<2Xi%|!1R6TK-;^ed41LkC@Ku*FA~fCWrOzzXIx@y=9vHr^c_9cpoLQ9V69$yYn7 zjt_j{Qv-MY3f*{z9;FNn45;Jd<0w*TM)<_HO}6l(6ar)&jsZk2+G)UJ+VE|YE&Ol{ zqG`vS3@ukro}Ztq+1Xju-`}rVTU)>Nh}}czpo#xBYAmwslciKBnZwS zmi>`QvSi3r)02jvDe>hR#wKRXJ~9Eo_1Vw_=KV4tiz@NylA3-tG~j(7f|(sdPVtSO ztP)?Y+5AU71RHSltZP{D4zZBytR=d4vBih|KGL(qjQ9X-u(&f1L&{e+Ha4ogy*<~+ zD&HdyCFu^?^`L{U%w28A#3H5-Pr&^+qQ(^b07*qo IM6N<$f;VB(#sB~S literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu_add_account@3x.png b/Telegram/Resources/icons/menu_add_account@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9a111d9bf154cecb03d29caa30b02764ddd5b4a3 GIT binary patch literal 2548 zcmV-ls{hrUxI=yF|wf0(j?Y-Xjb=psz_StK%=l0#txz2BB@uK?l=~HFBIT=`?_3Ures#SVuXh^?&`BMM+^GC2tC-{+rJmmJ$ zufMvx5A3X2v-FW8NA$aQ@6wTs;6y%p(AOiNy9e&vxpVcIGiS6k>j-F?tAalCqQA=^ z=LdJ<#EJU&@#D3deOmazm>MUAJzXmL^>aECbBdt5@~Hg$r{z zRmep?dO`yz_F{KcUnA-_2kw?FTS}vaNP6_>kzTxbaSlhkGSP?LvPk9`_D29#rA{;8 zhJgL~^QYdmYgZM+8n26f?C?yzRn|q|XASw)!JRZ|lK%4LixXT1i#mPmj2ScZp+kqf@@=KqL4EjALBL+$ zAcy=K-9vS7Wv{^YvAAcNQ)gDNdGls(AMRAxQAi&Ne=5M(?VG0IZ=&34;IeJ!8U!dy zoyW=vgWk7qpHprJe!+jS0Xd046!!akOWdxk1}^)eE@B0g>J)%9Np%3m4;SHgf`9Sg zvZL=>r&E@?q@^jlqQ&K4Y#H)Wy9oU7`IvB`5f3g$CN5%gB;l@PCjD5&W9pv!GMfhLQ&vh2b!ypNted!|>eTv_T2 z&#C7lO2^~TvYK? zISyQot6h}3(ai$DMKtwL#M&>D`o1nAbsG`CTm%lb{*wDRaLEU-i6fN~!KKewVY!ID zG({$SE<#U=Ja}A3M&J-DFDh3|nwFAzp2!?YWV)o1Oxm5SCr_SqmWK*`d_FxPc|3Rd z2M*v7Ls8(8VniyDP3O;_w~M0hIk|O_>>Id>gJnKGpPryVso?St9Ka)%f?0lGaMNGF`^+RRwxd=TWUf*;4bIlsS!^hKE9u>JH#n~k5aP|82Yr8o5 zUgn|By0d4`c9w??q+m^{DS66!Yc(`VaY+IE$niLuRF0oEfk&i{Ft}H) zT(RXBIRudkVht&dX39<`Mj6pj0AK3SPMIIBE)hJ+csibi!OgL^&|$y`Lwk|8;IpOf z-h#*tgX^2{lPVv>pHhc;FnYU@apSWO|6EjI13nBcj=K6ozCrLAHWte9&n9pHk4XQ* z;3BB$lZZ&;Vx7oRuPY}J0)&#|W-cR0a;TJ?HH|16D>wLse>S;ruTh#jJk&pe&iqzxyVOP%3oJce=)GByaoC!=A*Km z7X@5uCFG;0LLXVYh_2@?0B+rk8zO1!NmMmc=&BgeHDVt_SQ?CR`; z`y#U(M`FK;U=S&zn>TM3Q>HS|QlBvuLw*@yAM%OfzWF8sgF;{PF#U0D*BNJz9XqDw zcM_7KG!}5=qsK?shn;=(HIH$w>^ro_k01MdDjYU4x^XQ7xXjL;eTN1pd_v^ge{~HE zpiNWF9kKQcL!YmU@Y#u9H9nCtEi!F+XdDQA`)h|UeWBs)<`uoM)ED3W8gN2itsAE< zU%uQEV2zzIvj`%&sjt?f@)pFnQo3>DhT6JyYw>G!Wff%rDSMp#nQWVu>X0BP{J@{4 zsIh2bhu+tR5xqQP1(f<(l{lPaEBeqIvaP}iL#!QX2KyYPNx70pOxM7b=WLFoeg)*y zZI>e-Ju&t))fHGaGz%`mH*DCTKY#w*iKp{_B8h#|)Q?syM~0&bdB`n`RAUf!u3x`? znAayWvAlV3F+_e?P0Ke0#)sgQBNfi9y7{|e*oU2ozyoB->(iFI1tT~S~2(rL~yM-^3#C&+O=y@ z%`_O|H7d|eU9LRM!$uBq+%m` z3;&3(T{p7@HzVXNxGlID5y&XIjocR8j0j{D-9~N;Zbk$$ivAx3;_#5oYney@0000< KMNUMnLSTXl@(;xT literal 0 HcmV?d00001 diff --git a/Telegram/SourceFiles/main/main_session.cpp b/Telegram/SourceFiles/main/main_session.cpp index 39599e6d1..7e3e0cf17 100644 --- a/Telegram/SourceFiles/main/main_session.cpp +++ b/Telegram/SourceFiles/main/main_session.cpp @@ -92,6 +92,15 @@ Session::Session( _api->instance().setUserPhone(_user->phone()); + // Load current userpic and keep it loaded. + changes().peerFlagsValue( + _user, + Data::PeerUpdate::Flag::Photo + ) | rpl::start_with_next([=] { + [[maybe_unused]] const auto image = _user->currentUserpic( + _selfUserpicView); + }, lifetime()); + crl::on_main(this, [=] { using Flag = Data::PeerUpdate::Flag; changes().peerUpdates( diff --git a/Telegram/SourceFiles/main/main_session.h b/Telegram/SourceFiles/main/main_session.h index f23f8957d..9039dbf27 100644 --- a/Telegram/SourceFiles/main/main_session.h +++ b/Telegram/SourceFiles/main/main_session.h @@ -31,6 +31,7 @@ class Templates; namespace Data { class Session; class Changes; +class CloudImageView; } // namespace Data namespace Storage { @@ -174,6 +175,8 @@ private: const std::unique_ptr _supportHelper; + std::shared_ptr _selfUserpicView; + base::flat_set> _windows; base::Timer _saveSettingsTimer; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index be3dab507..9a8e796a2 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -243,15 +243,6 @@ MainWidget::MainWidget( floatPlayerClosed(itemId); }, lifetime()); - // Load current userpic and keep it loaded. - session().changes().peerFlagsValue( - session().user(), - Data::PeerUpdate::Flag::Photo - ) | rpl::start_with_next([=] { - [[maybe_unused]] const auto image = session().user()->currentUserpic( - _selfUserpicView); - }, lifetime()); - updateScrollColors(); setupConnectingWidget(); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 217ed65b4..21b3f16ce 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -34,7 +34,6 @@ class Session; namespace Data { class WallPaper; -class CloudImageView; } // namespace Data namespace Dialogs { @@ -360,8 +359,6 @@ private: int _thirdColumnWidth = 0; Ui::Animations::Simple _a_dialogsWidth; - std::shared_ptr _selfUserpicView; - object_ptr _sideShadow; object_ptr _thirdShadow = { nullptr }; object_ptr _firstColumnResizeArea = { nullptr }; diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index 3f117c6b2..7e75ef589 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -145,8 +145,18 @@ mainMenuReload: icon {{ "menu_reload", menuIconFg }}; mainMenuReloadOver: icon {{ "menu_reload", menuIconFgOver }}; mainMenuFixOrder: icon {{ "menu_fix_order", menuIconFg }}; mainMenuFixOrderOver: icon {{ "menu_fix_order", menuIconFgOver }}; -mainMenuAddAccount: icon {{ "menu_fix_order", menuIconFg }}; -mainMenuAddAccountOver: icon {{ "menu_fix_order", menuIconFgOver }}; +mainMenuAddAccount: icon {{ "menu_add_account", menuIconFg }}; +mainMenuAddAccountOver: icon {{ "menu_add_account", menuIconFgOver }}; +mainMenuAccountSize: 32px; +mainMenuAccountCheckPosition: point(7px, 5px); +mainMenuAccountCheckLine: 2px; +mainMenuAccountCheck: RoundCheckbox(defaultRoundCheckbox) { + size: 18px; + bgInactive: overviewCheckBg; + bgActive: overviewCheckBgActive; + check: icon {{ "account_check", overviewCheckFgActive }}; +} + mainMenuFooterLeft: 30px; mainMenuTelegramLabel: FlatLabel(defaultFlatLabel) { align: align(left); diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 0b50dc952..56c5ab5b5 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -88,10 +88,13 @@ public: private: void paintEvent(QPaintEvent *e) override; + void paintUserpic(Painter &p); const not_null _account; const style::Menu &_st; std::shared_ptr _userpicView; + InMemoryKey _userpicKey = {}; + QImage _userpicCache; Dialogs::Layout::UnreadBadgeStyle _unreadSt; int _unreadBadge = 0; @@ -154,26 +157,68 @@ MainMenu::AccountButton::AccountButton( }, lifetime()); } -void MainMenu::AccountButton::paintEvent(QPaintEvent *e) { +void MainMenu::AccountButton::paintUserpic(Painter &p) { Expects(_account->sessionExists()); - const auto &session = _account->session(); + const auto size = st::mainMenuAccountSize; + const auto iconSize = height() - 2 * _st.itemIconPosition.y(); + const auto shift = (size - iconSize) / 2; + const auto x = _st.itemIconPosition.x() - shift; + const auto y = (height() - size) / 2; + + const auto check = (_account == &Core::App().domain().active()); + const auto user = _account->session().user(); + if (!check) { + user->paintUserpicLeft(p, _userpicView, x, y, width(), size); + return; + } + const auto added = y; + const auto cacheSize = QSize(size + added, size + added) + * cIntRetinaFactor(); + const auto key = user->userpicUniqueKey(_userpicView); + if (_userpicKey != key) { + _userpicKey = key; + if (_userpicCache.size() != cacheSize) { + _userpicCache = QImage(cacheSize, QImage::Format_ARGB32_Premultiplied); + _userpicCache.setDevicePixelRatio(cRetinaFactor()); + } + _userpicCache.fill(Qt::transparent); + + auto q = Painter(&_userpicCache); + user->paintUserpicLeft(q, _userpicView, 0, 0, width(), size); + + const auto iconDiameter = st::mainMenuAccountCheck.size; + const auto iconLeft = size + st::mainMenuAccountCheckPosition.x() - iconDiameter; + const auto iconTop = size + st::mainMenuAccountCheckPosition.y() - iconDiameter; + const auto iconEllipse = QRect(iconLeft, iconTop, iconDiameter, iconDiameter); + auto iconBorderPen = QPen(Qt::transparent); + const auto line = st::mainMenuAccountCheckLine; + iconBorderPen.setWidth(line); + + PainterHighQualityEnabler hq(q); + q.setCompositionMode(QPainter::CompositionMode_Source); + q.setPen(iconBorderPen); + q.setBrush(st::dialogsUnreadBg); + q.drawEllipse(iconEllipse); + + q.setCompositionMode(QPainter::CompositionMode_SourceOver); + st::mainMenuAccountCheck.check.paintInCenter(q, iconEllipse); + } + p.drawImage(x, y, _userpicCache); +} + +void MainMenu::AccountButton::paintEvent(QPaintEvent *e) { + Expects(_account->sessionExists()); auto p = Painter(this); const auto over = isOver(); p.fillRect(rect(), over ? _st.itemBgOver : _st.itemBg); paintRipple(p, 0, 0); - session.user()->paintUserpicLeft( - p, - _userpicView, - _st.itemIconPosition.x(), - _st.itemIconPosition.y(), - width(), - height() - 2 * _st.itemIconPosition.y()); + paintUserpic(p); auto available = width() - _st.itemPadding.left(); - if (_unreadBadge && _account != &Core::App().domain().active()) { + if (_unreadBadge) { _unreadSt.muted = _unreadBadgeMuted; const auto string = (_unreadBadge > 99) ? "99+" @@ -196,7 +241,7 @@ void MainMenu::AccountButton::paintEvent(QPaintEvent *e) { } p.setPen(over ? _st.itemFgOver : _st.itemFg); - session.user()->nameText().drawElided( + _account->session().user()->nameText().drawElided( p, _st.itemPadding.left(), _st.itemPadding.top(), @@ -514,7 +559,12 @@ void MainMenu::rebuildAccounts() { const auto inner = _accounts->entity(); auto count = 0; - for (auto &[account, button] : _watched) { + for (const auto &[index, pointer] : Core::App().domain().accounts()) { + const auto account = pointer.get(); + auto i = _watched.find(account); + Assert(i != _watched.end()); + + auto &button = i->second; if (!account->sessionExists()) { button = nullptr; } else if (!button) { @@ -522,6 +572,10 @@ void MainMenu::rebuildAccounts() { ++count, object_ptr(inner, account))); button->setClickedCallback([=] { + if (account == &Core::App().domain().active()) { + closeLayer(); + return; + } auto activate = [=, guard = _accountSwitchGuard.make_guard()]{ if (guard) { Core::App().domain().activate(account); diff --git a/Telegram/lib_ui b/Telegram/lib_ui index d31d94e8f..2a0d189ee 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit d31d94e8fb47b8492fbf341b93c19ddfbcb42fa2 +Subproject commit 2a0d189ee22d8573bd4f9f0971ef1aa27a12f02d