Fixed simple animation of message sending with custom chat themes.

This commit is contained in:
23rd 2022-02-11 09:38:44 +03:00 committed by John Preston
parent a0a857a6db
commit 6939da2fd2
7 changed files with 60 additions and 44 deletions

View file

@ -838,6 +838,19 @@ void HistoryInner::paintEmpty(
_emptyPainter->paint(p, st, width, height);
}
Ui::ChatPaintContext HistoryInner::preparePaintContext(
const QRect &clip) const {
const auto visibleAreaTopGlobal = mapToGlobal(
QPoint(0, _visibleAreaTop)).y();
return _controller->preparePaintContext({
.theme = _theme.get(),
.visibleAreaTop = _visibleAreaTop,
.visibleAreaTopGlobal = visibleAreaTopGlobal,
.visibleAreaWidth = width(),
.clip = clip,
});
}
void HistoryInner::paintEvent(QPaintEvent *e) {
if (Ui::skipPaintEvent(this, e)) {
return;
@ -852,15 +865,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
Painter p(this);
auto clip = e->rect();
const auto visibleAreaTopGlobal = mapToGlobal(
QPoint(0, _visibleAreaTop)).y();
auto context = _controller->preparePaintContext({
.theme = _theme.get(),
.visibleAreaTop = _visibleAreaTop,
.visibleAreaTopGlobal = visibleAreaTopGlobal,
.visibleAreaWidth = width(),
.clip = clip,
});
auto context = preparePaintContext(clip);
_pathGradient->startFrame(
0,
width(),

View file

@ -44,6 +44,7 @@ class ChatTheme;
class ChatStyle;
class PopupMenu;
enum class ReportReason;
struct ChatPaintContext;
class PathShiftGradient;
} // namespace Ui
@ -89,6 +90,8 @@ public:
return _theme.get();
}
Ui::ChatPaintContext preparePaintContext(const QRect &clip) const;
void messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages);
void messagesReceivedDown(PeerData *peer, const QVector<MTPMessage> &messages);

View file

@ -5413,7 +5413,7 @@ void HistoryWidget::startMessageSendingAnimation(
sendingAnimation.startAnimation({
.globalEndGeometry = std::move(globalEndGeometry),
.view = [=] { return item->mainView(); },
.theme = _list->theme(),
.paintContext = [=] { return _list->preparePaintContext({}); },
});
}

View file

