diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 5c837c3b1..1a7f98a5c 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -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(), diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 950f1be2e..237a73b02 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -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 &messages); void messagesReceivedDown(PeerData *peer, const QVector &messages); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index f276c5aa3..16f130f6c 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -5413,7 +5413,7 @@ void HistoryWidget::startMessageSendingAnimation( sendingAnimation.startAnimation({ .globalEndGeometry = std::move(globalEndGeometry), .view = [=] { return item->mainView(); }, - .theme = _list->theme(), + .paintContext = [=] { return _list->preparePaintContext({}); }, }); } diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 4ceff1d21..6ddff5ee2 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -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) { diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index 17ae06dd9..e917c5b77 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -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 enforceViewForItem(not_null item); diff --git a/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.cpp b/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.cpp index 1ac9c7e7d..242a756b8 100644 --- a/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.cpp +++ b/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.cpp @@ -48,10 +48,10 @@ private: using Context = Ui::ChatPaintContext; void createSurrounding(); + not_null view() const; const not_null _controller; - Fn()> _view; - not_null _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 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(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()); } diff --git a/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.h b/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.h index 0e8bbfdaa..97f937f80 100644 --- a/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.h +++ b/Telegram/SourceFiles/ui/effects/message_sending_animation_controller.h @@ -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 globalEndGeometry; Fn()> view; - not_null theme; + Fn paintContext; }; void appendSending(MessageSendingAnimationFrom from);