Support colorized emoji in reactions inline dropdown.

This commit is contained in:
John Preston 2023-04-24 20:59:19 +04:00
parent 4cfa486d91
commit faf6352a11
6 changed files with 38 additions and 11 deletions

View file

@ -384,7 +384,7 @@ void AddReactionAnimatedIcon(
const auto paintCallback = [=](not_null<QWidget*> widget, QPainter &p) { const auto paintCallback = [=](not_null<QWidget*> widget, QPainter &p) {
const auto paintFrame = [&](not_null<Ui::AnimatedIcon*> animation) { const auto paintFrame = [&](not_null<Ui::AnimatedIcon*> animation) {
const auto frame = animation->frame(); const auto frame = animation->frame(st::windowFg->c);
p.drawImage( p.drawImage(
QRect( QRect(
(widget->width() - iconSize) / 2, (widget->width() - iconSize) / 2,
@ -404,7 +404,6 @@ void AddReactionAnimatedIcon(
} else if (const auto select = state->select.icon.get()) { } else if (const auto select = state->select.icon.get()) {
paintFrame(select); paintFrame(select);
} }
}; };
const auto widget = AddReactionIconWrap( const auto widget = AddReactionIconWrap(
parent, parent,

View file

@ -399,7 +399,8 @@ QImage Reactions::resolveImageFor(
const auto frameSize = set.fromSelectAnimation const auto frameSize = set.fromSelectAnimation
? (size / 2) ? (size / 2)
: size; : size;
image = set.icon->frame().scaled( // Must not be colored to text.
image = set.icon->frame(QColor()).scaled(
frameSize * factor, frameSize * factor,
frameSize * factor, frameSize * factor,
Qt::IgnoreAspectRatio, Qt::IgnoreAspectRatio,
@ -480,6 +481,7 @@ void Reactions::setAnimatedIcon(ImageSet &set) {
set.icon = Ui::MakeAnimatedIcon({ set.icon = Ui::MakeAnimatedIcon({
.generator = DocumentIconFrameGenerator(set.media), .generator = DocumentIconFrameGenerator(set.media),
.sizeOverride = QSize(size, size), .sizeOverride = QSize(size, size),
.colorized = set.media->owner()->emojiUsesTextColor(),
}); });
set.media = nullptr; set.media = nullptr;
} }

View file

@ -37,6 +37,7 @@ constexpr auto kHoverScale = 1.24;
return std::make_shared<Ui::AnimatedIcon>(Ui::AnimatedIconDescriptor{ return std::make_shared<Ui::AnimatedIcon>(Ui::AnimatedIconDescriptor{
.generator = DocumentIconFrameGenerator(media), .generator = DocumentIconFrameGenerator(media),
.sizeOverride = QSize(size, size), .sizeOverride = QSize(size, size),
.colorized = media->owner()->emojiUsesTextColor(),
}); });
} }
@ -51,6 +52,21 @@ Strip::Strip(
, _inner(inner) , _inner(inner)
, _finalSize(size) , _finalSize(size)
, _update(std::move(update)) { , _update(std::move(update)) {
style::PaletteChanged(
) | rpl::start_with_next([=] {
invalidateMainReactionImage();
}, _lifetime);
}
void Strip::invalidateMainReactionImage() {
if (_mainReactionImage.isNull()
&& !ranges::contains(_validEmoji, true)) {
return;
}
const auto was = base::take(_mainReactionMedia);
_mainReactionImage = QImage();
ranges::fill(_validEmoji, false);
resolveMainReactionIcon();
} }
void Strip::applyList( void Strip::applyList(
@ -157,7 +173,11 @@ void Strip::paintOne(
} else { } else {
const auto paintFrame = [&](not_null<Ui::AnimatedIcon*> animation) { const auto paintFrame = [&](not_null<Ui::AnimatedIcon*> animation) {
const auto size = int(std::floor(target.width() + 0.01)); const auto size = int(std::floor(target.width() + 0.01));
const auto frame = animation->frame({ size, size }, _update); const auto &textColor = st::windowFg->c;
const auto frame = animation->frame(
textColor,
{ size, size },
_update);
p.drawImage(target, frame.image); p.drawImage(target, frame.image);
}; };
@ -218,9 +238,9 @@ int Strip::fillChosenIconGetIndex(ChosenReaction &chosen) const {
} }
const auto &icon = *i; const auto &icon = *i;
if (const auto &appear = icon.appear; appear && appear->animating()) { if (const auto &appear = icon.appear; appear && appear->animating()) {
chosen.icon = appear->frame(); chosen.icon = appear->frame(st::windowFg->c);
} else if (const auto &select = icon.select; select && select->valid()) { } else if (const auto &select = icon.select; select && select->valid()) {
chosen.icon = select->frame(); chosen.icon = select->frame(st::windowFg->c);
} }
return (i - begin(_icons)); return (i - begin(_icons));
} }
@ -475,7 +495,7 @@ void Strip::setMainReactionIcon() {
if (i != end(_loadCache) && i->second.icon) { if (i != end(_loadCache) && i->second.icon) {
const auto &icon = i->second.icon; const auto &icon = i->second.icon;
if (!icon->frameIndex() && icon->width() == MainReactionSize()) { if (!icon->frameIndex() && icon->width() == MainReactionSize()) {
_mainReactionImage = i->second.icon->frame(); _mainReactionImage = i->second.icon->frame(st::windowFg->c);
return; return;
} }
} }
@ -522,7 +542,8 @@ Ui::ImageSubrect Strip::validateEmoji(int frameIndex, float64 scale) {
p.fillRect(QRect(position, result.rect.size() / ratio), Qt::transparent); p.fillRect(QRect(position, result.rect.size() / ratio), Qt::transparent);
if (_mainReactionImage.isNull() if (_mainReactionImage.isNull()
&& _mainReactionIcon) { && _mainReactionIcon) {
_mainReactionImage = base::take(_mainReactionIcon)->frame(); _mainReactionImage = base::take(_mainReactionIcon)->frame(
st::windowFg->c);
} }
if (!_mainReactionImage.isNull()) { if (!_mainReactionImage.isNull()) {
const auto target = QRect( const auto target = QRect(

View file

@ -117,6 +117,7 @@ private:
[[nodiscard]] Fn<QRectF(const ReactionIcons&)> resolveCountTargetMethod( [[nodiscard]] Fn<QRectF(const ReactionIcons&)> resolveCountTargetMethod(
float64 scale) const; float64 scale) const;
void invalidateMainReactionImage();
void resolveMainReactionIcon(); void resolveMainReactionIcon();
void setMainReactionIcon(); void setMainReactionIcon();
@ -141,6 +142,8 @@ private:
QImage _emojiParts; QImage _emojiParts;
std::array<bool, kFramesCount> _validEmoji = { { false } }; std::array<bool, kFramesCount> _validEmoji = { { false } };
rpl::lifetime _lifetime;
}; };
class CachedIconFactory final { class CachedIconFactory final {

View file

@ -106,6 +106,7 @@ ReactionFlyAnimation::ReactionFlyAnimation(
icon = MakeAnimatedIcon({ icon = MakeAnimatedIcon({
.generator = DocumentIconFrameGenerator(media), .generator = DocumentIconFrameGenerator(media),
.sizeOverride = QSize(size, size), .sizeOverride = QSize(size, size),
.colorized = media->owner()->emojiUsesTextColor(),
}); });
return true; return true;
}; };
@ -146,7 +147,8 @@ QRect ReactionFlyAnimation::paintGetArea(
if (clip.isEmpty() || area.intersects(clip)) { if (clip.isEmpty() || area.intersects(clip)) {
paintCenterFrame(p, target, colored, now); paintCenterFrame(p, target, colored, now);
if (const auto effect = _effect.get()) { if (const auto effect = _effect.get()) {
p.drawImage(wide, effect->frame()); // Must not be colored to text.
p.drawImage(wide, effect->frame(QColor()));
} }
paintMiniCopies(p, target.center(), colored, now); paintMiniCopies(p, target.center(), colored, now);
} }
@ -199,7 +201,7 @@ void ReactionFlyAnimation::paintCenterFrame(
target.y() + (target.height() - size.height()) / 2, target.y() + (target.height() - size.height()) / 2,
size.width(), size.width(),
size.height()); size.height());
p.drawImage(rect, _center->frame()); p.drawImage(rect, _center->frame(st::windowFg->c));
} else { } else {
const auto scaled = (size.width() != _customSize); const auto scaled = (size.width() != _customSize);
_custom->paint(p, { _custom->paint(p, {

@ -1 +1 @@
Subproject commit 56945859e3e7166ec26abf62b0bca0209ad5b498 Subproject commit efb7dc927a259bbf2ee35ab7e2d302a1c7c2e803