@ -1595,7 +1595,7 @@ void ListWidget::startMessageSendingAnimation(
sendingAnimation.startAnimation({
.globalEndGeometry = std::move(globalEndGeometry),
.view = [=] { return viewForItem(item); },
.theme = _delegate->listChatTheme(),
.paintContext = [=] { return preparePaintContext({}); },
});
}
@ -1733,6 +1733,17 @@ TextSelection ListWidget::itemRenderSelection(
return TextSelection();
}
Ui::ChatPaintContext ListWidget::preparePaintContext(
const QRect &clip) const {
return controller()->preparePaintContext({
.theme = _delegate->listChatTheme(),
.visibleAreaTop = _visibleTop,
.visibleAreaTopGlobal = mapToGlobal(QPoint(0, _visibleTop)).y(),
.visibleAreaWidth = width(),
.clip = clip,
});
}
void ListWidget::paintEvent(QPaintEvent *e) {
if (Ui::skipPaintEvent(this, e)) {
return;
@ -1762,13 +1773,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
_reactionsManager->startEffectsCollection();
auto top = itemTop(from->get());
auto context = controller()->preparePaintContext({
.theme = _delegate->listChatTheme(),
.visibleAreaTop = _visibleTop,
.visibleAreaTopGlobal = mapToGlobal(QPoint(0, _visibleTop)).y(),
.visibleAreaWidth = width(),
.clip = clip,
}).translated(0, -top);
auto context = preparePaintContext(clip).translated(0, -top);
p.translate(0, top);
const auto &sendingAnimation = _controller->sendingAnimation();
for (auto i = from; i != to; ++i) {

View file

@ -22,6 +22,7 @@ class Session;
namespace Ui {
class PopupMenu;
class ChatTheme;
struct ChatPaintContext;
} // namespace Ui
namespace Window {
@ -376,6 +377,8 @@ private:
void saveScrollState();
void restoreScrollState();
Ui::ChatPaintContext preparePaintContext(const QRect &clip) const;
Element *viewForItem(FullMsgId itemId) const;
Element *viewForItem(const HistoryItem *item) const;
not_null<Element*> enforceViewForItem(not_null<HistoryItem*> item);

View file

@ -48,10 +48,10 @@ private:
using Context = Ui::ChatPaintContext;
void createSurrounding();
not_null<HistoryView::Element*> view() const;
const not_null<Window::SessionController*> _controller;
Fn<not_null<HistoryView::Element*>()> _view;
not_null<ChatTheme*> _theme;
MessageSendingAnimationController::SendingInfoTo _toInfo;
QRect _from;
QRect _to;
QRect _innerContentRect;
@ -72,18 +72,18 @@ Content::Content(
MessageSendingAnimationController::SendingInfoTo &&to)
: RpWidget(parent)
, _controller(controller)
, _view(std::move(to.view))
, _theme(to.theme)
, _toInfo(std::move(to))
, _from(parent->mapFromGlobal(globalGeometryFrom))
, _innerContentRect(_view()->media()->contentRectForReactions()) {
Expects(_view != nullptr);
, _innerContentRect(view()->media()->contentRectForReactions()) {
Expects(_toInfo.view != nullptr);
Expects(_toInfo.paintContext != nullptr);
show();
setAttribute(Qt::WA_TransparentForMouseEvents);
raise();
base::take(
to.globalEndGeometry
_toInfo.globalEndGeometry
) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](const QRect &r) {
_to = parent->mapFromGlobal(r);
@ -117,10 +117,10 @@ Content::Content(
}
if (value == 1.) {
const auto view = _view();
const auto currentView = view();
const auto controller = _controller;
_destroyRequests.fire({});
controller->session().data().requestViewRepaint(view);
controller->session().data().requestViewRepaint(currentView);
}
};
animationCallback(0.);
@ -131,6 +131,10 @@ Content::Content(
HistoryView::ListWidget::kItemRevealDuration);
}
not_null<HistoryView::Element*> Content::view() const {
return _toInfo.view();
}
void Content::paintEvent(QPaintEvent *e) {
Painter p(this);
@ -145,14 +149,13 @@ void Content::paintEvent(QPaintEvent *e) {
(1 - progress) * OffsetMid(height(), _minScale));
p.scale(scale, scale);
auto context = _controller->preparePaintContext({
.theme = _theme,
});
const auto view = _view();
const auto currentView = view();
auto context = _toInfo.paintContext();
context.skipDrawingParts = Context::SkipDrawingParts::Surrounding;
context.outbg = view->hasOutLayout();
context.outbg = currentView->hasOutLayout();
p.translate(-_innerContentRect.topLeft());
view->media()->draw(p, context);
currentView->media()->draw(p, context);
}
rpl::producer<> Content::destroyRequests() const {
@ -163,8 +166,8 @@ void Content::createSurrounding() {
_surrounding = base::make_unique_q<Ui::RpWidget>(parentWidget());
_surrounding->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto view = _view();
const auto surroundingSize = view->innerGeometry().size();
const auto currentView = view();
const auto surroundingSize = currentView->innerGeometry().size();
const auto offset = _innerContentRect.topLeft();
_surrounding->resize(surroundingSize);
@ -194,16 +197,13 @@ void Content::createSurrounding() {
revProgress * OffsetMid(size.height() + offset.y(), _minScale));
p.scale(scale, scale);
auto context = _controller->preparePaintContext({
.theme = _theme,
});
const auto view = _view();
const auto currentView = view();
auto context = _toInfo.paintContext();
context.skipDrawingParts = Context::SkipDrawingParts::Content;
context.outbg = view->hasOutLayout();
context.outbg = currentView->hasOutLayout();
view->media()->draw(p, context);
currentView->media()->draw(p, context);
}, _surrounding->lifetime());
}

View file

@ -21,7 +21,7 @@ class SessionController;
namespace Ui {
class RpWidget;
class ChatTheme;
struct ChatPaintContext;
class MessageSendingAnimationController final {
public:
@ -31,7 +31,7 @@ public:
struct SendingInfoTo {
rpl::producer<QRect> globalEndGeometry;
Fn<not_null<HistoryView::Element*>()> view;
not_null<Ui::ChatTheme*> theme;
Fn<Ui::ChatPaintContext()> paintContext;
};
void appendSending(MessageSendingAnimationFrom from);