Added ripple animation to message replies.
This commit is contained in:
parent
238d4b8e17
commit
717041a462
|
@ -508,6 +508,8 @@ void HistoryMessageReply::paint(
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const auto opacity = p.opacity();
|
||||||
|
const auto outerWidth = w + 2 * x;
|
||||||
const auto &bar = !inBubble
|
const auto &bar = !inBubble
|
||||||
? st->msgImgReplyBarColor()
|
? st->msgImgReplyBarColor()
|
||||||
: replyToColorKey
|
: replyToColorKey
|
||||||
|
@ -518,8 +520,22 @@ void HistoryMessageReply::paint(
|
||||||
y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(),
|
y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(),
|
||||||
st::msgReplyBarSize.width(),
|
st::msgReplyBarSize.width(),
|
||||||
st::msgReplyBarSize.height(),
|
st::msgReplyBarSize.height(),
|
||||||
w + 2 * x);
|
outerWidth);
|
||||||
const auto opacity = p.opacity();
|
|
||||||
|
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.setOpacity(opacity * kBarAlpha);
|
||||||
p.fillRect(rbar, bar);
|
p.fillRect(rbar, bar);
|
||||||
p.setOpacity(opacity);
|
p.setOpacity(opacity);
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "spellcheck/spellcheck_types.h" // LanguageId.
|
#include "spellcheck/spellcheck_types.h" // LanguageId.
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
|
||||||
struct WebPageData;
|
struct WebPageData;
|
||||||
|
@ -307,6 +308,11 @@ struct HistoryMessageReply
|
||||||
bool topicPost = false;
|
bool topicPost = false;
|
||||||
bool storyReply = false;
|
bool storyReply = false;
|
||||||
|
|
||||||
|
struct final {
|
||||||
|
mutable std::unique_ptr<Ui::RippleAnimation> animation;
|
||||||
|
QPoint lastPoint;
|
||||||
|
} ripple;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistoryMessageTranslation
|
struct HistoryMessageTranslation
|
||||||
|
|
|
@ -1600,6 +1600,8 @@ void Message::clickHandlerPressedChanged(
|
||||||
toggleTopicButtonRipple(pressed);
|
toggleTopicButtonRipple(pressed);
|
||||||
} else if (_viewButton) {
|
} else if (_viewButton) {
|
||||||
_viewButton->checkLink(handler, pressed);
|
_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 {
|
BottomRippleMask Message::bottomRippleMask(int buttonHeight) const {
|
||||||
using namespace Ui;
|
using namespace Ui;
|
||||||
using namespace Images;
|
using namespace Images;
|
||||||
|
@ -2268,9 +2322,15 @@ bool Message::getStateReplyInfo(
|
||||||
if (auto reply = displayedReply()) {
|
if (auto reply = displayedReply()) {
|
||||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||||
if (point.y() >= trect.top() && point.y() < trect.top() + h) {
|
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)
|
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();
|
outResult->link = reply->replyToLink();
|
||||||
|
reply->ripple.lastPoint = point - g.topLeft();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,8 @@ private:
|
||||||
void createTopicButtonRipple();
|
void createTopicButtonRipple();
|
||||||
|
|
||||||
void toggleRightActionRipple(bool pressed);
|
void toggleRightActionRipple(bool pressed);
|
||||||
void createRightActionRipple();
|
|
||||||
|
void toggleReplyRipple(bool pressed);
|
||||||
|
|
||||||
void paintCommentsButton(
|
void paintCommentsButton(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
|
|
@ -1064,8 +1064,18 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
|
||||||
recth -= skip;
|
recth -= skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
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();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "history/view/media/history_view_media_unwrapped.h"
|
#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_media_common.h"
|
||||||
#include "history/view/media/history_view_sticker.h"
|
#include "history/view/media/history_view_sticker.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
@ -460,8 +462,18 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
||||||
recth -= skip;
|
recth -= skip;
|
||||||
}
|
}
|
||||||
if (reply) {
|
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();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user