diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 5553d37561..26cd3dc263 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -125,6 +125,28 @@ std::vector> PrepareCollageMedia( return result; } +void PaintInterpolatedIcon( + Painter &p, + const style::icon &a, + const style::icon &b, + float64 b_ratio, + QRect rect) { + PainterHighQualityEnabler hq(p); + p.save(); + p.translate(rect.center()); + p.setOpacity(b_ratio); + p.scale(b_ratio, b_ratio); + b.paintInCenter(p, rect.translated(-rect.center())); + p.restore(); + + p.save(); + p.translate(rect.center()); + p.setOpacity(1. - b_ratio); + p.scale(1. - b_ratio, 1. - b_ratio); + a.paintInCenter(p, rect.translated(-rect.center())); + p.restore(); +} + } // namespace QString FillAmountAndCurrency(uint64 amount, const QString ¤cy) { @@ -488,7 +510,8 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim p.setOpacity(radialOpacity); auto icon = ([radial, this, selected]() -> const style::icon* { if (radial || _data->loading()) { - if (!_data->full->location().isNull()) { + if (_data->uploading() + || !_data->full->location().isNull()) { return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); } return nullptr; @@ -625,9 +648,12 @@ void HistoryPhoto::drawGrouped( || (!loaded && !_data->loading()) || _data->waitingForAlbum(); if (displayState) { - const auto radialOpacity = (radial && loaded && !_data->uploading()) + const auto radialOpacity = radial ? _animation->radial.opacity() : 1.; + const auto backOpacity = (loaded && !_data->uploading()) + ? radialOpacity + : 1.; const auto radialSize = st::historyGroupRadialSize; const auto inner = QRect( geometry.x() + (geometry.width() - radialSize) / 2, @@ -645,27 +671,37 @@ void HistoryPhoto::drawGrouped( p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); } - p.setOpacity(radialOpacity * p.opacity()); + p.setOpacity(backOpacity * p.opacity()); { PainterHighQualityEnabler hq(p); p.drawEllipse(inner); } - p.setOpacity(radialOpacity); - auto icon = [&]() -> const style::icon* { + const auto icon = [&]() -> const style::icon* { if (_data->waitingForAlbum()) { return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting); } else if (radial || _data->loading()) { - if (!_data->full->location().isNull()) { + if (_data->uploading() || !_data->full->location().isNull()) { return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); } return nullptr; } return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); }(); + const auto previous = [&]() -> const style::icon* { + if (_data->waitingForAlbum()) { + return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); + } + return nullptr; + }(); + p.setOpacity(backOpacity); if (icon) { - icon->paintInCenter(p, inner); + if (previous && radialOpacity > 0. && radialOpacity < 1.) { + PaintInterpolatedIcon(p, *icon, *previous, radialOpacity, inner); + } else { + icon->paintInCenter(p, inner); + } } p.setOpacity(1); if (radial) { @@ -1082,9 +1118,12 @@ void HistoryVideo::drawGrouped( App::complexOverlayRect(p, geometry, roundRadius, corners); } - const auto radialOpacity = (radial && loaded && !_data->uploading()) + const auto radialOpacity = radial ? _animation->radial.opacity() : 1.; + const auto backOpacity = (loaded && !_data->uploading()) + ? radialOpacity + : 1.; const auto radialSize = st::historyGroupRadialSize; const auto inner = QRect( geometry.x() + (geometry.width() - radialSize) / 2, @@ -1102,14 +1141,13 @@ void HistoryVideo::drawGrouped( p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); } - p.setOpacity(radialOpacity * p.opacity()); + p.setOpacity(backOpacity * p.opacity()); { PainterHighQualityEnabler hq(p); p.drawEllipse(inner); } - p.setOpacity(radialOpacity); auto icon = [&]() -> const style::icon * { if (_data->waitingForAlbum()) { return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting); @@ -1123,8 +1161,20 @@ void HistoryVideo::drawGrouped( } return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); }(); + const auto previous = [&]() -> const style::icon* { + if (_data->waitingForAlbum()) { + return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); + } + return nullptr; + }(); + p.setOpacity(backOpacity); if (icon) { - icon->paintInCenter(p, inner); + if (previous && radialOpacity > 0. && radialOpacity < 1.) { + LOG(("INTERPOLATING: %1").arg(radialOpacity)); + PaintInterpolatedIcon(p, *icon, *previous, radialOpacity, inner); + } else { + icon->paintInCenter(p, inner); + } } p.setOpacity(1); if (radial) { diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.cpp b/Telegram/SourceFiles/ui/effects/radial_animation.cpp index 35b1b440ec..bcfb862353 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/radial_animation.cpp @@ -26,15 +26,22 @@ void RadialAnimation::start(float64 prg) { bool RadialAnimation::update(float64 prg, bool finished, TimeMs ms) { const auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength); const auto result = (iprg != qRound(a_arcEnd.to())); - if (result) { + if (_finished != finished) { + a_arcEnd.start(iprg); + _finished = finished; + _lastStart = _lastTime; + } else if (result) { a_arcEnd.start(iprg); _lastStart = _lastTime; } _lastTime = ms; - auto dt = float64(ms - _lastStart); - auto fulldt = float64(ms - _firstStart); - _opacity = qMin(fulldt / st::radialDuration, 1.); + const auto dt = float64(ms - _lastStart); + const auto fulldt = float64(ms - _firstStart); + const auto opacitydt = _finished + ? (_lastStart - _firstStart) + : fulldt; + _opacity = qMin(opacitydt / st::radialDuration, 1.); if (anim::Disabled()) { a_arcEnd.update(1., anim::linear); if (finished) { diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.h b/Telegram/SourceFiles/ui/effects/radial_animation.h index e0a6aabc79..d4742455ab 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.h +++ b/Telegram/SourceFiles/ui/effects/radial_animation.h @@ -43,6 +43,7 @@ private: anim::value a_arcEnd; anim::value a_arcStart; BasicAnimation _animation; + bool _finished = false; };