122 lines
2.9 KiB
C++
122 lines
2.9 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#include "ui/text/text_lottie_custom_emoji.h"
|
|
|
|
#include "lottie/lottie_icon.h"
|
|
#include "ui/text/text_utilities.h"
|
|
|
|
namespace Ui::Text {
|
|
|
|
LottieCustomEmoji::LottieCustomEmoji(Lottie::IconDescriptor &&descriptor)
|
|
: LottieCustomEmoji(std::move(descriptor), nullptr) {
|
|
}
|
|
|
|
LottieCustomEmoji::LottieCustomEmoji(
|
|
Lottie::IconDescriptor &&descriptor,
|
|
Fn<void()> repaint)
|
|
: _entityData(!descriptor.name.isEmpty()
|
|
? descriptor.name
|
|
: !descriptor.path.isEmpty()
|
|
? descriptor.path
|
|
: (Unexpected("LottieCustomEmoji: descriptor.name or descriptor.path"),
|
|
QString()))
|
|
, _width(descriptor.sizeOverride.width())
|
|
, _icon(Lottie::MakeIcon(std::move(descriptor)))
|
|
, _repaint(std::move(repaint)) {
|
|
if (!_width && _icon && _icon->valid()) {
|
|
_width = _icon->width();
|
|
startAnimation();
|
|
}
|
|
}
|
|
|
|
int LottieCustomEmoji::width() {
|
|
return _width;
|
|
}
|
|
|
|
QString LottieCustomEmoji::entityData() {
|
|
return _entityData;
|
|
}
|
|
|
|
void LottieCustomEmoji::paint(QPainter &p, const Context &context) {
|
|
if (!_icon || !_icon->valid()) {
|
|
return;
|
|
}
|
|
|
|
const auto paused = context.paused
|
|
|| context.internal.forceFirstFrame
|
|
|| context.internal.overrideFirstWithLastFrame;
|
|
|
|
if (paused) {
|
|
const auto frame = context.internal.forceLastFrame
|
|
? _icon->framesCount() - 1
|
|
: 0;
|
|
_icon->jumpTo(frame, _repaint);
|
|
} else if (!_icon->animating()) {
|
|
startAnimation();
|
|
}
|
|
|
|
_icon->paint(
|
|
p,
|
|
context.position.x(),
|
|
context.position.y(),
|
|
context.textColor);
|
|
}
|
|
|
|
void LottieCustomEmoji::unload() {
|
|
if (_icon) {
|
|
_icon->jumpTo(0, nullptr);
|
|
}
|
|
}
|
|
|
|
bool LottieCustomEmoji::ready() {
|
|
return _icon && _icon->valid();
|
|
}
|
|
|
|
bool LottieCustomEmoji::readyInDefaultState() {
|
|
return _icon && _icon->valid() && _icon->frameIndex() == 0;
|
|
}
|
|
|
|
void LottieCustomEmoji::startAnimation() {
|
|
if (!_icon || !_icon->valid() || _icon->framesCount() <= 1) {
|
|
return;
|
|
}
|
|
|
|
_icon->animate(
|
|
_repaint,
|
|
0,
|
|
_icon->framesCount() - 1);
|
|
}
|
|
|
|
QString LottieEmojiData(Lottie::IconDescriptor descriptor) {
|
|
return !descriptor.name.isEmpty()
|
|
? descriptor.name
|
|
: !descriptor.path.isEmpty()
|
|
? descriptor.path
|
|
: QString();
|
|
}
|
|
|
|
TextWithEntities LottieEmoji(Lottie::IconDescriptor descriptor) {
|
|
return SingleCustomEmoji(LottieEmojiData(std::move(descriptor)));
|
|
}
|
|
|
|
MarkedContext LottieEmojiContext(Lottie::IconDescriptor descriptor) {
|
|
auto customEmojiFactory = [descriptor = std::move(descriptor)](
|
|
QStringView data,
|
|
const MarkedContext &context
|
|
) mutable -> std::unique_ptr<CustomEmoji> {
|
|
if (data == LottieEmojiData(descriptor)) {
|
|
return std::make_unique<LottieCustomEmoji>(
|
|
std::move(descriptor),
|
|
context.repaint);
|
|
}
|
|
return nullptr;
|
|
};
|
|
return { .customEmojiFactory = std::move(customEmojiFactory) };
|
|
}
|
|
|
|
} // namespace Ui::Text
|