From f9ff676e57aa02a68f10cf8b2e2163af9c420671 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 3 May 2018 18:05:18 +0300 Subject: [PATCH] Improve proxies box design and progress animation. --- Telegram/Resources/icons/passport_ready.png | Bin 0 -> 369 bytes .../Resources/icons/passport_ready@2x.png | Bin 0 -> 655 bytes Telegram/SourceFiles/boxes/boxes.style | 9 +- Telegram/SourceFiles/boxes/connection_box.cpp | 47 ++++++++- .../ui/effects/radial_animation.cpp | 98 +++++++++++++++++- .../SourceFiles/ui/effects/radial_animation.h | 39 +++++++ Telegram/SourceFiles/ui/widgets/widgets.style | 21 ++++ 7 files changed, 208 insertions(+), 6 deletions(-) create mode 100644 Telegram/Resources/icons/passport_ready.png create mode 100644 Telegram/Resources/icons/passport_ready@2x.png diff --git a/Telegram/Resources/icons/passport_ready.png b/Telegram/Resources/icons/passport_ready.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba5de37a56763c0841caa01c053c61520f5407c GIT binary patch literal 369 zcmV-%0gnEOP)7fmKA!_nRTYE5pw06+;&8>sL5R8<8)6h*&v(um=3$nkgt zAWc&=O+yHQ>$)5c2LR$YMp2aKfIFio?|YPA=FAYi-QV%v77JykB$cg5fOzS`mw$5VCMjxpGD P00000NkvXXu0mjf;e?<% literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/passport_ready@2x.png b/Telegram/Resources/icons/passport_ready@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a62efd58cfc938dd9b43c29550798301eb9eaa GIT binary patch literal 655 zcmV;A0&x9_P)B)&O#Xlyko*XP^|Cn0uVgV? z$@4q;^znK7b+fq;5hEwy4T?1@i_MTJ$|NKF24sb91df*+u?VT$>i&SUauF+<&weW za=A-2e}}W%?T}@e!Ies-OXu(JfIQD*G#W9uTCE0y!Emisf1J^1geZy(uG8tjWHQ~V z*B56n7*MTN8Jr|Zu-R<)^w1YrC=?i+EXxoC;octl;nL|egWGPm@cDdd`sjm8Boa6r z4ktK8Q4onl)b=|6!0B|tYPCLui^XD46y*eWI2@2jBp&H^9w*B(hQlE&7K^Hem!?E2 zm3s7ToZfIa9GFZd-;MkIK6swLtC=7OYNv#HV6)j|Ht6+wH<31*4U!}=wUtWc+LTZa zJigxFX}8-Kkvz|1Fc>g3qA0>>G-|<}KZAlGU^<;L8@5_4n9b&swU?$ux7)q@Xs8Af z5nL`8X0sWyakJUP*Vh+_2pq?uQmHU&R7{D-fkXti+l~2r&H(E5I!q=La=9GyY`I*j znG)K7LGefdJO)H3Lki(|Y050f`8~U=W+l<{MWi6!gTY2NDrNp%5C428zYvt> _edit; object_ptr> _delete; object_ptr> _restore; + std::unique_ptr _progress; int _skipLeft = 0; int _skipRight = 0; @@ -191,11 +194,33 @@ void ProxyRow::updateFields(View &&view) { _edit->toggle(!_view.deleted, anim::type::instant); _restore->toggle(_view.deleted, anim::type::instant); + const auto state = _view.state; + if (state == State::Connecting || state == State::Checking) { + if (!_progress) { + _progress = std::make_unique( + animation(this, &ProxyRow::step_radial)); + _progress->start(); + } + } else { + _progress = nullptr; + } + setPointerCursor(!_view.deleted); update(); } +void ProxyRow::step_radial(TimeMs ms, bool timer) { + if (timer) { + update(); + } else if (_progress) { + _progress->update(false, ms); + if (!_progress->animating()) { + _progress = nullptr; + } + } +} + int ProxyRow::resizeGetHeight(int newWidth) { const auto result = st::proxyRowPadding.top() + st::semiboldFont->height @@ -226,8 +251,8 @@ int ProxyRow::resizeGetHeight(int newWidth) { void ProxyRow::paintEvent(QPaintEvent *e) { Painter p(this); + const auto ms = getms(); if (!_view.deleted) { - const auto ms = getms(); paintRipple(p, 0, 0, ms); } @@ -282,9 +307,25 @@ void ProxyRow::paintEvent(QPaintEvent *e) { }(); p.setPen(statusFg); p.setFont(st::normalFont); - p.drawTextLeft(left, top, width(), status); - top += st::normalFont->height + st::proxyRowPadding.bottom(); + auto statusLeft = left; + if (_progress) { + _progress->step(ms); + if (_progress) { + _progress->draw( + p, + { + st::proxyCheckingPosition.x() + statusLeft, + st::proxyCheckingPosition.y() + top }, + width(), + st::proxyCheckingAnimation); + statusLeft += st::proxyCheckingPosition.x() + + st::proxyCheckingAnimation.size.width() + + st::proxyCheckingSkip; + } + } + p.drawTextLeft(statusLeft, top, width(), status); + top += st::normalFont->height + st::proxyRowPadding.bottom(); } ProxiesBox::ProxiesBox( diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.cpp b/Telegram/SourceFiles/ui/effects/radial_animation.cpp index 34ebeab5c..fbf4cb5ee 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/radial_animation.cpp @@ -7,11 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "ui/effects/radial_animation.h" +#include "styles/style_widgets.h" + namespace Ui { RadialAnimation::RadialAnimation(AnimationCallbacks &&callbacks) - : a_arcStart(0, FullArcLength) - , _animation(std::move(callbacks)) { +: a_arcStart(0, FullArcLength) +, _animation(std::move(callbacks)) { } void RadialAnimation::start(float64 prg) { @@ -82,4 +84,96 @@ void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, styl p.setOpacity(o); } +InfiniteRadialAnimation::InfiniteRadialAnimation(AnimationCallbacks &&callbacks) +: _animation(std::move(callbacks)) { +} + +void InfiniteRadialAnimation::start() { + _start = _changed = getms(); + _finished = false; + _animation.start(); +} + +void InfiniteRadialAnimation::update(bool finished, TimeMs ms) { + if (_finished != finished) { + _finished = finished; + _changed = ms; + } + + auto dt = float64(ms - _changed); + auto fulldt = float64(ms - _start); + _opacity = qMin(fulldt / st::radialDuration, 1.); + if (!finished) { + } else if (dt >= st::radialDuration) { + stop(); + } else { + auto r = dt / st::radialDuration; + _opacity *= 1 - r; + } +} + +void InfiniteRadialAnimation::stop() { + _start = _changed = 0; + _animation.stop(); +} + +void InfiniteRadialAnimation::step(TimeMs ms) { + _animation.step(ms); +} + +void InfiniteRadialAnimation::draw( + Painter &p, + QPoint position, + int outerWidth, + const style::InfiniteRadialAnimation &st) { + auto o = p.opacity(); + p.setOpacity(o * _opacity); + + auto pen = st.color->p; + auto was = p.pen(); + pen.setWidth(st.thickness); + pen.setCapStyle(Qt::RoundCap); + p.setPen(pen); + + const auto time = (getms() - _start); + const auto linear = (time * FullArcLength) / st.linearPeriod; + const auto frontPeriods = time / st.sinePeriod; + const auto frontCurrent = time % st.sinePeriod; + const auto frontProgress = anim::sineInOut( + st.arcMax - st.arcMin, + std::min(frontCurrent, TimeMs(st.sineDuration)) + / float64(st.sineDuration)); + const auto backTime = std::max(time - st.sineShift, 0LL); + const auto backPeriods = backTime / st.sinePeriod; + const auto backCurrent = backTime % st.sinePeriod; + const auto backProgress = anim::sineInOut( + st.arcMax - st.arcMin, + std::min(backCurrent, TimeMs(st.sineDuration)) + / float64(st.sineDuration)); + const auto front = linear + std::round((st.arcMin + frontProgress + frontPeriods * (st.arcMax - st.arcMin)) * FullArcLength); + const auto from = linear + std::round((backProgress + backPeriods * (st.arcMax - st.arcMin)) * FullArcLength); + const auto len = (front - from); + + //if (rtl()) { + // from = QuarterArcLength - (from - QuarterArcLength) - len; + // if (from < 0) from += FullArcLength; + //} + + { + PainterHighQualityEnabler hq(p); + p.drawArc( + rtlrect( + position.x(), + position.y(), + st.size.width(), + st.size.height(), + outerWidth), + from, + len); + } + + p.setPen(was); + p.setOpacity(o); +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.h b/Telegram/SourceFiles/ui/effects/radial_animation.h index ac255aaae..b3c0f28bd 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.h +++ b/Telegram/SourceFiles/ui/effects/radial_animation.h @@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +namespace style { +struct InfiniteRadialAnimation; +} // namespace style + namespace Ui { class RadialAnimation { @@ -42,4 +46,39 @@ private: }; +class InfiniteRadialAnimation { +public: + InfiniteRadialAnimation(AnimationCallbacks &&callbacks); + + float64 opacity() const { + return _opacity; + } + bool animating() const { + return _animation.animating(); + } + + void start(); + void update(bool finished, TimeMs ms); + void stop(); + + void step(TimeMs ms); + void step() { + step(getms()); + } + + void draw( + Painter &p, + QPoint position, + int outerWidth, + const style::InfiniteRadialAnimation &st); + +private: + float64 _opacity = 0.; + TimeMs _start = 0; + TimeMs _changed = 0; + bool _finished = false; + BasicAnimation _animation; + +}; + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style index c60cdec77..48f2bd794 100644 --- a/Telegram/SourceFiles/ui/widgets/widgets.style +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -37,6 +37,27 @@ RippleAnimation { hideDuration: int; } +InfiniteRadialAnimation { + color: color; + thickness: pixels; + size: size; + linearPeriod: int; + sinePeriod: int; + sineDuration: int; + sineShift: int; + arcMin: double; + arcMax: double; +} + +defaultInfiniteRadialAnimation: InfiniteRadialAnimation { + linearPeriod: 1000; + sinePeriod: 3000; + sineDuration: 1000; + sineShift: 1500; + arcMin: 0.0625; + arcMax: 0.75; +} + FlatButton { color: color; overColor: color;