Support generic dice media display.

This commit is contained in:
John Preston 2020-04-19 16:17:53 +04:00
parent fb8a9a930c
commit e118972d5c
6 changed files with 75 additions and 22 deletions

View File

@ -35,11 +35,11 @@ DocumentData *DicePack::lookup(int value) {
if (!_requestId) { if (!_requestId) {
load(); load();
} }
if (!value) {
ensureZeroGenerated();
return _zero;
}
const auto i = _map.find(value); const auto i = _map.find(value);
//if (!value) {
// ensureZeroGenerated();
// return _zero;
//}
return (i != end(_map)) ? i->second.get() : nullptr; return (i != end(_map)) ? i->second.get() : nullptr;
} }
@ -59,14 +59,33 @@ void DicePack::load() {
} }
void DicePack::applySet(const MTPDmessages_stickerSet &data) { void DicePack::applySet(const MTPDmessages_stickerSet &data) {
auto index = 0; _map.clear();
auto documents = base::flat_map<DocumentId, not_null<DocumentData*>>();
for (const auto &sticker : data.vdocuments().v) { for (const auto &sticker : data.vdocuments().v) {
const auto document = _session->data().processDocument( const auto document = _session->data().processDocument(
sticker); sticker);
if (document->sticker()) { if (document->sticker()) {
_map.emplace(++index, document); documents.emplace(document->id, document);
} }
} }
for (const auto pack : data.vpacks().v) {
pack.match([&](const MTPDstickerPack &data) {
const auto emoji = qs(data.vemoticon());
if (emoji.isEmpty()) {
return;
}
const auto ch = int(emoji[0].unicode());
const auto index = (ch == '#') ? 0 : (ch + 1 - '1');
if (index < 0 || index > 6) {
return;
}
for (const auto id : data.vdocuments().v) {
if (const auto document = documents.take(id.v)) {
_map.emplace(index, *document);
}
}
});
}
} }
void DicePack::ensureZeroGenerated() { void DicePack::ensureZeroGenerated() {

View File

@ -1,4 +1,5 @@
/* /*
/*
This file is part of Telegram Desktop, This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service. the official desktop application for the Telegram messaging service.

View File

@ -44,11 +44,13 @@ Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice)
: _parent(parent) : _parent(parent)
, _dice(dice) , _dice(dice)
, _link(_parent->data()->Has<HistoryMessageForwarded>() , _link(_parent->data()->Has<HistoryMessageForwarded>()
? nullptr ? nullptr
: MakeDiceHandler(dice->emoji())) : MakeDiceHandler(dice->emoji())) {
, _start(parent, Lookup(parent, dice->emoji(), 0)) { if (const auto document = Lookup(parent, dice->emoji(), 0)) {
_start.emplace(parent, document);
_start->setDiceIndex(_dice->emoji(), 0);
}
_showLastFrame = _parent->data()->Has<HistoryMessageForwarded>(); _showLastFrame = _parent->data()->Has<HistoryMessageForwarded>();
_start.setDiceIndex(_dice->emoji(), 0);
if (_showLastFrame) { if (_showLastFrame) {
_drawingEnd = true; _drawingEnd = true;
} }
@ -57,7 +59,9 @@ Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice)
Dice::~Dice() = default; Dice::~Dice() = default;
QSize Dice::size() { QSize Dice::size() {
return _start.size(); return _start
? _start->size()
: Sticker::GetAnimatedEmojiSize(&_parent->history()->session());
} }
ClickHandlerPtr Dice::link() { ClickHandlerPtr Dice::link() {
@ -65,6 +69,13 @@ ClickHandlerPtr Dice::link() {
} }
void Dice::draw(Painter &p, const QRect &r, bool selected) { void Dice::draw(Painter &p, const QRect &r, bool selected) {
if (!_start) {
if (const auto document = Lookup(_parent, _dice->emoji(), 0)) {
_start.emplace(_parent, document);
_start->setDiceIndex(_dice->emoji(), 0);
_start->initSize();
}
}
if (const auto value = _end ? 0 : _dice->value()) { if (const auto value = _end ? 0 : _dice->value()) {
if (const auto document = Lookup(_parent, _dice->emoji(), value)) { if (const auto document = Lookup(_parent, _dice->emoji(), value)) {
_end.emplace(_parent, document); _end.emplace(_parent, document);
@ -77,9 +88,9 @@ void Dice::draw(Painter &p, const QRect &r, bool selected) {
} }
if (_drawingEnd) { if (_drawingEnd) {
_end->draw(p, r, selected); _end->draw(p, r, selected);
} else { } else if (_start) {
_start.draw(p, r, selected); _start->draw(p, r, selected);
if (_end && _end->readyToDrawLottie() && _start.atTheEnd()) { if (_end && _end->readyToDrawLottie() && _start->atTheEnd()) {
_drawingEnd = true; _drawingEnd = true;
} }
} }

View File

@ -29,7 +29,9 @@ public:
void clearStickerLoopPlayed() override { void clearStickerLoopPlayed() override {
} }
void unloadHeavyPart() override { void unloadHeavyPart() override {
_start.unloadHeavyPart(); if (_start) {
_start->unloadHeavyPart();
}
if (_end) { if (_end) {
_end->unloadHeavyPart(); _end->unloadHeavyPart();
} }
@ -42,8 +44,8 @@ private:
const not_null<Element*> _parent; const not_null<Element*> _parent;
const not_null<Data::MediaDice*> _dice; const not_null<Data::MediaDice*> _dice;
ClickHandlerPtr _link; ClickHandlerPtr _link;
std::optional<Sticker> _start;
std::optional<Sticker> _end; std::optional<Sticker> _end;
Sticker _start;
mutable bool _showLastFrame = false; mutable bool _showLastFrame = false;
mutable bool _drawingEnd = false; mutable bool _drawingEnd = false;

View File

@ -74,12 +74,7 @@ bool Sticker::isEmojiSticker() const {
void Sticker::initSize() { void Sticker::initSize() {
_size = _document->dimensions; _size = _document->dimensions;
if (isEmojiSticker() || _diceIndex >= 0) { if (isEmojiSticker() || _diceIndex >= 0) {
constexpr auto kIdealStickerSize = 512; _size = GetAnimatedEmojiSize(&_document->session(), _size);
const auto zoom = GetEmojiStickerZoom(&_document->session());
const auto convert = [&](int size) {
return int(size * st::maxStickerSize * zoom / kIdealStickerSize);
};
_size = QSize(convert(_size.width()), convert(_size.height()));
[[maybe_unused]] bool result = readyToDrawLottie(); [[maybe_unused]] bool result = readyToDrawLottie();
} else { } else {
_size = DownscaledSize( _size = DownscaledSize(
@ -110,6 +105,21 @@ bool Sticker::readyToDrawLottie() {
return (_lottie && _lottie->ready()); return (_lottie && _lottie->ready());
} }
QSize Sticker::GetAnimatedEmojiSize(not_null<Main::Session*> session) {
return GetAnimatedEmojiSize(session, { 512, 512 });
}
QSize Sticker::GetAnimatedEmojiSize(
not_null<Main::Session*> session,
QSize documentSize) {
constexpr auto kIdealStickerSize = 512;
const auto zoom = GetEmojiStickerZoom(session);
const auto convert = [&](int size) {
return int(size * st::maxStickerSize * zoom / kIdealStickerSize);
};
return { convert(documentSize.width()), convert(documentSize.height()) };
}
void Sticker::draw(Painter &p, const QRect &r, bool selected) { void Sticker::draw(Painter &p, const QRect &r, bool selected) {
if (readyToDrawLottie()) { if (readyToDrawLottie()) {
paintLottie(p, r, selected); paintLottie(p, r, selected);

View File

@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media_unwrapped.h" #include "history/view/media/history_view_media_unwrapped.h"
#include "base/weak_ptr.h" #include "base/weak_ptr.h"
namespace Main {
class Session;
} // namespace Main
namespace Data { namespace Data {
struct FileOrigin; struct FileOrigin;
} // namespace Data } // namespace Data
@ -55,6 +59,12 @@ public:
} }
[[nodiscard]] bool readyToDrawLottie(); [[nodiscard]] bool readyToDrawLottie();
[[nodiscard]] static QSize GetAnimatedEmojiSize(
not_null<Main::Session*> session);
[[nodiscard]] static QSize GetAnimatedEmojiSize(
not_null<Main::Session*> session,
QSize documentSize);
private: private:
[[nodiscard]] bool isEmojiSticker() const; [[nodiscard]] bool isEmojiSticker() const;
void paintLottie(Painter &p, const QRect &r, bool selected); void paintLottie(Painter &p, const QRect &r, bool selected);