From e118972d5cf110a5c78e31c99d07d98ff946c0ad Mon Sep 17 00:00:00 2001 From: John Preston <johnprestonmail@gmail.com> Date: Sun, 19 Apr 2020 16:17:53 +0400 Subject: [PATCH] Support generic dice media display. --- .../chat_helpers/stickers_dice_pack.cpp | 31 +++++++++++++++---- .../chat_helpers/stickers_dice_pack.h | 1 + .../history/view/media/history_view_dice.cpp | 27 +++++++++++----- .../history/view/media/history_view_dice.h | 6 ++-- .../view/media/history_view_sticker.cpp | 22 +++++++++---- .../history/view/media/history_view_sticker.h | 10 ++++++ 6 files changed, 75 insertions(+), 22 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp index 869fa4b40..d69b76742 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp @@ -35,11 +35,11 @@ DocumentData *DicePack::lookup(int value) { if (!_requestId) { load(); } - if (!value) { - ensureZeroGenerated(); - return _zero; - } const auto i = _map.find(value); + //if (!value) { + // ensureZeroGenerated(); + // return _zero; + //} return (i != end(_map)) ? i->second.get() : nullptr; } @@ -59,14 +59,33 @@ void DicePack::load() { } 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) { const auto document = _session->data().processDocument( 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() { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.h b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.h index aa8d2db31..92035bfdc 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.h @@ -1,4 +1,5 @@ /* +/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.cpp b/Telegram/SourceFiles/history/view/media/history_view_dice.cpp index 30fb6468a..b3fd34bfb 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_dice.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_dice.cpp @@ -44,11 +44,13 @@ Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice) : _parent(parent) , _dice(dice) , _link(_parent->data()->Has<HistoryMessageForwarded>() - ? nullptr - : MakeDiceHandler(dice->emoji())) -, _start(parent, Lookup(parent, dice->emoji(), 0)) { + ? nullptr + : MakeDiceHandler(dice->emoji())) { + if (const auto document = Lookup(parent, dice->emoji(), 0)) { + _start.emplace(parent, document); + _start->setDiceIndex(_dice->emoji(), 0); + } _showLastFrame = _parent->data()->Has<HistoryMessageForwarded>(); - _start.setDiceIndex(_dice->emoji(), 0); if (_showLastFrame) { _drawingEnd = true; } @@ -57,7 +59,9 @@ Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice) Dice::~Dice() = default; QSize Dice::size() { - return _start.size(); + return _start + ? _start->size() + : Sticker::GetAnimatedEmojiSize(&_parent->history()->session()); } ClickHandlerPtr Dice::link() { @@ -65,6 +69,13 @@ ClickHandlerPtr Dice::link() { } 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 document = Lookup(_parent, _dice->emoji(), value)) { _end.emplace(_parent, document); @@ -77,9 +88,9 @@ void Dice::draw(Painter &p, const QRect &r, bool selected) { } if (_drawingEnd) { _end->draw(p, r, selected); - } else { - _start.draw(p, r, selected); - if (_end && _end->readyToDrawLottie() && _start.atTheEnd()) { + } else if (_start) { + _start->draw(p, r, selected); + if (_end && _end->readyToDrawLottie() && _start->atTheEnd()) { _drawingEnd = true; } } diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.h b/Telegram/SourceFiles/history/view/media/history_view_dice.h index 0c614deca..2e784ed1a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_dice.h +++ b/Telegram/SourceFiles/history/view/media/history_view_dice.h @@ -29,7 +29,9 @@ public: void clearStickerLoopPlayed() override { } void unloadHeavyPart() override { - _start.unloadHeavyPart(); + if (_start) { + _start->unloadHeavyPart(); + } if (_end) { _end->unloadHeavyPart(); } @@ -42,8 +44,8 @@ private: const not_null<Element*> _parent; const not_null<Data::MediaDice*> _dice; ClickHandlerPtr _link; + std::optional<Sticker> _start; std::optional<Sticker> _end; - Sticker _start; mutable bool _showLastFrame = false; mutable bool _drawingEnd = false; diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index 037567221..56e913809 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -74,12 +74,7 @@ bool Sticker::isEmojiSticker() const { void Sticker::initSize() { _size = _document->dimensions; if (isEmojiSticker() || _diceIndex >= 0) { - constexpr auto kIdealStickerSize = 512; - 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())); + _size = GetAnimatedEmojiSize(&_document->session(), _size); [[maybe_unused]] bool result = readyToDrawLottie(); } else { _size = DownscaledSize( @@ -110,6 +105,21 @@ bool Sticker::readyToDrawLottie() { 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) { if (readyToDrawLottie()) { paintLottie(p, r, selected); diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.h b/Telegram/SourceFiles/history/view/media/history_view_sticker.h index 7ec89fb3e..e9e09c7c3 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.h +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.h @@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/media/history_view_media_unwrapped.h" #include "base/weak_ptr.h" +namespace Main { +class Session; +} // namespace Main + namespace Data { struct FileOrigin; } // namespace Data @@ -55,6 +59,12 @@ public: } [[nodiscard]] bool readyToDrawLottie(); + [[nodiscard]] static QSize GetAnimatedEmojiSize( + not_null<Main::Session*> session); + [[nodiscard]] static QSize GetAnimatedEmojiSize( + not_null<Main::Session*> session, + QSize documentSize); + private: [[nodiscard]] bool isEmojiSticker() const; void paintLottie(Painter &p, const QRect &r, bool selected);