mirror of https://github.com/procxx/kepka.git
Use Lottie::MultiPlayer in StickersListWidget.
This commit is contained in:
parent
09c9f4ef9a
commit
ad1816cb7c
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
|
#include "lottie/lottie_multi_player.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
namespace Stickers {
|
namespace Stickers {
|
||||||
|
@ -1092,7 +1093,9 @@ RecentStickerPack &GetRecentPack() {
|
||||||
return cRefRecentStickers();
|
return cRefRecentStickers();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
template <typename Method>
|
||||||
|
auto LottieFromDocument(
|
||||||
|
Method &&method,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
LottieSize sizeTag,
|
LottieSize sizeTag,
|
||||||
QSize box) {
|
QSize box) {
|
||||||
|
@ -1100,7 +1103,7 @@ std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||||
const auto filepath = document->filepath();
|
const auto filepath = document->filepath();
|
||||||
if (box.width() & box.height() > kDontCacheLottieAfterArea) {
|
if (box.width() & box.height() > kDontCacheLottieAfterArea) {
|
||||||
// Don't use frame caching for large stickers.
|
// Don't use frame caching for large stickers.
|
||||||
return std::make_unique<Lottie::SinglePlayer>(
|
return method(
|
||||||
Lottie::ReadContent(data, filepath),
|
Lottie::ReadContent(data, filepath),
|
||||||
Lottie::FrameRequest{ box });
|
Lottie::FrameRequest{ box });
|
||||||
}
|
}
|
||||||
|
@ -1120,15 +1123,37 @@ std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||||
weak->data().cacheBigFile().put(key, std::move(data));
|
weak->data().cacheBigFile().put(key, std::move(data));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
return std::make_unique<Lottie::SinglePlayer>(
|
return method(
|
||||||
get,
|
get,
|
||||||
put,
|
put,
|
||||||
Lottie::ReadContent(data, filepath),
|
Lottie::ReadContent(data, filepath),
|
||||||
Lottie::FrameRequest{ box });
|
Lottie::FrameRequest{ box });
|
||||||
}
|
}
|
||||||
return std::make_unique<Lottie::SinglePlayer>(
|
return method(
|
||||||
Lottie::ReadContent(data, filepath),
|
Lottie::ReadContent(data, filepath),
|
||||||
Lottie::FrameRequest{ box });
|
Lottie::FrameRequest{ box });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
LottieSize sizeTag,
|
||||||
|
QSize box) {
|
||||||
|
const auto method = [](auto &&...args) {
|
||||||
|
return std::make_unique<Lottie::SinglePlayer>(
|
||||||
|
std::forward<decltype(args)>(args)...);
|
||||||
|
};
|
||||||
|
return LottieFromDocument(method, document, sizeTag, box);
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
||||||
|
not_null<Lottie::MultiPlayer*> player,
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
LottieSize sizeTag,
|
||||||
|
QSize box) {
|
||||||
|
const auto method = [&](auto &&...args) {
|
||||||
|
return player->append(std::forward<decltype(args)>(args)...);
|
||||||
|
};
|
||||||
|
return LottieFromDocument(method, document, sizeTag, box);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Stickers
|
} // namespace Stickers
|
||||||
|
|
|
@ -13,6 +13,8 @@ class DocumentData;
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
class SinglePlayer;
|
class SinglePlayer;
|
||||||
|
class MultiPlayer;
|
||||||
|
class Animation;
|
||||||
} // namespace Lottie
|
} // namespace Lottie
|
||||||
|
|
||||||
namespace Stickers {
|
namespace Stickers {
|
||||||
|
@ -119,5 +121,10 @@ std::unique_ptr<Lottie::SinglePlayer> LottiePlayerFromDocument(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
LottieSize sizeTag,
|
LottieSize sizeTag,
|
||||||
QSize box);
|
QSize box);
|
||||||
|
not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
||||||
|
not_null<Lottie::MultiPlayer*> player,
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
LottieSize sizeTag,
|
||||||
|
QSize box);
|
||||||
|
|
||||||
} // namespace Stickers
|
} // namespace Stickers
|
||||||
|
|
|
@ -14,7 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_multi_player.h"
|
||||||
|
#include "lottie/lottie_animation.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
|
@ -839,6 +840,7 @@ bool StickersListWidget::enumerateSections(Callback callback) const {
|
||||||
|
|
||||||
StickersListWidget::SectionInfo StickersListWidget::sectionInfo(int section) const {
|
StickersListWidget::SectionInfo StickersListWidget::sectionInfo(int section) const {
|
||||||
Expects(section >= 0 && section < shownSets().size());
|
Expects(section >= 0 && section < shownSets().size());
|
||||||
|
|
||||||
auto result = SectionInfo();
|
auto result = SectionInfo();
|
||||||
enumerateSections([searchForSection = section, &result](const SectionInfo &info) {
|
enumerateSections([searchForSection = section, &result](const SectionInfo &info) {
|
||||||
if (info.section == searchForSection) {
|
if (info.section == searchForSection) {
|
||||||
|
@ -1200,6 +1202,13 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto &set = sets[info.section];
|
auto &set = sets[info.section];
|
||||||
|
if (const auto player = set.lottiePlayer.get()) {
|
||||||
|
const auto paused = controller()->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::SavedGifs);
|
||||||
|
if (!paused) {
|
||||||
|
player->markFrameShown();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (set.externalLayout) {
|
if (set.externalLayout) {
|
||||||
const auto size = (set.flags
|
const auto size = (set.flags
|
||||||
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
||||||
|
@ -1364,21 +1373,41 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
|
||||||
p.drawTextLeft(button.x() - (st::stickerGroupCategoryAdd.width / 2), button.y() + st::stickerGroupCategoryAdd.textTop, width(), _megagroupSetButtonText, _megagroupSetButtonTextWidth);
|
p.drawTextLeft(button.x() - (st::stickerGroupCategoryAdd.width / 2), button.y() + st::stickerGroupCategoryAdd.textTop, width(), _megagroupSetButtonText, _megagroupSetButtonTextWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersListWidget::ensureLottiePlayer(Set &set) {
|
||||||
|
if (set.lottiePlayer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
set.lottiePlayer = std::make_unique<Lottie::MultiPlayer>(
|
||||||
|
getLottieRenderer());
|
||||||
|
const auto raw = set.lottiePlayer.get();
|
||||||
|
set.lottiePlayer->updates(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
const auto &sets = shownSets();
|
||||||
|
|
||||||
|
enumerateSections([&](const SectionInfo &info) {
|
||||||
|
if (shownSets()[info.section].lottiePlayer.get() == raw) {
|
||||||
|
update(
|
||||||
|
0,
|
||||||
|
info.rowsTop,
|
||||||
|
width(),
|
||||||
|
info.rowsBottom - info.rowsTop);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
void StickersListWidget::setupLottie(Set &set, int section, int index) {
|
void StickersListWidget::setupLottie(Set &set, int section, int index) {
|
||||||
auto &sticker = set.stickers[index];
|
auto &sticker = set.stickers[index];
|
||||||
const auto document = sticker.document;
|
const auto document = sticker.document;
|
||||||
|
|
||||||
sticker.animated = Stickers::LottiePlayerFromDocument(
|
ensureLottiePlayer(set);
|
||||||
|
sticker.animated = Stickers::LottieAnimationFromDocument(
|
||||||
|
set.lottiePlayer.get(),
|
||||||
document,
|
document,
|
||||||
Stickers::LottieSize::StickersPanel,
|
Stickers::LottieSize::StickersPanel,
|
||||||
boundingBoxSize() * cIntRetinaFactor());
|
boundingBoxSize() * cIntRetinaFactor());
|
||||||
const auto animation = sticker.animated.get();
|
|
||||||
|
|
||||||
animation->updates(
|
|
||||||
) | rpl::start_with_next_error([=](Lottie::Update update) {
|
|
||||||
rtlupdate(stickerRect(section, index));
|
|
||||||
}, [=](Lottie::Error error) {
|
|
||||||
}, lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize StickersListWidget::boundingBoxSize() const {
|
QSize StickersListWidget::boundingBoxSize() const {
|
||||||
|
@ -1419,11 +1448,6 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
|
||||||
if (sticker.animated && sticker.animated->ready()) {
|
if (sticker.animated && sticker.animated->ready()) {
|
||||||
auto request = Lottie::FrameRequest();
|
auto request = Lottie::FrameRequest();
|
||||||
request.box = boundingBoxSize() * cIntRetinaFactor();
|
request.box = boundingBoxSize() * cIntRetinaFactor();
|
||||||
const auto paused = controller()->isGifPausedAtLeastFor(
|
|
||||||
Window::GifPauseReason::SavedGifs);
|
|
||||||
if (!paused) {
|
|
||||||
sticker.animated->markFrameShown();
|
|
||||||
}
|
|
||||||
const auto frame = sticker.animated->frame(request);
|
const auto frame = sticker.animated->frame(request);
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
QRect(ppos, frame.size() / cIntRetinaFactor()),
|
QRect(ppos, frame.size() / cIntRetinaFactor()),
|
||||||
|
@ -1787,7 +1811,7 @@ void StickersListWidget::refreshStickers() {
|
||||||
refreshFavedStickers();
|
refreshFavedStickers();
|
||||||
refreshRecentStickers(false);
|
refreshRecentStickers(false);
|
||||||
refreshMegagroupStickers(GroupStickersPlace::Visible);
|
refreshMegagroupStickers(GroupStickersPlace::Visible);
|
||||||
for_const (auto setId, Auth().data().stickerSetsOrder()) {
|
for (const auto setId : Auth().data().stickerSetsOrder()) {
|
||||||
const auto externalLayout = false;
|
const auto externalLayout = false;
|
||||||
appendSet(_mySets, setId, externalLayout, AppendSkip::Archived);
|
appendSet(_mySets, setId, externalLayout, AppendSkip::Archived);
|
||||||
}
|
}
|
||||||
|
@ -1796,7 +1820,7 @@ void StickersListWidget::refreshStickers() {
|
||||||
_featuredSets.clear();
|
_featuredSets.clear();
|
||||||
_featuredSets.reserve(Auth().data().featuredStickerSetsOrder().size());
|
_featuredSets.reserve(Auth().data().featuredStickerSetsOrder().size());
|
||||||
|
|
||||||
for_const (auto setId, Auth().data().featuredStickerSetsOrder()) {
|
for (const auto setId : Auth().data().featuredStickerSetsOrder()) {
|
||||||
const auto externalLayout = true;
|
const auto externalLayout = true;
|
||||||
appendSet(_featuredSets, setId, externalLayout, AppendSkip::Installed);
|
appendSet(_featuredSets, setId, externalLayout, AppendSkip::Installed);
|
||||||
}
|
}
|
||||||
|
@ -2311,6 +2335,16 @@ void StickersListWidget::showPreview() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto StickersListWidget::getLottieRenderer()
|
||||||
|
-> std::shared_ptr<Lottie::FrameRenderer> {
|
||||||
|
if (auto result = _lottieRenderer.lock()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
auto result = Lottie::MakeFrameRenderer();
|
||||||
|
_lottieRenderer = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void StickersListWidget::showStickerSet(uint64 setId) {
|
void StickersListWidget::showStickerSet(uint64 setId) {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,9 @@ class RippleAnimation;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
class SinglePlayer;
|
class Animation;
|
||||||
|
class MultiPlayer;
|
||||||
|
class FrameRenderer;
|
||||||
} // namespace Lottie
|
} // namespace Lottie
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
|
@ -141,7 +143,7 @@ private:
|
||||||
|
|
||||||
struct Sticker {
|
struct Sticker {
|
||||||
not_null<DocumentData*> document;
|
not_null<DocumentData*> document;
|
||||||
std::unique_ptr<Lottie::SinglePlayer> animated;
|
Lottie::Animation *animated = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Set {
|
struct Set {
|
||||||
|
@ -165,6 +167,7 @@ private:
|
||||||
ImagePtr thumbnail;
|
ImagePtr thumbnail;
|
||||||
std::vector<Sticker> stickers;
|
std::vector<Sticker> stickers;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
|
std::unique_ptr<Lottie::MultiPlayer> lottiePlayer;
|
||||||
bool externalLayout = false;
|
bool externalLayout = false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
};
|
};
|
||||||
|
@ -223,6 +226,8 @@ private:
|
||||||
void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected);
|
void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected);
|
||||||
void paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected);
|
void paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected);
|
||||||
void paintEmptySearchResults(Painter &p);
|
void paintEmptySearchResults(Painter &p);
|
||||||
|
|
||||||
|
void ensureLottiePlayer(Set &set);
|
||||||
void setupLottie(Set &set, int section, int index);
|
void setupLottie(Set &set, int section, int index);
|
||||||
|
|
||||||
int stickersRight() const;
|
int stickersRight() const;
|
||||||
|
@ -265,6 +270,8 @@ private:
|
||||||
|
|
||||||
void showPreview();
|
void showPreview();
|
||||||
|
|
||||||
|
std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
||||||
|
|
||||||
ChannelData *_megagroupSet = nullptr;
|
ChannelData *_megagroupSet = nullptr;
|
||||||
uint64 _megagroupSetIdRequested = 0;
|
uint64 _megagroupSetIdRequested = 0;
|
||||||
std::vector<Set> _mySets;
|
std::vector<Set> _mySets;
|
||||||
|
@ -273,6 +280,7 @@ private:
|
||||||
base::flat_set<uint64> _installedLocallySets;
|
base::flat_set<uint64> _installedLocallySets;
|
||||||
std::vector<bool> _custom;
|
std::vector<bool> _custom;
|
||||||
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
||||||
|
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
||||||
|
|
||||||
Section _section = Section::Stickers;
|
Section _section = Section::Stickers;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue