Added ripple animation to message replies.

This commit is contained in:
23rd 2023-08-11 15:23:27 +03:00 committed by John Preston
parent 238d4b8e17
commit 717041a462
6 changed files with 111 additions and 6 deletions

View File

@ -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);

View File

@ -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<Ui::RippleAnimation> animation;
QPoint lastPoint;
} ripple;
};
struct HistoryMessageTranslation

View File

@ -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<QImage, 4>{{
((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<Ui::RippleAnimation>(
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;
}

View File

@ -187,7 +187,8 @@ private:
void createTopicButtonRipple();
void toggleRightActionRipple(bool pressed);
void createRightActionRipple();
void toggleReplyRipple(bool pressed);
void paintCommentsButton(
Painter &p,

View File

@ -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<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::RoundRectMask(
replyRect.size(),
st::roundRadiusSmall),
[=] { item->history()->owner().requestItemRepaint(item); });
}
return result;
}
}

View File

@ -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<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::RoundRectMask(
replyRect.size(),
st::roundRadiusSmall),
[=] { item->history()->owner().requestItemRepaint(item); });
}
return result;
}
}