Support animated stickers in inline results.

This commit is contained in:
John Preston 2019-07-02 15:41:50 +02:00
parent 76630528f7
commit 848ea16eef
7 changed files with 57 additions and 25 deletions

View File

@ -524,9 +524,8 @@ void StickerSetBox::Inner::setupLottie(int index) {
const auto animation = element.animated.get();
animation->updates(
) | rpl::start_with_next_error([=](Lottie::Update update) {
this->update();
}, [=](Lottie::Error error) {
) | rpl::start_with_next([=] {
update();
}, lifetime());
}

View File

@ -126,6 +126,7 @@ enum class LottieSize : uchar {
StickersPanel,
StickersFooter,
SetsListThumbnail,
InlineResults,
};
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(

View File

@ -126,7 +126,6 @@ private:
int newSelected,
ValidateIconAnimations animations);
void validateIconLottieAnimation(const StickerIcon &icon);
QSize iconBox() const;
void refreshIconsGeometry(ValidateIconAnimations animations);
void refillLottieData();
@ -701,12 +700,6 @@ void StickersListWidget::Footer::paintFeaturedStickerSetsBadge(Painter &p, int i
}
}
QSize StickersListWidget::Footer::iconBox() const {
return QSize(
st::stickerIconWidth - 2 * st::stickerIconPadding,
st::emojiFooterHeight - 2 * st::stickerIconPadding);
}
void StickersListWidget::Footer::validateIconLottieAnimation(
const StickerIcon &icon) {
if (icon.lottie
@ -717,7 +710,10 @@ void StickersListWidget::Footer::validateIconLottieAnimation(
icon.thumbnail,
icon.sticker,
Stickers::LottieSize::StickersFooter,
iconBox() * cIntRetinaFactor(),
QSize(
st::stickerIconWidth - 2 * st::stickerIconPadding,
st::emojiFooterHeight - 2 * st::stickerIconPadding
) * cIntRetinaFactor(),
_pan->getLottieRenderer());
if (!player) {
return;
@ -768,9 +764,7 @@ void StickersListWidget::Footer::paintSetIcon(
width(),
thumb->pix(origin, icon.pixw, icon.pixh));
} else if (icon.lottie->ready()) {
auto request = Lottie::FrameRequest();
request.box = iconBox() * cIntRetinaFactor();
const auto frame = icon.lottie->frame(request);
const auto frame = icon.lottie->frame();
const auto size = frame.size() / cIntRetinaFactor();
p.drawImage(
QRect(

View File

@ -104,13 +104,12 @@ void HistorySticker::setupLottie() {
_parent->data()->history()->owner().registerHeavyViewPart(_parent);
_lottie->updates(
) | rpl::start_with_next_error([=](Lottie::Update update) {
) | rpl::start_with_next([=](Lottie::Update update) {
update.data.match([&](const Lottie::Information &information) {
_parent->data()->history()->owner().requestViewResize(_parent);
}, [&](const Lottie::DisplayFrameRequest &request) {
_parent->data()->history()->owner().requestViewRepaint(_parent);
});
}, [=](Lottie::Error error) {
}, _lifetime);
}
@ -126,7 +125,7 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, c
auto sticker = _data->sticker();
if (!sticker) return;
if (sticker->animated && _data->loaded() && !_lottie) {
if (sticker->animated && !_lottie && _data->loaded()) {
const_cast<HistorySticker*>(this)->setupLottie();
}

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_chat_helpers.h"
#include "styles/style_widgets.h"
#include "inline_bots/inline_bot_result.h"
#include "lottie/lottie_single_player.h"
#include "media/audio/media_audio.h"
#include "media/clip/media_clip_reader.h"
#include "media/player/media_player_instance.h"
@ -387,6 +388,8 @@ Sticker::Sticker(not_null<Context*> context, Result *result)
: FileBase(context, result) {
}
Sticker::~Sticker() = default;
void Sticker::initDimensions() {
_maxw = st::stickerPanSize.width();
_minh = st::stickerPanSize.height();
@ -411,7 +414,17 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context)
}
prepareThumbnail();
if (!_thumb.isNull()) {
if (_lottie && _lottie->ready()) {
const auto frame = _lottie->frame();
_lottie->markFrameShown();
const auto size = frame.size() / cIntRetinaFactor();
const auto pos = QPoint(
(st::stickerPanSize.width() - size.width()) / 2,
(st::stickerPanSize.height() - size.height()) / 2);
p.drawImage(
QRect(pos, size),
frame);
} else if (!_thumb.isNull()) {
int w = _thumb.width() / cIntRetinaFactor(), h = _thumb.height() / cIntRetinaFactor();
QPoint pos = QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
p.drawPixmap(pos, _thumb);
@ -450,11 +463,31 @@ QSize Sticker::getThumbSize() const {
return QSize(qMax(w, 1), qMax(h, 1));
}
void Sticker::setupLottie(not_null<DocumentData*> document) const {
_lottie = Stickers::LottiePlayerFromDocument(
document,
Stickers::LottieSize::InlineResults,
QSize(
st::stickerPanSize.width() - st::buttonRadius * 2,
st::stickerPanSize.height() - st::buttonRadius * 2
) * cIntRetinaFactor());
_lottie->updates(
) | rpl::start_with_next([=] {
update();
}, _lifetime);
}
void Sticker::prepareThumbnail() const {
if (const auto document = getShownDocument()) {
if (document->sticker()->animated
&& !_lottie
&& document->loaded()) {
setupLottie(document);
}
document->checkStickerSmall();
if (const auto sticker = document->getStickerSmall()) {
if (!_thumbLoaded && sticker->loaded()) {
if (!_lottie && !_thumbLoaded && sticker->loaded()) {
const auto thumbSize = getThumbSize();
_thumb = sticker->pix(
document->stickerSetOrigin(),

View File

@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/radial_animation.h"
#include "ui/text/text.h"
namespace Lottie {
class SinglePlayer;
} // namespace Lottie
namespace InlineBots {
namespace Layout {
namespace internal {
@ -151,6 +155,7 @@ private:
class Sticker : public FileBase {
public:
Sticker(not_null<Context*> context, Result *result);
~Sticker();
// Not used anywhere currently.
//Sticker(not_null<Context*> context, DocumentData *document);
@ -173,14 +178,18 @@ public:
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
private:
void setupLottie(not_null<DocumentData*> document) const;
QSize getThumbSize() const;
void prepareThumbnail() const;
mutable Ui::Animations::Simple _a_over;
mutable bool _active = false;
mutable QPixmap _thumb;
mutable bool _thumbLoaded = false;
void prepareThumbnail() const;
mutable std::unique_ptr<Lottie::SinglePlayer> _lottie;
mutable rpl::lifetime _lifetime;
};

View File

@ -879,10 +879,8 @@ void MediaPreviewWidget::paintEvent(QPaintEvent *e) {
if (!_lottie || !_lottie->ready()) {
return QImage();
}
auto request = Lottie::FrameRequest();
request.box = currentDimensions() * cIntRetinaFactor();
_lottie->markFrameShown();
return _lottie->frame(request);
return _lottie->frame();
}();
const auto pixmap = image.isNull() ? currentImage() : QPixmap();
const auto size = image.isNull() ? pixmap.size() : image.size();
@ -1054,13 +1052,12 @@ void MediaPreviewWidget::setupLottie() {
Lottie::FrameRequest{ currentDimensions() * cIntRetinaFactor() });
_lottie->updates(
) | rpl::start_with_next_error([=](Lottie::Update update) {
) | rpl::start_with_next([=](Lottie::Update update) {
update.data.match([&](const Lottie::Information &) {
this->update();
}, [&](const Lottie::DisplayFrameRequest &) {
this->update(updateArea());
});
}, [=](Lottie::Error error) {
}, lifetime());
}