Use correct sizes for lottie frames.

This commit is contained in:
John Preston 2022-01-10 12:43:26 +03:00
parent 58f4884deb
commit a377364621
7 changed files with 58 additions and 23 deletions

View file

@ -47,7 +47,7 @@ void AddReactionIcon(
button->sizeValue( button->sizeValue(
) | rpl::start_with_next([=](QSize size) { ) | rpl::start_with_next([=](QSize size) {
icon->moveToLeft( icon->moveToLeft(
st::settingsSectionIconLeft, st::editPeerReactionsIconLeft,
(size.height() - icon->height()) / 2, (size.height() - icon->height()) / 2,
size.width()); size.width());
}, icon->lifetime()); }, icon->lifetime());
@ -153,7 +153,9 @@ void EditAllowedReactionsBox(
container, container,
rpl::single(entry.title), rpl::single(entry.title),
st::manageGroupButton.button); st::manageGroupButton.button);
AddReactionIcon(button, entry.centerIcon); AddReactionIcon(button, entry.centerIcon
? entry.centerIcon
: entry.appearAnimation.get());
state->toggles.emplace(entry.emoji, button); state->toggles.emplace(entry.emoji, button);
button->toggleOn(rpl::single( button->toggleOn(rpl::single(
active(entry) active(entry)

View file

@ -85,11 +85,13 @@ void Reactions::preloadImageFor(const QString &emoji) {
} }
auto &set = _images.emplace(emoji).first->second; auto &set = _images.emplace(emoji).first->second;
const auto i = ranges::find(_available, emoji, &Reaction::emoji); const auto i = ranges::find(_available, emoji, &Reaction::emoji);
const auto document = (i != end(_available)) const auto document = (i == end(_available))
? i->centerIcon.get() ? nullptr
: nullptr; : i->centerIcon
? i->centerIcon
: i->appearAnimation.get();
if (document) { if (document) {
loadImage(set, document); loadImage(set, document, !i->centerIcon);
} else if (!_waitingForList) { } else if (!_waitingForList) {
_waitingForList = true; _waitingForList = true;
refresh(); refresh();
@ -106,16 +108,35 @@ QImage Reactions::resolveImageFor(
auto &set = (i != end(_images)) ? i->second : _images[emoji]; auto &set = (i != end(_images)) ? i->second : _images[emoji];
const auto resolve = [&](QImage &image, int size) { const auto resolve = [&](QImage &image, int size) {
const auto factor = style::DevicePixelRatio(); const auto factor = style::DevicePixelRatio();
const auto frameSize = set.fromAppearAnimation
? (size / 2)
: size;
image = set.icon->frame().scaled( image = set.icon->frame().scaled(
size * factor, frameSize * factor,
size * factor, frameSize * factor,
Qt::IgnoreAspectRatio, Qt::IgnoreAspectRatio,
Qt::SmoothTransformation); Qt::SmoothTransformation);
if (set.fromAppearAnimation) {
auto result = QImage(
size * factor,
size * factor,
QImage::Format_ARGB32_Premultiplied);
result.fill(Qt::transparent);
auto p = QPainter(&result);
p.drawImage(
(size - frameSize) * factor / 2,
(size - frameSize) * factor / 2,
image);
p.end();
std::swap(result, image);
}
image.setDevicePixelRatio(factor); image.setDevicePixelRatio(factor);
}; };
if (set.bottomInfo.isNull() && set.icon) { if (set.bottomInfo.isNull() && set.icon) {
resolve(set.bottomInfo, st::reactionInfoSize); resolve(set.bottomInfo, st::reactionInfoImage);
resolve(set.inlineList, st::reactionBottomSize); resolve(set.inlineList, st::reactionBottomImage);
crl::async([icon = std::move(set.icon)]{}); crl::async([icon = std::move(set.icon)]{});
} }
switch (size) { switch (size) {
@ -131,11 +152,13 @@ void Reactions::resolveImages() {
continue; continue;
} }
const auto i = ranges::find(_available, emoji, &Reaction::emoji); const auto i = ranges::find(_available, emoji, &Reaction::emoji);
const auto document = (i != end(_available)) const auto document = (i == end(_available))
? i->centerIcon.get() ? nullptr
: nullptr; : i->centerIcon
? i->centerIcon
: i->appearAnimation.get();
if (document) { if (document) {
loadImage(set, document); loadImage(set, document, !i->centerIcon);
} else { } else {
LOG(("API Error: Reaction for emoji '%1' not found!" LOG(("API Error: Reaction for emoji '%1' not found!"
).arg(emoji)); ).arg(emoji));
@ -145,10 +168,12 @@ void Reactions::resolveImages() {
void Reactions::loadImage( void Reactions::loadImage(
ImageSet &set, ImageSet &set,
not_null<DocumentData*> document) { not_null<DocumentData*> document,
bool fromAppearAnimation) {
if (!set.bottomInfo.isNull() || set.icon) { if (!set.bottomInfo.isNull() || set.icon) {
return; return;
} else if (!set.media) { } else if (!set.media) {
set.fromAppearAnimation = fromAppearAnimation;
set.media = document->createMediaView(); set.media = document->createMediaView();
set.media->checkStickerLarge(); set.media->checkStickerLarge();
} }
@ -285,8 +310,8 @@ std::optional<Reaction> Reactions::parse(const MTPAvailableReaction &entry) {
.activateEffects = _owner->processDocument( .activateEffects = _owner->processDocument(
data.veffect_animation()), data.veffect_animation()),
.centerIcon = (data.vcenter_icon() .centerIcon = (data.vcenter_icon()
? _owner->processDocument(*data.vcenter_icon()) ? _owner->processDocument(*data.vcenter_icon()).get()
: selectAnimation), : nullptr),
.aroundAnimation = (data.varound_animation() .aroundAnimation = (data.varound_animation()
? _owner->processDocument( ? _owner->processDocument(
*data.varound_animation()).get() *data.varound_animation()).get()

View file

@ -26,7 +26,7 @@ struct Reaction {
not_null<DocumentData*> selectAnimation; not_null<DocumentData*> selectAnimation;
not_null<DocumentData*> activateAnimation; not_null<DocumentData*> activateAnimation;
not_null<DocumentData*> activateEffects; not_null<DocumentData*> activateEffects;
not_null<DocumentData*> centerIcon; DocumentData *centerIcon = nullptr;
DocumentData *aroundAnimation = nullptr; DocumentData *aroundAnimation = nullptr;
bool active = false; bool active = false;
}; };
@ -78,6 +78,7 @@ private:
QImage inlineList; QImage inlineList;
std::shared_ptr<DocumentMedia> media; std::shared_ptr<DocumentMedia> media;
std::unique_ptr<Lottie::Icon> icon; std::unique_ptr<Lottie::Icon> icon;
bool fromAppearAnimation = false;
}; };
void request(); void request();
@ -85,7 +86,10 @@ private:
[[nodiscard]] std::optional<Reaction> parse( [[nodiscard]] std::optional<Reaction> parse(
const MTPAvailableReaction &entry); const MTPAvailableReaction &entry);
void loadImage(ImageSet &set, not_null<DocumentData*> document); void loadImage(
ImageSet &set,
not_null<DocumentData*> document,
bool fromAppearAnimation);
void setLottie(ImageSet &set); void setLottie(ImageSet &set);
void resolveImages(); void resolveImages();
void downloadTaskFinished(); void downloadTaskFinished();

View file

@ -253,8 +253,8 @@ void BottomInfo::paintReactions(
} }
if (!reaction.image.isNull()) { if (!reaction.image.isNull()) {
p.drawImage( p.drawImage(
x, x + (st::reactionInfoSize - st::reactionInfoImage) / 2,
y + (st::msgDateFont->height - st::reactionInfoSize) / 2, y + (st::msgDateFont->height - st::reactionInfoImage) / 2,
reaction.image); reaction.image);
} }
if (reaction.countTextWidth > 0) { if (reaction.countTextWidth > 0) {

View file

@ -185,6 +185,7 @@ void InlineList::paint(
const auto stm = context.messageStyle(); const auto stm = context.messageStyle();
const auto padding = st::reactionBottomPadding; const auto padding = st::reactionBottomPadding;
const auto size = st::reactionBottomSize; const auto size = st::reactionBottomSize;
const auto skip = (size - st::reactionBottomImage) / 2;
const auto inbubble = (_data.flags & InlineListData::Flag::InBubble); const auto inbubble = (_data.flags & InlineListData::Flag::InBubble);
p.setFont(st::semiboldFont); p.setFont(st::semiboldFont);
for (const auto &button : _buttons) { for (const auto &button : _buttons) {
@ -216,7 +217,7 @@ void InlineList::paint(
::Data::Reactions::ImageSize::InlineList); ::Data::Reactions::ImageSize::InlineList);
} }
if (!button.image.isNull()) { if (!button.image.isNull()) {
p.drawImage(inner.topLeft(), button.image); p.drawImage(inner.topLeft() + QPoint(skip, skip), button.image);
} }
p.setPen(!inbubble p.setPen(!inbubble
? (chosen ? (chosen

View file

@ -711,7 +711,8 @@ editPeerInviteLinkBoxBottomSkip: 15px;
editPeerReactionsButton: SettingsButton(infoProfileButton) { editPeerReactionsButton: SettingsButton(infoProfileButton) {
padding: margins(59px, 13px, 8px, 11px); padding: margins(59px, 13px, 8px, 11px);
} }
editPeerReactionsPreview: 28px; editPeerReactionsPreview: 48px;
editPeerReactionsIconLeft: 12px;
historyTopBarBack: IconButton(infoTopBarBack) { historyTopBarBack: IconButton(infoTopBarBack) {
width: 52px; width: 52px;

View file

@ -965,11 +965,13 @@ sendAsButton: SendAsButton {
reactionBottomPadding: margins(5px, 2px, 7px, 2px); reactionBottomPadding: margins(5px, 2px, 7px, 2px);
reactionBottomSize: 16px; reactionBottomSize: 16px;
reactionBottomImage: 28px;
reactionBottomSkip: 3px; reactionBottomSkip: 3px;
reactionBottomBetween: 4px; reactionBottomBetween: 4px;
reactionBottomInBubbleLeft: -3px; reactionBottomInBubbleLeft: -3px;
reactionInfoSize: 15px; reactionInfoSize: 15px;
reactionInfoImage: 30px;
reactionInfoSkip: 3px; reactionInfoSkip: 3px;
reactionInfoDigitSkip: 6px; reactionInfoDigitSkip: 6px;
reactionInfoBetween: 3px; reactionInfoBetween: 3px;