From faf6352a114f6f5ab0461d4e9fd2227f2ef8da94 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 24 Apr 2023 20:59:19 +0400 Subject: [PATCH] Support colorized emoji in reactions inline dropdown. --- .../boxes/reactions_settings_box.cpp | 3 +- .../data/data_message_reactions.cpp | 4 ++- .../history_view_reactions_strip.cpp | 31 ++++++++++++++++--- .../reactions/history_view_reactions_strip.h | 3 ++ .../ui/effects/reaction_fly_animation.cpp | 6 ++-- Telegram/lib_ui | 2 +- 6 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp index e58a1de8e..baf0f157e 100644 --- a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp @@ -384,7 +384,7 @@ void AddReactionAnimatedIcon( const auto paintCallback = [=](not_null widget, QPainter &p) { const auto paintFrame = [&](not_null animation) { - const auto frame = animation->frame(); + const auto frame = animation->frame(st::windowFg->c); p.drawImage( QRect( (widget->width() - iconSize) / 2, @@ -404,7 +404,6 @@ void AddReactionAnimatedIcon( } else if (const auto select = state->select.icon.get()) { paintFrame(select); } - }; const auto widget = AddReactionIconWrap( parent, diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index d13d7a9bf..a0834888d 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -399,7 +399,8 @@ QImage Reactions::resolveImageFor( const auto frameSize = set.fromSelectAnimation ? (size / 2) : size; - image = set.icon->frame().scaled( + // Must not be colored to text. + image = set.icon->frame(QColor()).scaled( frameSize * factor, frameSize * factor, Qt::IgnoreAspectRatio, @@ -480,6 +481,7 @@ void Reactions::setAnimatedIcon(ImageSet &set) { set.icon = Ui::MakeAnimatedIcon({ .generator = DocumentIconFrameGenerator(set.media), .sizeOverride = QSize(size, size), + .colorized = set.media->owner()->emojiUsesTextColor(), }); set.media = nullptr; } diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp index 865f9293c..25d7fa4dd 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.cpp @@ -37,6 +37,7 @@ constexpr auto kHoverScale = 1.24; return std::make_shared(Ui::AnimatedIconDescriptor{ .generator = DocumentIconFrameGenerator(media), .sizeOverride = QSize(size, size), + .colorized = media->owner()->emojiUsesTextColor(), }); } @@ -51,6 +52,21 @@ Strip::Strip( , _inner(inner) , _finalSize(size) , _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( @@ -157,7 +173,11 @@ void Strip::paintOne( } else { const auto paintFrame = [&](not_null animation) { 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); }; @@ -218,9 +238,9 @@ int Strip::fillChosenIconGetIndex(ChosenReaction &chosen) const { } const auto &icon = *i; 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()) { - chosen.icon = select->frame(); + chosen.icon = select->frame(st::windowFg->c); } return (i - begin(_icons)); } @@ -475,7 +495,7 @@ void Strip::setMainReactionIcon() { if (i != end(_loadCache) && i->second.icon) { const auto &icon = i->second.icon; if (!icon->frameIndex() && icon->width() == MainReactionSize()) { - _mainReactionImage = i->second.icon->frame(); + _mainReactionImage = i->second.icon->frame(st::windowFg->c); return; } } @@ -522,7 +542,8 @@ Ui::ImageSubrect Strip::validateEmoji(int frameIndex, float64 scale) { p.fillRect(QRect(position, result.rect.size() / ratio), Qt::transparent); if (_mainReactionImage.isNull() && _mainReactionIcon) { - _mainReactionImage = base::take(_mainReactionIcon)->frame(); + _mainReactionImage = base::take(_mainReactionIcon)->frame( + st::windowFg->c); } if (!_mainReactionImage.isNull()) { const auto target = QRect( diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h index 56726ae88..9447b0d77 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h @@ -117,6 +117,7 @@ private: [[nodiscard]] Fn resolveCountTargetMethod( float64 scale) const; + void invalidateMainReactionImage(); void resolveMainReactionIcon(); void setMainReactionIcon(); @@ -141,6 +142,8 @@ private: QImage _emojiParts; std::array _validEmoji = { { false } }; + rpl::lifetime _lifetime; + }; class CachedIconFactory final { diff --git a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp index 5d8c6b0a6..44c7686c6 100644 --- a/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/reaction_fly_animation.cpp @@ -106,6 +106,7 @@ ReactionFlyAnimation::ReactionFlyAnimation( icon = MakeAnimatedIcon({ .generator = DocumentIconFrameGenerator(media), .sizeOverride = QSize(size, size), + .colorized = media->owner()->emojiUsesTextColor(), }); return true; }; @@ -146,7 +147,8 @@ QRect ReactionFlyAnimation::paintGetArea( if (clip.isEmpty() || area.intersects(clip)) { paintCenterFrame(p, target, colored, now); 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); } @@ -199,7 +201,7 @@ void ReactionFlyAnimation::paintCenterFrame( target.y() + (target.height() - size.height()) / 2, size.width(), size.height()); - p.drawImage(rect, _center->frame()); + p.drawImage(rect, _center->frame(st::windowFg->c)); } else { const auto scaled = (size.width() != _customSize); _custom->paint(p, { diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 56945859e..efb7dc927 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 56945859e3e7166ec26abf62b0bca0209ad5b498 +Subproject commit efb7dc927a259bbf2ee35ab7e2d302a1c7c2e803