2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

Show animated thumbnails in sets box.

This commit is contained in:
John Preston
2019-07-02 15:20:04 +02:00
parent 3b645422ff
commit 76630528f7
8 changed files with 168 additions and 60 deletions

View File

@@ -20,8 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "storage/localstorage.h"
#include "dialogs/dialogs_layout.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "lottie/lottie_single_player.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/scroll_area.h"
@@ -31,7 +30,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/input_fields.h"
#include "ui/image/image.h"
#include "window/window_session_controller.h"
#include "auth_session.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
namespace {
@@ -655,7 +657,8 @@ StickersBox::Inner::Row::Row(
StickersBox::Inner::Row::~Row() = default;
StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidget(parent)
StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section)
: RpWidget(parent)
, _section(section)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
@@ -669,7 +672,8 @@ StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidg
setup();
}
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup) : TWidget(parent)
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup)
: RpWidget(parent)
, _section(StickersBox::Section::Installed)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
@@ -794,7 +798,7 @@ QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
return QRect(buttonx, buttony, buttonw, buttonh);
}
void StickersBox::Inner::paintRow(Painter &p, Row *set, int index) {
void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
auto xadd = 0, yadd = qRound(set->yadd.current());
if (xadd || yadd) p.translate(xadd, yadd);
@@ -854,17 +858,7 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index) {
}
if (set->sticker) {
const auto origin = Data::FileOriginStickerSet(
set->id,
set->accessHash);
const auto thumb = set->thumbnail
? set->thumbnail.get()
: set->sticker->thumbnail();
if (thumb) {
thumb->load(origin);
auto pix = thumb->pix(origin, set->pixw, set->pixh);
p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix);
}
paintRowThumbnail(p, set, stickerx);
}
int namex = stickerx + st::contactsPhotoSize + st::contactsPadding.left();
@@ -897,7 +891,97 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index) {
if (xadd || yadd) p.translate(-xadd, -yadd);
}
void StickersBox::Inner::paintFakeButton(Painter &p, Row *set, int index) {
void StickersBox::Inner::paintRowThumbnail(
Painter &p,
not_null<Row*> set,
int left) {
const auto origin = Data::FileOriginStickerSet(
set->id,
set->accessHash);
const auto thumb = set->thumbnail
? set->thumbnail.get()
: set->sticker->thumbnail();
if (!thumb) {
return;
}
thumb->load(origin);
validateLottieAnimation(set);
if (!set->lottie) {
if (!thumb->loaded()) {
return;
}
p.drawPixmapLeft(
left + (st::contactsPhotoSize - set->pixw) / 2,
st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2,
width(),
thumb->pix(origin, set->pixw, set->pixh));
} else if (set->lottie->ready()) {
const auto frame = set->lottie->frame();
const auto size = frame.size() / cIntRetinaFactor();
p.drawImage(
QRect(
left + (st::contactsPhotoSize - size.width()) / 2,
st::contactsPadding.top() + (st::contactsPhotoSize - size.height()) / 2,
size.width(),
size.height()),
frame);
const auto controller = App::wnd()->sessionController();
const auto paused = controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer);
if (!paused) {
set->lottie->markFrameShown();
}
}
}
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> set) {
if (set->lottie
|| !Stickers::HasLottieThumbnail(set->thumbnail, set->sticker)) {
return;
}
auto player = Stickers::LottieThumbnail(
set->thumbnail,
set->sticker,
Stickers::LottieSize::SetsListThumbnail,
QSize(
st::contactsPhotoSize,
st::contactsPhotoSize) * cIntRetinaFactor());
if (!player) {
return;
}
set->lottie = std::move(player);
set->lottie->updates(
) | rpl::start_with_next([=] {
updateRowThumbnail(set);
}, lifetime());
}
void StickersBox::Inner::updateRowThumbnail(not_null<Row*> set) {
const auto rowTop = [&] {
if (set == _megagroupSelectedSet.get()) {
return _megagroupDivider->y() - _rowHeight;
}
auto top = _itemsTop;
for (const auto &row : _rows) {
if (row.get() == set) {
return top + qRound(row->yadd.current());
}
top += _rowHeight;
}
Unexpected("StickersBox::Inner::updateRowThumbnail: row not found");
}();
const auto left = st::contactsPadding.left()
+ ((!_megagroupSet && _section == Section::Installed)
? st::stickersReorderIcon.width() + st::stickersReorderSkip
: 0);
update(
left,
rowTop + st::contactsPadding.top(),
st::contactsPhotoSize,
st::contactsPhotoSize);
}
void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> set, int index) {
auto removeButton = (_section == Section::Installed && !set->removed);
auto rect = relativeButtonRect(removeButton);
if (_section != Section::Installed && set->installed && !set->archived && !set->removed) {
@@ -1535,36 +1619,41 @@ void StickersBox::Inner::updateSize(int newWidth) {
void StickersBox::Inner::updateRows() {
int maxNameWidth = countMaxNameWidth();
auto &sets = Auth().data().stickerSets();
for_const (auto &row, _rows) {
auto it = sets.constFind(row->id);
if (it != sets.cend()) {
auto &set = it.value();
if (!row->sticker) {
auto thumbnail = ImagePtr();
auto sticker = (DocumentData*)nullptr;
auto pixw = 0, pixh = 0;
fillSetCover(set, &thumbnail, &sticker, &pixw, &pixh);
if (sticker) {
row->thumbnail = thumbnail;
row->sticker = sticker;
row->pixw = pixw;
row->pixh = pixh;
}
}
if (!row->isRecentSet()) {
auto wasInstalled = row->installed;
auto wasArchived = row->archived;
fillSetFlags(set, &row->installed, &row->official, &row->unread, &row->archived);
if (_section == Section::Installed) {
row->archived = false;
}
if (row->installed != wasInstalled || row->archived != wasArchived) {
row->ripple.reset();
}
}
row->title = fillSetTitle(set, maxNameWidth, &row->titleWidth);
row->count = fillSetCount(set);
for (const auto &row : _rows) {
const auto it = sets.constFind(row->id);
if (it == sets.cend()) {
continue;
}
const auto &set = it.value();
if (!row->sticker) {
auto thumbnail = ImagePtr();
auto sticker = (DocumentData*)nullptr;
auto pixw = 0, pixh = 0;
fillSetCover(set, &thumbnail, &sticker, &pixw, &pixh);
if (sticker) {
if ((row->thumbnail.get() != thumbnail.get())
|| (!thumbnail && row->sticker != sticker)) {
row->lottie = nullptr;
}
row->thumbnail = thumbnail;
row->sticker = sticker;
row->pixw = pixw;
row->pixh = pixh;
}
}
if (!row->isRecentSet()) {
auto wasInstalled = row->installed;
auto wasArchived = row->archived;
fillSetFlags(set, &row->installed, &row->official, &row->unread, &row->archived);
if (_section == Section::Installed) {
row->archived = false;
}
if (row->installed != wasInstalled || row->archived != wasArchived) {
row->ripple.reset();
}
}
row->title = fillSetTitle(set, maxNameWidth, &row->titleWidth);
row->count = fillSetCount(set);
}
update();
}