Removed cache from sending animation.

This commit is contained in:
23rd 2022-02-10 22:34:50 +03:00 committed by John Preston
parent 4cebccd6dc
commit e72be4abfc

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "ui/effects/message_sending_animation_controller.h" #include "ui/effects/message_sending_animation_controller.h"
#include "data/data_session.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "history/view/history_view_list_widget.h" // kItemRevealDuration #include "history/view/history_view_list_widget.h" // kItemRevealDuration
@ -46,18 +47,14 @@ protected:
private: private:
using Context = Ui::ChatPaintContext; using Context = Ui::ChatPaintContext;
QImage drawMedia(
Context::SkipDrawingParts skipParts,
const QRect &rect) const;
void updateCache();
void createSurrounding(); void createSurrounding();
const not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
Fn<not_null<HistoryView::Element*>()> _view; Fn<not_null<HistoryView::Element*>()> _view;
not_null<ChatTheme*> _theme; not_null<ChatTheme*> _theme;
QImage _cache;
QRect _from; QRect _from;
QRect _to; QRect _to;
QRect _innerContentRect;
Animations::Simple _animation; Animations::Simple _animation;
float64 _minScale = 0; float64 _minScale = 0;
@ -77,7 +74,8 @@ Content::Content(
, _controller(controller) , _controller(controller)
, _view(std::move(to.view)) , _view(std::move(to.view))
, _theme(to.theme) , _theme(to.theme)
, _from(parent->mapFromGlobal(globalGeometryFrom)) { , _from(parent->mapFromGlobal(globalGeometryFrom))
, _innerContentRect(_view()->media()->contentRectForReactions()) {
Expects(_view != nullptr); Expects(_view != nullptr);
show(); show();
@ -92,22 +90,18 @@ Content::Content(
_minScale = float64(_from.height()) / _to.height(); _minScale = float64(_from.height()) / _to.height();
}, lifetime()); }, lifetime());
updateCache();
_controller->session().downloaderTaskFinished( _controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
updateCache(); update();
}, lifetime()); }, lifetime());
const auto innerContentRect resize(_innerContentRect.size());
= _view()->media()->contentRectForReactions();
auto animationCallback = [=](float64 value) { auto animationCallback = [=](float64 value) {
auto resultFrom = QRect( auto resultFrom = rect();
QPoint(),
_cache.size() / style::DevicePixelRatio());
resultFrom.moveCenter(_from.center()); resultFrom.moveCenter(_from.center());
const auto resultTo = _to.topLeft() + innerContentRect.topLeft(); const auto resultTo = _to.topLeft() + _innerContentRect.topLeft();
const auto x = anim::interpolate(resultFrom.x(), resultTo.x(), value); const auto x = anim::interpolate(resultFrom.x(), resultTo.x(), value);
const auto y = anim::interpolate(resultFrom.y(), resultTo.y(), value); const auto y = anim::interpolate(resultFrom.y(), resultTo.y(), value);
moveToLeft(x, y); moveToLeft(x, y);
@ -118,12 +112,15 @@ Content::Content(
} }
if (_surrounding) { if (_surrounding) {
_surrounding->moveToLeft( _surrounding->moveToLeft(
x - innerContentRect.x(), x - _innerContentRect.x(),
y - innerContentRect.y()); y - _innerContentRect.y());
} }
if (value == 1.) { if (value == 1.) {
const auto view = _view();
const auto controller = _controller;
_destroyRequests.fire({}); _destroyRequests.fire({});
controller->session().data().requestViewRepaint(view);
} }
}; };
animationCallback(0.); animationCallback(0.);
@ -139,64 +136,36 @@ void Content::paintEvent(QPaintEvent *e) {
p.fillRect(e->rect(), Qt::transparent); p.fillRect(e->rect(), Qt::transparent);
if (_cache.isNull()) {
return;
}
const auto progress = _animation.value(_animation.animating() ? 0. : 1.); const auto progress = _animation.value(_animation.animating() ? 0. : 1.);
const auto scale = anim::interpolateF(_minScale, 1., progress); const auto scale = anim::interpolateF(_minScale, 1., progress);
const auto size = _cache.size() / style::DevicePixelRatio();
p.translate( p.translate(
(1 - progress) * OffsetMid(size.width(), _minScale), (1 - progress) * OffsetMid(width(), _minScale),
(1 - progress) * OffsetMid(size.height(), _minScale)); (1 - progress) * OffsetMid(height(), _minScale));
p.scale(scale, scale); p.scale(scale, scale);
p.drawImage(QPoint(), _cache);
auto context = _controller->preparePaintContext({
.theme = _theme,
});
const auto view = _view();
context.skipDrawingParts = Context::SkipDrawingParts::Surrounding;
context.outbg = view->hasOutLayout();
p.translate(-_innerContentRect.topLeft());
view->media()->draw(p, context);
} }
rpl::producer<> Content::destroyRequests() const { rpl::producer<> Content::destroyRequests() const {
return _destroyRequests.events(); return _destroyRequests.events();
} }
void Content::updateCache() {
_cache = drawMedia(
Context::SkipDrawingParts::Surrounding,
_view()->media()->contentRectForReactions());
resize(_cache.size() / style::DevicePixelRatio());
}
QImage Content::drawMedia(
Context::SkipDrawingParts skipParts,
const QRect &rect) const {
auto image = QImage(
rect.size() * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(style::DevicePixelRatio());
image.fill(Qt::transparent);
{
Painter p(&image);
PainterHighQualityEnabler hq(p);
auto context = _controller->preparePaintContext({
.theme = _theme,
});
const auto view = _view();
context.skipDrawingParts = skipParts;
context.outbg = view->hasOutLayout();
p.translate(-rect.left(), -rect.top());
view->media()->draw(p, context);
}
return image;
}
void Content::createSurrounding() { void Content::createSurrounding() {
_surrounding = base::make_unique_q<Ui::RpWidget>(parentWidget()); _surrounding = base::make_unique_q<Ui::RpWidget>(parentWidget());
_surrounding->setAttribute(Qt::WA_TransparentForMouseEvents); _surrounding->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto view = _view(); const auto view = _view();
const auto surroundingSize = view->innerGeometry().size(); const auto surroundingSize = view->innerGeometry().size();
const auto offset = view->media()->contentRectForReactions().topLeft(); const auto offset = _innerContentRect.topLeft();
_surrounding->resize(surroundingSize); _surrounding->resize(surroundingSize);
_surrounding->show(); _surrounding->show();