mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Colorize emoji in text color correctly.
This commit is contained in:
parent
1ab8830ba8
commit
833a259234
35 changed files with 176 additions and 147 deletions
|
@ -735,7 +735,6 @@ int PeerListRow::paintNameIconGetWidth(
|
|||
.premiumFg = &(selected
|
||||
? st::dialogsVerifiedIconBgOver
|
||||
: st::dialogsVerifiedIconBg),
|
||||
.preview = st::windowBgOver->c,
|
||||
.customEmojiRepaint = repaint,
|
||||
.now = now,
|
||||
.paused = false,
|
||||
|
|
|
@ -177,7 +177,7 @@ bool DefaultIconEmoji::readyInDefaultState() {
|
|||
return !paintIconFrame(result);
|
||||
}) | rpl::start_with_next([=](QRect clip) {
|
||||
auto args = Ui::Text::CustomEmoji::Context{
|
||||
.preview = st::windowBgOver->c,
|
||||
.textColor = st::windowFg->c,
|
||||
.now = crl::now(),
|
||||
.paused = controller->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::Layer),
|
||||
|
|
|
@ -447,7 +447,7 @@ void AddReactionCustomIcon(
|
|||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto size = Data::FrameSizeFromTag(tag) / ratio;
|
||||
state->custom->paint(p, {
|
||||
.preview = st::windowBgRipple->c,
|
||||
.textColor = st::windowFg->c,
|
||||
.now = crl::now(),
|
||||
.position = QPoint(
|
||||
(widget->width() - size) / 2,
|
||||
|
|
|
@ -331,7 +331,6 @@ private:
|
|||
std::vector<Element> _elements;
|
||||
std::unique_ptr<Lottie::MultiPlayer> _lottiePlayer;
|
||||
|
||||
mutable Ui::Text::CustomEmojiColored _colored;
|
||||
base::flat_map<
|
||||
not_null<DocumentData*>,
|
||||
std::unique_ptr<Ui::Text::CustomEmoji>> _customEmoji;
|
||||
|
@ -1335,10 +1334,8 @@ void StickerSetBox::Inner::paintSticker(
|
|||
(_singleSize.height() - size.height()) / 2);
|
||||
auto lottieFrame = QImage();
|
||||
if (element.emoji) {
|
||||
_colored.color = st::profileVerifiedCheckBg->c;
|
||||
element.emoji->paint(p, {
|
||||
.preview = st::windowBgOver->c,
|
||||
.colored = &_colored,
|
||||
.textColor = st::windowFg->c,
|
||||
.now = now,
|
||||
.position = ppos,
|
||||
.paused = paused,
|
||||
|
|
|
@ -438,9 +438,6 @@ EmojiListWidget::EmojiListWidget(
|
|||
resizeToWidth(width());
|
||||
}, lifetime());
|
||||
|
||||
if (_mode == Mode::EmojiStatus) {
|
||||
_emojiStatusColor = std::make_unique<Ui::Text::CustomEmojiColored>();
|
||||
}
|
||||
rpl::single(
|
||||
rpl::empty
|
||||
) | rpl::then(
|
||||
|
@ -449,12 +446,6 @@ EmojiListWidget::EmojiListWidget(
|
|||
initButton(_add, tr::lng_stickers_featured_add(tr::now), false);
|
||||
initButton(_unlock, tr::lng_emoji_featured_unlock(tr::now), true);
|
||||
initButton(_restore, tr::lng_emoji_premium_restore(tr::now), true);
|
||||
if (const auto status = _emojiStatusColor.get()) {
|
||||
status->color = anim::color(
|
||||
st::stickerPanPremium1,
|
||||
st::stickerPanPremium2,
|
||||
0.5);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
if (!descriptor.customRecentList.empty()) {
|
||||
|
@ -842,10 +833,36 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
|||
paint(p, {}, clip);
|
||||
}
|
||||
|
||||
void EmojiListWidget::validateEmojiPaintContext(
|
||||
const ExpandingContext &context) {
|
||||
auto value = Ui::Text::CustomEmojiPaintContext{
|
||||
.textColor = (_mode == Mode::EmojiStatus
|
||||
? anim::color(
|
||||
st::stickerPanPremium1,
|
||||
st::stickerPanPremium2,
|
||||
0.5)
|
||||
: st::windowFg->c),
|
||||
.size = QSize(_customSingleSize, _customSingleSize),
|
||||
.now = crl::now(),
|
||||
.scale = context.progress,
|
||||
.paused = paused(),
|
||||
.scaled = context.expanding,
|
||||
};
|
||||
if (!_emojiPaintContext) {
|
||||
_emojiPaintContext = std::make_unique<
|
||||
Ui::Text::CustomEmojiPaintContext
|
||||
>(std::move(value));
|
||||
} else {
|
||||
*_emojiPaintContext = std::move(value);
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiListWidget::paint(
|
||||
QPainter &p,
|
||||
ExpandingContext context,
|
||||
QRect clip) {
|
||||
validateEmojiPaintContext(context);
|
||||
|
||||
auto fromColumn = floorclamp(
|
||||
clip.x() - _rowsLeft,
|
||||
_singleSize.width(),
|
||||
|
@ -861,10 +878,7 @@ void EmojiListWidget::paint(
|
|||
fromColumn = _columnCount - fromColumn;
|
||||
toColumn = _columnCount - toColumn;
|
||||
}
|
||||
|
||||
const auto expandProgress = context.progress;
|
||||
const auto paused = this->paused();
|
||||
const auto now = crl::now();
|
||||
auto selectedButton = std::get_if<OverButton>(!v::is_null(_pressed)
|
||||
? &_pressed
|
||||
: &_selected);
|
||||
|
@ -968,12 +982,12 @@ void EmojiListWidget::paint(
|
|||
_overBg.paint(p, QRect(tl, st::emojiPanArea));
|
||||
}
|
||||
if (info.section == int(Section::Recent)) {
|
||||
drawRecent(p, context, w, now, paused, index);
|
||||
drawRecent(p, context, w, index);
|
||||
} else if (info.section < _staticCount) {
|
||||
drawEmoji(p, context, w, _emoji[info.section][index]);
|
||||
} else {
|
||||
const auto set = info.section - _staticCount;
|
||||
drawCustom(p, context, w, now, paused, set, index);
|
||||
drawCustom(p, context, w, set, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1006,24 +1020,14 @@ void EmojiListWidget::drawRecent(
|
|||
QPainter &p,
|
||||
const ExpandingContext &context,
|
||||
QPoint position,
|
||||
crl::time now,
|
||||
bool paused,
|
||||
int index) {
|
||||
_recentPainted = true;
|
||||
auto &recent = _recent[index];
|
||||
if (const auto custom = recent.custom) {
|
||||
position += _innerPosition + _customPosition;
|
||||
const auto paintContext = Ui::Text::CustomEmoji::Context{
|
||||
.preview = st::windowBgRipple->c,
|
||||
.colored = _emojiStatusColor.get(),
|
||||
.size = QSize(_customSingleSize, _customSingleSize),
|
||||
.now = now,
|
||||
.scale = context.progress,
|
||||
.position = position,
|
||||
.paused = paused,
|
||||
.scaled = context.expanding,
|
||||
};
|
||||
custom->paint(p, paintContext);
|
||||
_emojiPaintContext->position = position
|
||||
+ _innerPosition
|
||||
+ _customPosition;
|
||||
custom->paint(p, *_emojiPaintContext);
|
||||
} else if (const auto emoji = std::get_if<EmojiPtr>(&recent.id.data)) {
|
||||
if (_mode == Mode::EmojiStatus) {
|
||||
position += QPoint(
|
||||
|
@ -1057,24 +1061,16 @@ void EmojiListWidget::drawCustom(
|
|||
QPainter &p,
|
||||
const ExpandingContext &context,
|
||||
QPoint position,
|
||||
crl::time now,
|
||||
bool paused,
|
||||
int set,
|
||||
int index) {
|
||||
position += _innerPosition + _customPosition;
|
||||
auto &custom = _custom[set];
|
||||
custom.painted = true;
|
||||
auto &entry = custom.list[index];
|
||||
entry.custom->paint(p, {
|
||||
.preview = st::windowBgRipple->c,
|
||||
.colored = _emojiStatusColor.get(),
|
||||
.size = QSize(_customSingleSize, _customSingleSize),
|
||||
.now = now,
|
||||
.scale = context.progress,
|
||||
.position = position,
|
||||
.paused = paused,
|
||||
.scaled = context.expanding,
|
||||
});
|
||||
_emojiPaintContext->position = position
|
||||
+ _innerPosition
|
||||
+ _customPosition;
|
||||
entry.custom->paint(p, *_emojiPaintContext);
|
||||
}
|
||||
|
||||
bool EmojiListWidget::checkPickerHide() {
|
||||
|
|
|
@ -38,7 +38,7 @@ enum class Section;
|
|||
} // namespace Ui::Emoji
|
||||
|
||||
namespace Ui::Text {
|
||||
struct CustomEmojiColored;
|
||||
struct CustomEmojiPaintContext;
|
||||
} // namespace Ui::Text
|
||||
|
||||
namespace Ui::CustomEmoji {
|
||||
|
@ -267,8 +267,6 @@ private:
|
|||
QPainter &p,
|
||||
const ExpandingContext &context,
|
||||
QPoint position,
|
||||
crl::time now,
|
||||
bool paused,
|
||||
int index);
|
||||
void drawEmoji(
|
||||
QPainter &p,
|
||||
|
@ -279,10 +277,9 @@ private:
|
|||
QPainter &p,
|
||||
const ExpandingContext &context,
|
||||
QPoint position,
|
||||
crl::time now,
|
||||
bool paused,
|
||||
int set,
|
||||
int index);
|
||||
void validateEmojiPaintContext(const ExpandingContext &context);
|
||||
[[nodiscard]] bool hasRemoveButton(int index) const;
|
||||
[[nodiscard]] QRect removeButtonRect(int index) const;
|
||||
[[nodiscard]] QRect removeButtonRect(const SectionInfo &info) const;
|
||||
|
@ -345,7 +342,7 @@ private:
|
|||
std::vector<RecentOne> _recent;
|
||||
base::flat_set<DocumentId> _recentCustomIds;
|
||||
base::flat_set<uint64> _repaintsScheduled;
|
||||
std::unique_ptr<Ui::Text::CustomEmojiColored> _emojiStatusColor;
|
||||
std::unique_ptr<Ui::Text::CustomEmojiPaintContext> _emojiPaintContext;
|
||||
bool _recentPainted = false;
|
||||
bool _grabbingChosen = false;
|
||||
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
|
||||
|
|
|
@ -341,8 +341,10 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
|
|||
Ui::StickerHoverCorners);
|
||||
}
|
||||
|
||||
const auto now = crl::now();
|
||||
const auto preview = st::windowBgOver->c;
|
||||
auto context = Ui::CustomEmoji::Context{
|
||||
.textColor = st::windowFg->c,
|
||||
.now = crl::now(),
|
||||
};
|
||||
for (auto i = from; i != till; ++i) {
|
||||
const auto &row = _rows[i];
|
||||
const auto emoji = row.emoji;
|
||||
|
@ -351,11 +353,8 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
|
|||
const auto x = i * _oneWidth + (_oneWidth - size) / 2;
|
||||
const auto y = (_oneWidth - size) / 2;
|
||||
if (row.custom) {
|
||||
row.custom->paint(p, {
|
||||
.preview = preview,
|
||||
.now = now,
|
||||
.position = { x, y },
|
||||
});
|
||||
context.position = { x, y };
|
||||
row.custom->paint(p, context);
|
||||
} else {
|
||||
Ui::Emoji::Draw(p, emoji, esize, x, y);
|
||||
}
|
||||
|
|
|
@ -605,6 +605,7 @@ void StickersListFooter::paint(
|
|||
|
||||
const auto now = crl::now();
|
||||
const auto paused = _paused();
|
||||
p.setPen(st::windowFg);
|
||||
enumerateVisibleIcons([&](const IconInfo &info) {
|
||||
paintSetIcon(p, context, info, now, paused);
|
||||
});
|
||||
|
@ -1251,7 +1252,7 @@ void StickersListFooter::paintSetIcon(
|
|||
const auto y = _iconsTop + (st().footer - icon.pixh) / 2;
|
||||
if (icon.custom) {
|
||||
icon.custom->paint(p, Ui::Text::CustomEmoji::Context{
|
||||
.preview = st::windowBgRipple->c,
|
||||
.textColor = st::windowFg->c,
|
||||
.size = QSize(icon.pixw, icon.pixh),
|
||||
.now = now,
|
||||
.scale = context.progress,
|
||||
|
|
|
@ -327,6 +327,7 @@ void DocumentData::setattributes(
|
|||
const QVector<MTPDocumentAttribute> &attributes) {
|
||||
_flags &= ~(Flag::ImageType
|
||||
| Flag::HasAttachedStickers
|
||||
| Flag::UseTextColor
|
||||
| kStreamingSupportedMask);
|
||||
_flags |= kStreamingSupportedUnknown;
|
||||
|
||||
|
@ -375,6 +376,9 @@ void DocumentData::setattributes(
|
|||
} else {
|
||||
_flags |= Flag::PremiumSticker;
|
||||
}
|
||||
if (data.is_text_color()) {
|
||||
_flags |= Flag::UseTextColor;
|
||||
}
|
||||
UpdateStickerSetIdentifier(info->set, data.vstickerset());
|
||||
}
|
||||
}, [&](const MTPDdocumentAttributeVideo &data) {
|
||||
|
@ -555,6 +559,10 @@ bool DocumentData::isPremiumEmoji() const {
|
|||
return info && info->setType == Data::StickersType::Emoji;
|
||||
}
|
||||
|
||||
bool DocumentData::emojiUsesTextColor() const {
|
||||
return (_flags & Flag::UseTextColor);
|
||||
}
|
||||
|
||||
bool DocumentData::hasThumbnail() const {
|
||||
return _thumbnail.location.valid()
|
||||
&& !thumbnailFailed()
|
||||
|
|
|
@ -181,6 +181,7 @@ public:
|
|||
[[nodiscard]] bool isPatternWallPaperSVG() const;
|
||||
[[nodiscard]] bool isPremiumSticker() const;
|
||||
[[nodiscard]] bool isPremiumEmoji() const;
|
||||
[[nodiscard]] bool emojiUsesTextColor() const;
|
||||
|
||||
[[nodiscard]] bool hasThumbnail() const;
|
||||
[[nodiscard]] bool thumbnailLoading() const;
|
||||
|
@ -290,6 +291,7 @@ private:
|
|||
ForceToCache = 0x100,
|
||||
PremiumSticker = 0x200,
|
||||
PossibleCoverThumbnail = 0x400,
|
||||
UseTextColor = 0x800,
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend constexpr bool is_flag_type(Flag) { return true; };
|
||||
|
|
|
@ -582,7 +582,11 @@ void ForumTopic::paintUserpic(
|
|||
(st->height - size) / 2);
|
||||
}
|
||||
_icon->paint(p, {
|
||||
.preview = st::windowBgOver->c,
|
||||
.textColor = (context.active
|
||||
? st::dialogsNameFgActive
|
||||
: context.selected
|
||||
? st::dialogsNameFgOver
|
||||
: st::dialogsNameFg)->c,
|
||||
.now = context.now,
|
||||
.position = position,
|
||||
.paused = context.paused,
|
||||
|
|
|
@ -447,14 +447,16 @@ std::unique_ptr<Ui::Text::CustomEmoji> CustomEmojiManager::create(
|
|||
Ui::CustomEmoji::RepaintRequest request) {
|
||||
repaintLater(instance, request);
|
||||
};
|
||||
auto [loader, setId] = factory();
|
||||
auto [loader, setId, colored] = factory();
|
||||
i = instances.emplace(
|
||||
documentId,
|
||||
std::make_unique<Ui::CustomEmoji::Instance>(Loading{
|
||||
std::move(loader),
|
||||
prepareNonExactPreview(documentId, tag, sizeOverride)
|
||||
}, std::move(repaint))).first;
|
||||
if (_coloredSetId) {
|
||||
if (colored) {
|
||||
i->second->setColored();
|
||||
} else if (_coloredSetId) {
|
||||
if (_coloredSetId == setId) {
|
||||
i->second->setColored();
|
||||
}
|
||||
|
@ -608,6 +610,7 @@ auto CustomEmojiManager::createLoaderWithSetId(
|
|||
return {
|
||||
std::make_unique<CustomEmojiLoader>(document, tag, sizeOverride),
|
||||
sticker->set.id,
|
||||
document->emojiUsesTextColor(),
|
||||
};
|
||||
}
|
||||
return createLoaderWithSetId(document->id, tag, sizeOverride);
|
||||
|
@ -625,7 +628,11 @@ auto CustomEmojiManager::createLoaderWithSetId(
|
|||
sizeOverride);
|
||||
if (const auto document = result->document()) {
|
||||
if (const auto sticker = document->sticker()) {
|
||||
return { std::move(result), sticker->set.id };
|
||||
return {
|
||||
std::move(result),
|
||||
sticker->set.id,
|
||||
document->emojiUsesTextColor(),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const auto i = SizeIndex(tag);
|
||||
|
@ -635,7 +642,7 @@ auto CustomEmojiManager::createLoaderWithSetId(
|
|||
crl::on_main(this, [=] { request(); });
|
||||
}
|
||||
}
|
||||
return { std::move(result), uint64() };
|
||||
return { std::move(result), uint64(), false };
|
||||
}
|
||||
|
||||
QString CustomEmojiManager::lookupSetName(uint64 setId) {
|
||||
|
@ -675,17 +682,28 @@ void CustomEmojiManager::request() {
|
|||
|
||||
void CustomEmojiManager::fillColoredFlags(not_null<DocumentData*> document) {
|
||||
const auto id = document->id;
|
||||
const auto setColored = [&] {
|
||||
for (auto &instances : _instances) {
|
||||
const auto i = instances.find(id);
|
||||
if (i != end(instances)) {
|
||||
i->second->setColored();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (document->emojiUsesTextColor()) {
|
||||
setColored();
|
||||
return;
|
||||
}
|
||||
const auto sticker = document->sticker();
|
||||
const auto setId = sticker ? sticker->set.id : uint64();
|
||||
if (!setId || (_coloredSetId && setId != _coloredSetId)) {
|
||||
return;
|
||||
}
|
||||
for (auto &instances : _instances) {
|
||||
const auto i = instances.find(id);
|
||||
if (i != end(instances)) {
|
||||
if (setId == _coloredSetId) {
|
||||
i->second->setColored();
|
||||
} else {
|
||||
} else if (setId == _coloredSetId) {
|
||||
setColored();
|
||||
} else {
|
||||
for (auto &instances : _instances) {
|
||||
const auto i = instances.find(id);
|
||||
if (i != end(instances)) {
|
||||
_coloredSetPending[setId].emplace(i->second.get());
|
||||
}
|
||||
}
|
||||
|
@ -915,6 +933,7 @@ void InsertCustomEmoji(
|
|||
return;
|
||||
}
|
||||
Ui::InsertCustomEmojiAtCursor(
|
||||
field,
|
||||
field->textCursor(),
|
||||
sticker->alt,
|
||||
Ui::InputField::CustomEmojiLink(SerializeCustomEmojiId(document)));
|
||||
|
|
|
@ -90,6 +90,7 @@ private:
|
|||
struct LoaderWithSetId {
|
||||
std::unique_ptr<Ui::CustomEmoji::Loader> loader;
|
||||
uint64 setId = 0;
|
||||
bool colored = false;
|
||||
};
|
||||
|
||||
[[nodiscard]] LoaderWithSetId createLoaderWithSetId(
|
||||
|
|
|
@ -1016,11 +1016,6 @@ void InnerWidget::paintPeerSearchResult(
|
|||
: context.selected
|
||||
? &st::dialogsVerifiedIconBgOver
|
||||
: &st::dialogsVerifiedIconBg),
|
||||
.preview = (context.active
|
||||
? st::dialogsScamFgActive
|
||||
: context.selected
|
||||
? st::windowBgRipple
|
||||
: st::windowBgOver)->c,
|
||||
.customEmojiRepaint = [=] { updateSearchResult(peer); },
|
||||
.now = context.now,
|
||||
.paused = context.paused,
|
||||
|
|
|
@ -656,11 +656,6 @@ void PaintRow(
|
|||
: context.selected
|
||||
? &st::dialogsVerifiedIconBgOver
|
||||
: &st::dialogsVerifiedIconBg),
|
||||
.preview = (context.active
|
||||
? st::dialogsScamFgActive
|
||||
: context.selected
|
||||
? st::windowBgRipple
|
||||
: st::windowBgOver)->c,
|
||||
.customEmojiRepaint = customEmojiRepaint,
|
||||
.now = context.now,
|
||||
.paused = context.paused,
|
||||
|
|
|
@ -2987,12 +2987,12 @@ void HistoryItem::createComponents(const MTPDmessage &data) {
|
|||
config.replyToPeer = 0;
|
||||
}
|
||||
}
|
||||
const auto id = data.vreply_to_msg_id().v;
|
||||
config.replyTo = data.is_reply_to_scheduled()
|
||||
? _history->owner().scheduledMessages().localMessageId(id)
|
||||
: id;
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
||||
config.replyIsTopicPost = data.is_forum_topic();
|
||||
const auto id = data.vreply_to_msg_id().v;
|
||||
config.replyTo = data.is_reply_to_scheduled()
|
||||
? _history->owner().scheduledMessages().localMessageId(id)
|
||||
: id;
|
||||
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
||||
config.replyIsTopicPost = data.is_forum_topic();
|
||||
});
|
||||
}
|
||||
config.viaBotId = data.vvia_bot_id().value_or_empty();
|
||||
|
@ -3239,7 +3239,9 @@ void HistoryItem::createServiceFromMtp(const MTPDmessageService &message) {
|
|||
if (!updateServiceDependent()) {
|
||||
RequestDependentMessageData(
|
||||
this,
|
||||
dependent->peerId,
|
||||
(dependent->peerId
|
||||
? dependent->peerId
|
||||
: _history->peer->id),
|
||||
dependent->msgId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,7 +289,6 @@ struct Message::CommentsButton {
|
|||
struct Message::FromNameStatus {
|
||||
DocumentId id = 0;
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
||||
Ui::Text::CustomEmojiColored colored;
|
||||
int skip = 0;
|
||||
};
|
||||
|
||||
|
@ -1239,10 +1238,8 @@ void Message::paintFromName(
|
|||
}
|
||||
if (_fromNameStatus->custom) {
|
||||
clearCustomEmojiRepaint();
|
||||
_fromNameStatus->colored.color = color;
|
||||
_fromNameStatus->custom->paint(p, {
|
||||
.preview = color,
|
||||
.colored = &_fromNameStatus->colored,
|
||||
.textColor = color,
|
||||
.now = context.now,
|
||||
.position = QPoint(
|
||||
x - 2 * _fromNameStatus->skip,
|
||||
|
|
|
@ -311,7 +311,7 @@ void StickerToast::setupEmojiPreview(
|
|||
const auto size = Ui::Emoji::GetSizeLarge()
|
||||
/ style::DevicePixelRatio();
|
||||
instance->object.paint(p, Ui::Text::CustomEmoji::Context{
|
||||
.preview = st::toastBg->c,
|
||||
.textColor = st::toastFg->c,
|
||||
.now = crl::now(),
|
||||
.position = QPoint(
|
||||
(widget->width() - size) / 2,
|
||||
|
|
|
@ -562,7 +562,6 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
.premium = &st::dialogsPremiumIcon,
|
||||
.scam = &st::attentionButtonFg,
|
||||
.premiumFg = &st::dialogsVerifiedIconBg,
|
||||
.preview = st::windowBgOver->c,
|
||||
.customEmojiRepaint = [=] { update(); },
|
||||
.now = now,
|
||||
.paused = _controller->isGifPausedAtLeastFor(
|
||||
|
|
|
@ -262,7 +262,8 @@ void CustomEmoji::paintCustom(
|
|||
_hasHeavyPart = true;
|
||||
_parent->history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
const auto preview = context.imageStyle()->msgServiceBg->c;
|
||||
//const auto preview = context.imageStyle()->msgServiceBg->c;
|
||||
auto &textst = context.st->messageStyle(false, false);
|
||||
if (context.selected()) {
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
const auto size = QSize(_singleSize, _singleSize) * factor;
|
||||
|
@ -275,7 +276,7 @@ void CustomEmoji::paintCustom(
|
|||
_selectedFrame.fill(Qt::transparent);
|
||||
auto q = QPainter(&_selectedFrame);
|
||||
emoji->paint(q, {
|
||||
.preview = preview,
|
||||
.textColor = textst.historyTextFg->c,
|
||||
.now = context.now,
|
||||
.paused = context.paused,
|
||||
});
|
||||
|
@ -287,7 +288,7 @@ void CustomEmoji::paintCustom(
|
|||
p.drawImage(x, y, _selectedFrame);
|
||||
} else {
|
||||
emoji->paint(p, {
|
||||
.preview = preview,
|
||||
.textColor = textst.historyTextFg->c,
|
||||
.now = context.now,
|
||||
.position = { x, y },
|
||||
.paused = context.paused,
|
||||
|
|
|
@ -135,7 +135,8 @@ void LargeEmoji::paintCustom(
|
|||
const auto inner = st::largeEmojiSize + 2 * st::largeEmojiOutline;
|
||||
const auto outer = Ui::Text::AdjustCustomEmojiSize(inner);
|
||||
const auto skip = (inner - outer) / 2;
|
||||
const auto preview = context.imageStyle()->msgServiceBg->c;
|
||||
//const auto preview = context.imageStyle()->msgServiceBg->c;
|
||||
auto &textst = context.st->messageStyle(false, false);
|
||||
if (context.selected()) {
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
const auto size = QSize(outer, outer) * factor;
|
||||
|
@ -148,7 +149,7 @@ void LargeEmoji::paintCustom(
|
|||
_selectedFrame.fill(Qt::transparent);
|
||||
auto q = QPainter(&_selectedFrame);
|
||||
emoji->paint(q, {
|
||||
.preview = preview,
|
||||
.textColor = textst.historyTextFg->c,
|
||||
.now = context.now,
|
||||
.paused = context.paused,
|
||||
});
|
||||
|
@ -160,7 +161,7 @@ void LargeEmoji::paintCustom(
|
|||
p.drawImage(x + skip, y + skip, _selectedFrame);
|
||||
} else {
|
||||
emoji->paint(p, {
|
||||
.preview = preview,
|
||||
.textColor = textst.historyTextFg->c,
|
||||
.now = context.now,
|
||||
.position = { x + skip, y + skip },
|
||||
.paused = context.paused,
|
||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/text/custom_emoji_instance.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/painter.h"
|
||||
#include "core/application.h"
|
||||
|
@ -54,6 +55,23 @@ constexpr auto kEmojiMultiplier = 3;
|
|||
return image;
|
||||
}
|
||||
|
||||
[[nodiscard]] QColor ComputeEmojiTextColor(const PaintContext &context) {
|
||||
const auto st = context.st;
|
||||
const auto result = st->messageStyle(false, false).historyTextFg->c;
|
||||
if (!context.selected()) {
|
||||
return result;
|
||||
}
|
||||
const auto &add = st->msgStickerOverlay()->c;
|
||||
|
||||
const auto ca = add.alpha();
|
||||
const auto ra = 0x100 - ca;
|
||||
const auto aa = ca + 1;
|
||||
const auto red = (result.red() * ra + add.red() * aa) >> 8;
|
||||
const auto green = (result.green() * ra + add.green() * aa) >> 8;
|
||||
const auto blue = (result.blue() * ra + add.blue() * aa) >> 8;
|
||||
return QColor(red, green, blue, result.alpha());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Sticker::Sticker(
|
||||
|
@ -224,7 +242,9 @@ void Sticker::paintAnimationFrame(
|
|||
Painter &p,
|
||||
const PaintContext &context,
|
||||
const QRect &r) {
|
||||
const auto colored = (context.selected() && !_nextLastDiceFrame)
|
||||
const auto colored = (customEmojiPart() && _data->emojiUsesTextColor())
|
||||
? ComputeEmojiTextColor(context)
|
||||
: (context.selected() && !_nextLastDiceFrame)
|
||||
? context.st->msgStickerOverlay()->c
|
||||
: QColor(0, 0, 0, 0);
|
||||
const auto frame = _player
|
||||
|
@ -319,7 +339,12 @@ void Sticker::paintPath(
|
|||
const PaintContext &context,
|
||||
const QRect &r) {
|
||||
const auto pathGradient = _parent->delegate()->elementPathShiftGradient();
|
||||
if (context.selected()) {
|
||||
auto helper = std::optional<style::owned_color>();
|
||||
if (customEmojiPart() && _data->emojiUsesTextColor()) {
|
||||
helper.emplace(Ui::CustomEmoji::PreviewColorFromTextColor(
|
||||
ComputeEmojiTextColor(context)));
|
||||
pathGradient->overrideColors(helper->color(), helper->color());
|
||||
} else if (context.selected()) {
|
||||
pathGradient->overrideColors(
|
||||
context.st->msgServiceBgSelected(),
|
||||
context.st->msgServiceBg());
|
||||
|
@ -333,10 +358,16 @@ void Sticker::paintPath(
|
|||
r,
|
||||
pathGradient,
|
||||
mirrorHorizontal());
|
||||
if (helper) {
|
||||
pathGradient->clearOverridenColors();
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap Sticker::paintedPixmap(const PaintContext &context) const {
|
||||
const auto colored = context.selected()
|
||||
auto helper = std::optional<style::owned_color>();
|
||||
const auto colored = (customEmojiPart() && _data->emojiUsesTextColor())
|
||||
? &helper.emplace(ComputeEmojiTextColor(context)).color()
|
||||
: context.selected()
|
||||
? &context.st->msgStickerOverlay()
|
||||
: nullptr;
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
|
|
|
@ -547,7 +547,7 @@ void InlineList::paintCustomFrame(
|
|||
not_null<Ui::Text::CustomEmoji*> emoji,
|
||||
QPoint innerTopLeft,
|
||||
crl::time now,
|
||||
const QColor &preview) const {
|
||||
const QColor &textColor) const {
|
||||
if (_customCache.isNull()) {
|
||||
using namespace Ui::Text;
|
||||
const auto size = st::emojiSize;
|
||||
|
@ -562,7 +562,7 @@ void InlineList::paintCustomFrame(
|
|||
_customCache.fill(Qt::transparent);
|
||||
auto q = QPainter(&_customCache);
|
||||
emoji->paint(q, {
|
||||
.preview = preview,
|
||||
.textColor = textColor,
|
||||
.now = now,
|
||||
.paused = p.inactive(),
|
||||
});
|
||||
|
|
|
@ -110,7 +110,7 @@ private:
|
|||
not_null<Ui::Text::CustomEmoji*> emoji,
|
||||
QPoint innerTopLeft,
|
||||
crl::time now,
|
||||
const QColor &preview) const;
|
||||
const QColor &textColor) const;
|
||||
|
||||
QSize countOptimalSize() override;
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ void Row::rightActionPaint(
|
|||
const auto size = Ui::Emoji::GetSizeNormal() / style::DevicePixelRatio();
|
||||
const auto skip = (size - Ui::Text::AdjustCustomEmojiSize(size)) / 2;
|
||||
_custom->paint(p, {
|
||||
.preview = st::windowBgRipple->c,
|
||||
.textColor = st::windowFg->c,
|
||||
.now = crl::now(),
|
||||
.position = { x + skip, y + skip },
|
||||
.paused = _paused(),
|
||||
|
|
|
@ -112,13 +112,9 @@ not_null<Ui::AbstractButton*> CreateTab(
|
|||
const auto shift = (height - size) / 2;
|
||||
const auto skip = (size - AdjustCustomEmojiSize(size)) / 2;
|
||||
custom->paint(p, {
|
||||
.preview = (state->selected
|
||||
? QColor(
|
||||
st::activeButtonFg->c.red(),
|
||||
st::activeButtonFg->c.green(),
|
||||
st::activeButtonFg->c.blue(),
|
||||
st::activeButtonFg->c.alpha() / 3)
|
||||
: st::windowBgRipple->c),
|
||||
.textColor = (state->selected
|
||||
? stm->textActiveFg
|
||||
: stm->textFg)->c,
|
||||
.now = crl::now(),
|
||||
.position = { icon.x() + shift + skip, shift + skip },
|
||||
});
|
||||
|
|
|
@ -68,7 +68,6 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
|||
_badge = badge;
|
||||
_emojiStatusId = emojiStatusId;
|
||||
_emojiStatus = nullptr;
|
||||
_emojiStatusColored = nullptr;
|
||||
_view.destroy();
|
||||
if (_badge == BadgeType::None) {
|
||||
_updated.fire({});
|
||||
|
@ -89,18 +88,13 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
|||
std::move(_emojiStatus),
|
||||
_customStatusLoopsLimit);
|
||||
}
|
||||
_emojiStatusColored = std::make_unique<
|
||||
Ui::Text::CustomEmojiColored
|
||||
>();
|
||||
const auto emoji = Data::FrameSizeFromTag(sizeTag())
|
||||
/ style::DevicePixelRatio();
|
||||
_view->resize(emoji, emoji);
|
||||
_view->paintRequest(
|
||||
) | rpl::start_with_next([=, check = _view.data()]{
|
||||
_emojiStatusColored->color = _st.premiumFg->c;
|
||||
auto args = Ui::Text::CustomEmoji::Context{
|
||||
.preview = st::windowBgOver->c,
|
||||
.colored = _emojiStatusColored.get(),
|
||||
.textColor = _st.premiumFg->c,
|
||||
.now = crl::now(),
|
||||
.paused = _animationPaused && _animationPaused(),
|
||||
};
|
||||
|
|
|
@ -65,7 +65,6 @@ private:
|
|||
const int _customStatusLoopsLimit = 0;
|
||||
DocumentId _emojiStatusId = 0;
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
|
||||
std::unique_ptr<Ui::Text::CustomEmojiColored> _emojiStatusColored;
|
||||
base::flags<BadgeType> _allowed;
|
||||
BadgeType _badge = BadgeType();
|
||||
Fn<void()> _premiumClickCallback;
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Serialize {
|
|||
namespace {
|
||||
|
||||
constexpr auto kVersionTag = int32(0x7FFFFFFF);
|
||||
constexpr auto kVersion = 4;
|
||||
constexpr auto kVersion = 5;
|
||||
|
||||
enum StickerSetType {
|
||||
StickerSetTypeEmpty = 0,
|
||||
|
@ -63,6 +63,7 @@ void Document::writeToStream(QDataStream &stream, DocumentData *document) {
|
|||
const auto premium = document->isPremiumSticker()
|
||||
|| document->isPremiumEmoji();
|
||||
stream << qint32(premium ? 1 : 0);
|
||||
stream << qint32(document->emojiUsesTextColor() ? 1 : 0);
|
||||
}
|
||||
writeImageLocation(stream, document->thumbnailLocation());
|
||||
stream << qint32(document->thumbnailByteSize());
|
||||
|
@ -111,6 +112,7 @@ DocumentData *Document::readFromStreamHelper(
|
|||
|
||||
qint32 duration = -1;
|
||||
qint32 isPremiumSticker = 0;
|
||||
qint32 useTextColor = 0;
|
||||
if (type == StickerDocument) {
|
||||
QString alt;
|
||||
qint32 typeOfSet;
|
||||
|
@ -119,6 +121,9 @@ DocumentData *Document::readFromStreamHelper(
|
|||
stream >> duration;
|
||||
if (version >= 4) {
|
||||
stream >> isPremiumSticker;
|
||||
if (version >= 5) {
|
||||
stream >> useTextColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeOfSet == StickerSetTypeEmpty) {
|
||||
|
@ -140,9 +145,15 @@ DocumentData *Document::readFromStreamHelper(
|
|||
attributes.push_back(MTP_documentAttributeSticker(MTP_flags(MTPDdocumentAttributeSticker::Flag::f_mask), MTP_string(alt), MTP_inputStickerSetID(MTP_long(info->setId), MTP_long(info->accessHash)), MTPMaskCoords()));
|
||||
} break;
|
||||
case StickerSetTypeEmoji: {
|
||||
if (version < 5) {
|
||||
// We didn't store useTextColor yet, can't use.
|
||||
stream.setStatus(QDataStream::ReadCorruptData);
|
||||
return nullptr;
|
||||
}
|
||||
using Flag = MTPDdocumentAttributeCustomEmoji::Flag;
|
||||
attributes.push_back(MTP_documentAttributeCustomEmoji(
|
||||
MTP_flags(isPremiumSticker ? Flag(0) : Flag::f_free),
|
||||
MTP_flags((isPremiumSticker ? Flag(0) : Flag::f_free)
|
||||
| (useTextColor ? Flag::f_text_color : Flag(0))),
|
||||
MTP_string(alt),
|
||||
MTP_inputStickerSetID(
|
||||
MTP_long(info->setId),
|
||||
|
|
|
@ -327,7 +327,7 @@ void Action::paint(Painter &p) {
|
|||
+ (st::whoReadChecks.width() - adjusted) / 2;
|
||||
const auto y = (_height - adjusted) / 2;
|
||||
_custom->paint(p, {
|
||||
.preview = _st.ripple.color->c,
|
||||
.textColor = (selected ? _st.itemFgOver : _st.itemFg)->c,
|
||||
.now = crl::now(),
|
||||
.position = { x, y },
|
||||
});
|
||||
|
@ -588,7 +588,7 @@ void WhoReactedListMenu::EntryAction::paint(Painter &&p) {
|
|||
const auto size = Emoji::GetSizeNormal() / ratio;
|
||||
const auto skip = (size - _customSize) / 2;
|
||||
_custom->paint(p, {
|
||||
.preview = _st.ripple.color->c,
|
||||
.textColor = (selected ? _st.itemFgOver : _st.itemFg)->c,
|
||||
.now = crl::now(),
|
||||
.position = QPoint(
|
||||
width() - _st.itemPadding.right() - (size / ratio) + skip,
|
||||
|
|
|
@ -80,7 +80,6 @@ ReactionFlyAnimation::ReactionFlyAnimation(
|
|||
document,
|
||||
callback(),
|
||||
customSizeTag);
|
||||
_colored = std::make_unique<Text::CustomEmojiColored>();
|
||||
_customSize = esize;
|
||||
_centerSizeMultiplier = _customSize / float64(size);
|
||||
aroundAnimation = owner->chooseGenericAnimation(document);
|
||||
|
@ -203,10 +202,8 @@ void ReactionFlyAnimation::paintCenterFrame(
|
|||
p.drawImage(rect, _center->frame());
|
||||
} else {
|
||||
const auto scaled = (size.width() != _customSize);
|
||||
_colored->color = colored;
|
||||
_custom->paint(p, {
|
||||
.preview = QColor(0, 0, 0, 0),
|
||||
.colored = _colored.get(),
|
||||
.textColor = colored,
|
||||
.size = { _customSize, _customSize },
|
||||
.now = now,
|
||||
.scale = (scaled ? (size.width() / float64(_customSize)) : 1.),
|
||||
|
@ -237,10 +234,8 @@ void ReactionFlyAnimation::paintMiniCopies(
|
|||
/ float64(kMiniCopiesDurationMax);
|
||||
const auto scaleOut = kMiniCopiesScaleOutDuration
|
||||
/ float64(kMiniCopiesDurationMax);
|
||||
_colored->color = colored;
|
||||
auto context = Text::CustomEmoji::Context{
|
||||
.preview = preview,
|
||||
.colored = _colored.get(),
|
||||
.textColor = colored,
|
||||
.size = size,
|
||||
.now = now,
|
||||
.scaled = true,
|
||||
|
|
|
@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui::Text {
|
||||
class CustomEmoji;
|
||||
struct CustomEmojiColored;
|
||||
} // namespace Ui::Text
|
||||
|
||||
namespace Data {
|
||||
|
@ -95,7 +94,6 @@ private:
|
|||
Fn<void()> _repaint;
|
||||
QImage _flyIcon;
|
||||
std::unique_ptr<Text::CustomEmoji> _custom;
|
||||
std::unique_ptr<Text::CustomEmojiColored> _colored;
|
||||
std::unique_ptr<AnimatedIcon> _center;
|
||||
std::unique_ptr<AnimatedIcon> _effect;
|
||||
std::vector<MiniCopy> _miniCopies;
|
||||
|
|
|
@ -178,9 +178,6 @@ int PeerBadge::drawGetWidth(
|
|||
const auto size = st::emojiSize;
|
||||
const auto emoji = Ui::Text::AdjustCustomEmojiSize(size);
|
||||
_emojiStatus->skip = (size - emoji) / 2;
|
||||
_emojiStatus->colored = std::make_unique<
|
||||
Ui::Text::CustomEmojiColored
|
||||
>();
|
||||
}
|
||||
if (_emojiStatus->id != id) {
|
||||
using namespace Ui::Text;
|
||||
|
@ -192,10 +189,8 @@ int PeerBadge::drawGetWidth(
|
|||
descriptor.customEmojiRepaint),
|
||||
kPlayStatusLimit);
|
||||
}
|
||||
_emojiStatus->colored->color = (*descriptor.premiumFg)->c;
|
||||
_emojiStatus->emoji->paint(p, {
|
||||
.preview = descriptor.preview,
|
||||
.colored = _emojiStatus->colored.get(),
|
||||
.textColor = (*descriptor.premiumFg)->c,
|
||||
.now = descriptor.now,
|
||||
.position = QPoint(
|
||||
iconx - 2 * _emojiStatus->skip,
|
||||
|
|
|
@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui::Text {
|
||||
class CustomEmoji;
|
||||
struct CustomEmojiColored;
|
||||
} // namespace Ui::Text
|
||||
|
||||
namespace Ui {
|
||||
|
@ -43,7 +42,6 @@ public:
|
|||
const style::icon *premium = nullptr;
|
||||
const style::color *scam = nullptr;
|
||||
const style::color *premiumFg = nullptr;
|
||||
QColor preview;
|
||||
Fn<void()> customEmojiRepaint;
|
||||
crl::time now = 0;
|
||||
bool paused = false;
|
||||
|
@ -60,7 +58,6 @@ private:
|
|||
struct EmojiStatus {
|
||||
DocumentId id = 0;
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
||||
std::unique_ptr<Ui::Text::CustomEmojiColored> colored;
|
||||
int skip = 0;
|
||||
};
|
||||
std::unique_ptr<EmojiStatus> _emojiStatus;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 64d277891403ba3275b47d6ccab849322670cf99
|
||||
Subproject commit 4befce5a29d247fb17da3faafebb03578c5a989b
|
Loading…
Add table
Reference in a new issue