mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 09:41:41 -05:00
Support animated stickers in inline results.
This commit is contained in:
parent
76630528f7
commit
848ea16eef
7 changed files with 57 additions and 25 deletions
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ enum class LottieSize : uchar {
|
|||
StickersPanel,
|
||||
StickersFooter,
|
||||
SetsListThumbnail,
|
||||
InlineResults,
|
||||
};
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue