From ad0c9ebb7984caff8e762b898cec832e71184d64 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 29 Aug 2022 17:54:56 +0400 Subject: [PATCH] Fly-animate custom reactions. --- .../history/view/history_view_bottom_info.h | 2 +- .../history_view_reactions_animation.cpp | 44 +++++++++++++------ .../history_view_reactions_animation.h | 2 +- .../history_view_reactions_button.cpp | 2 +- .../history_view_reactions_strip.cpp | 6 +-- .../reactions/history_view_reactions_strip.h | 2 +- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/Telegram/SourceFiles/history/view/history_view_bottom_info.h b/Telegram/SourceFiles/history/view/history_view_bottom_info.h index fca2d8d2b..0818764c0 100644 --- a/Telegram/SourceFiles/history/view/history_view_bottom_info.h +++ b/Telegram/SourceFiles/history/view/history_view_bottom_info.h @@ -28,7 +28,7 @@ class Animation; struct ReactionAnimationArgs { ::Data::ReactionId id; - std::shared_ptr flyIcon; + QImage flyIcon; QRect flyFrom; [[nodiscard]] ReactionAnimationArgs translated(QPoint point) const; diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.cpp index 511cb7be1..8bbd9869a 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_bottom_info.h" #include "ui/animated_icon.h" #include "data/data_message_reactions.h" +#include "data/data_session.h" #include "data/data_document.h" #include "data/data_document_media.h" #include "styles/style_chat.h" @@ -31,9 +32,20 @@ Animation::Animation( , _repaint(std::move(repaint)) , _flyFrom(args.flyFrom) { const auto &list = owner->list(::Data::Reactions::Type::All); - const auto i = ranges::find(list, args.id, &::Data::Reaction::id); - if (i == end(list) || !i->centerIcon) { - return; + auto centerIcon = (DocumentData*)nullptr; + auto aroundAnimation = (DocumentData*)nullptr; + if (const auto customId = args.id.custom()) { + const auto document = owner->owner().document(customId); + if (document->sticker()) { + centerIcon = document; + } + } else { + const auto i = ranges::find(list, args.id, &::Data::Reaction::id); + if (i == end(list) || !i->centerIcon) { + return; + } + centerIcon = i->centerIcon; + aroundAnimation = i->aroundAnimation; } const auto resolve = [&]( std::unique_ptr &icon, @@ -53,11 +65,11 @@ Animation::Animation( return true; }; _flyIcon = std::move(args.flyIcon); - if (!resolve(_center, i->centerIcon, size) - || !resolve(_effect, i->aroundAnimation, size * 2)) { + if (!resolve(_center, centerIcon, size)) { return; } - if (_flyIcon) { + resolve(_effect, aroundAnimation, size * 2); + if (!_flyIcon.isNull()) { _fly.start([=] { flyCallback(); }, 0., 1., kFlyDuration); } else { startAnimations(); @@ -71,12 +83,14 @@ QRect Animation::paintGetArea( QPainter &p, QPoint origin, QRect target) const { - if (!_flyIcon) { + if (_flyIcon.isNull()) { p.drawImage(target, _center->frame()); const auto wide = QRect( target.topLeft() - QPoint(target.width(), target.height()) / 2, target.size() * 2); - p.drawImage(wide, _effect->frame()); + if (const auto effect = _effect.get()) { + p.drawImage(wide, effect->frame()); + } return wide; } const auto from = _flyFrom.translated(origin); @@ -94,7 +108,7 @@ QRect Animation::paintGetArea( auto hq = PainterHighQualityEnabler(p); if (progress < 1.) { p.setOpacity(1. - progress); - p.drawImage(rect, _flyIcon->frame()); + p.drawImage(rect, _flyIcon); } if (progress > 0.) { p.setOpacity(progress); @@ -142,12 +156,14 @@ int Animation::computeParabolicTop( void Animation::startAnimations() { _center->animate([=] { callback(); }); - _effect->animate([=] { callback(); }); + if (const auto effect = _effect.get()) { + _effect->animate([=] { callback(); }); + } } void Animation::flyCallback() { if (!_fly.animating()) { - _flyIcon = nullptr; + _flyIcon = QImage(); startAnimations(); } callback(); @@ -164,7 +180,7 @@ void Animation::setRepaintCallback(Fn repaint) { } bool Animation::flying() const { - return (_flyIcon != nullptr); + return !_flyIcon.isNull(); } float64 Animation::flyingProgress() const { @@ -173,7 +189,9 @@ float64 Animation::flyingProgress() const { bool Animation::finished() const { return !_valid - || (!_flyIcon && !_center->animating() && !_effect->animating()); + || (_flyIcon.isNull() + && !_center->animating() + && (!_effect || !_effect->animating())); } } // namespace HistoryView::Reactions diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.h index 176670193..6e3f271e1 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_animation.h @@ -47,7 +47,7 @@ private: const not_null<::Data::Reactions*> _owner; Fn _repaint; - std::shared_ptr _flyIcon; + QImage _flyIcon; std::unique_ptr _center; std::unique_ptr _effect; Ui::Animations::Simple _fly; diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp index 18609d00f..cc2fe9f9f 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp @@ -359,7 +359,7 @@ ChosenReaction Manager::lookupChosen(const ReactionId &id) const { return result; } const auto index = _strip.fillChosenIconGetIndex(result); - if (!result.icon) { + if (result.icon.isNull()) { return result; } const auto between = st::reactionCornerSkip; diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp index ecc4aabca..e9cae9758 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp @@ -231,9 +231,9 @@ int Strip::fillChosenIconGetIndex(ChosenReaction &chosen) const { } const auto &icon = *i; if (const auto &appear = icon.appear; appear && appear->animating()) { - chosen.icon = CreateIconSnapshot(icon.appearAnimation, appear.get()); - } else if (const auto &select = icon.select) { - chosen.icon = CreateIconSnapshot(icon.selectAnimation, select.get()); + chosen.icon = appear->frame(); + } else if (const auto &select = icon.select; select && select->valid()) { + chosen.icon = select->frame(); } return (i - begin(_icons)); } diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h index 405261c83..0de93fd6f 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h @@ -27,7 +27,7 @@ namespace HistoryView::Reactions { struct ChosenReaction { FullMsgId context; Data::ReactionId id; - std::shared_ptr icon; + QImage icon; QRect geometry; explicit operator bool() const {