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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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