diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index 05289283e..dc648b811 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -508,6 +508,8 @@ void HistoryMessageReply::paint( const auto stm = context.messageStyle(); { + const auto opacity = p.opacity(); + const auto outerWidth = w + 2 * x; const auto &bar = !inBubble ? st->msgImgReplyBarColor() : replyToColorKey @@ -518,8 +520,22 @@ void HistoryMessageReply::paint( y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), - w + 2 * x); - const auto opacity = p.opacity(); + outerWidth); + + if (ripple.animation) { + const auto colorOverride = &stm->msgWaveformInactive->c; + p.setOpacity(st::historyPollRippleOpacity); + ripple.animation->paint( + p, + x - st::msgReplyPadding.left(), + y, + outerWidth, + colorOverride); + if (ripple.animation->empty()) { + ripple.animation.reset(); + } + } + p.setOpacity(opacity * kBarAlpha); p.fillRect(rbar, bar); p.setOpacity(opacity); diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index 5a8db07c9..e743932b9 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "spellcheck/spellcheck_types.h" // LanguageId. #include "ui/empty_userpic.h" #include "ui/effects/animations.h" +#include "ui/effects/ripple_animation.h" #include "ui/chat/message_bubble.h" struct WebPageData; @@ -307,6 +308,11 @@ struct HistoryMessageReply bool topicPost = false; bool storyReply = false; + struct final { + mutable std::unique_ptr animation; + QPoint lastPoint; + } ripple; + }; struct HistoryMessageTranslation diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index ad06f53c4..d3ea404c6 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -1600,6 +1600,8 @@ void Message::clickHandlerPressedChanged( toggleTopicButtonRipple(pressed); } else if (_viewButton) { _viewButton->checkLink(handler, pressed); + } else if (const auto reply = displayedReply()) { + toggleReplyRipple(pressed); } } @@ -1639,6 +1641,58 @@ void Message::toggleRightActionRipple(bool pressed) { } } +void Message::toggleReplyRipple(bool pressed) { + const auto reply = displayedReply(); + if (!reply) { + return; + } + + if (pressed) { + if (!reply->ripple.animation && !unwrapped()) { + const auto smallTop = displayFromName() + || displayedTopicButton() + || displayForwardedFrom(); + const auto rounding = countBubbleRounding(); + + using Corner = Ui::BubbleCornerRounding; + using Radius = Ui::CachedCornerRadius; + const auto &small = Ui::CachedCornersMasks(Radius::ThumbSmall); + const auto &large = Ui::CachedCornersMasks(Radius::ThumbLarge); + const auto corners = std::array{{ + ((smallTop || (rounding.topLeft == Corner::Small)) + ? small + : large)[0], + ((smallTop || (rounding.topRight == Corner::Small)) + ? small + : large)[1], + small[2], + small[3], + }}; + + const auto &padding = st::msgReplyPadding; + const auto geometry = countGeometry(); + const auto size = QSize( + geometry.width() + - padding.left() / 2 + - padding.right(), + st::msgReplyBarSize.height() + + padding.top() + + padding.bottom()); + reply->ripple.animation = std::make_unique( + st::defaultRippleAnimation, + Images::Round( + Ui::RippleAnimation::MaskByDrawer(size, true, nullptr), + corners), + [=] { repaint(); }); + } + if (reply->ripple.animation) { + reply->ripple.animation->add(reply->ripple.lastPoint); + } + } else if (reply->ripple.animation) { + reply->ripple.animation->lastStop(); + } +} + BottomRippleMask Message::bottomRippleMask(int buttonHeight) const { using namespace Ui; using namespace Images; @@ -2268,9 +2322,15 @@ bool Message::getStateReplyInfo( if (auto reply = displayedReply()) { int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom(); if (point.y() >= trect.top() && point.y() < trect.top() + h) { + const auto g = QRect( + trect.x(), + trect.y() + st::msgReplyPadding.top(), + trect.width(), + st::msgReplyBarSize.height()); if ((reply->replyToMsg || reply->replyToStory) - && QRect(trect.x(), trect.y() + st::msgReplyPadding.top(), trect.width(), st::msgReplyBarSize.height()).contains(point)) { + && g.contains(point)) { outResult->link = reply->replyToLink(); + reply->ripple.lastPoint = point - g.topLeft(); } return true; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index f9fd8afa7..2c0ebaf0e 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -187,7 +187,8 @@ private: void createTopicButtonRipple(); void toggleRightActionRipple(bool pressed); - void createRightActionRipple(); + + void toggleReplyRipple(bool pressed); void paintCommentsButton( Painter &p, diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 0bee2fbf0..074f89dab 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -1064,8 +1064,18 @@ TextState Gif::textState(QPoint point, StateRequest request) const { recth -= skip; } if (reply) { - if (QRect(rectx, recty, rectw, recth).contains(point)) { + const auto replyRect = QRect(rectx, recty, rectw, recth); + if (replyRect.contains(point)) { result.link = reply->replyToLink(); + reply->ripple.lastPoint = point - replyRect.topLeft(); + if (!reply->ripple.animation) { + reply->ripple.animation = std::make_unique( + st::defaultRippleAnimation, + Ui::RippleAnimation::RoundRectMask( + replyRect.size(), + st::roundRadiusSmall), + [=] { item->history()->owner().requestItemRepaint(item); }); + } return result; } } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp index cd3674de1..3348a1855 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/media/history_view_media_unwrapped.h" +#include "data/data_session.h" +#include "history/history.h" #include "history/view/media/history_view_media_common.h" #include "history/view/media/history_view_sticker.h" #include "history/view/history_view_element.h" @@ -460,8 +462,18 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const { recth -= skip; } if (reply) { - if (QRect(rectx, recty, rectw, recth).contains(point)) { + const auto replyRect = QRect(rectx, recty, rectw, recth); + if (replyRect.contains(point)) { result.link = reply->replyToLink(); + reply->ripple.lastPoint = point - replyRect.topLeft(); + if (!reply->ripple.animation) { + reply->ripple.animation = std::make_unique( + st::defaultRippleAnimation, + Ui::RippleAnimation::RoundRectMask( + replyRect.size(), + st::roundRadiusSmall), + [=] { item->history()->owner().requestItemRepaint(item); }); + } return result; } }