mirror of https://github.com/procxx/kepka.git
				
				
				
			Support generic dice media display.
This commit is contained in:
		
							parent
							
								
									fb8a9a930c
								
							
						
					
					
						commit
						e118972d5c
					
				|  | @ -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() { | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| /*
 | ||||
| /*
 | ||||
| This file is part of Telegram Desktop, | ||||
| the official desktop application for the Telegram messaging service. | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue