Fixed emoji in chats filter tags.

This commit is contained in:
23rd 2024-11-29 08:31:49 +03:00
parent ca0adba6cf
commit cffce47eb1
5 changed files with 140 additions and 54 deletions

View file

@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "settings/settings_common.h"
#include "ui/chat/chats_filter_tag.h"
#include "ui/effects/animation_value_f.h"
#include "ui/effects/animations.h"
#include "ui/effects/panel_animation.h"
@ -544,31 +545,18 @@ void EditFilterBox(
colors->width(),
h);
}, preview->lifetime());
const auto previewColor = preview->lifetime().make_state<QColor>();
const auto previewTag = preview->lifetime().make_state<QImage>();
const auto previewAlpha = preview->lifetime().make_state<float64>(1);
preview->paintRequest() | rpl::start_with_next([=] {
auto p = QPainter(preview);
p.fillRect(preview->rect(), Qt::transparent);
const auto &font = st::dialogRowFilterTagFont;
const auto text = name->getLastText().toUpper();
p.setFont(font);
p.setOpacity(*previewAlpha);
const auto roundedWidth = font->width(text) + font->spacew * 3;
const auto size = previewTag->size() / style::DevicePixelRatio();
const auto rect = QRect(
preview->width() - roundedWidth - st::boxRowPadding.right(),
(st::normalFont->height - font->height) / 2,
roundedWidth,
font->height);
const auto pen = QPen(*previewColor);
p.setPen(Qt::NoPen);
p.setBrush(anim::with_alpha(pen.color(), .15));
{
auto hq = PainterHighQualityEnabler(p);
const auto radius = font->height / 3.;
p.drawRoundedRect(rect, radius, radius);
}
p.setPen(pen);
p.drawText(rect, text, style::al_center);
preview->width() - size.width() - st::boxRowPadding.right(),
(st::normalFont->height - size.height()) / 2,
size.width(),
size.height());
p.drawImage(rect.topLeft(), *previewTag);
if (p.opacity() < 1) {
p.setOpacity(1. - p.opacity());
p.setFont(st::normalFont);
@ -580,10 +568,6 @@ void EditFilterBox(
}
}, preview->lifetime());
name->changes() | rpl::start_with_next([=] {
preview->update();
}, preview->lifetime());
const auto side = st::userpicBuilderEmojiAccentColorSize;
const auto line = colors->add(
Ui::CreateSkipWidget(colors, side),
@ -594,6 +578,13 @@ void EditFilterBox(
const auto palette = [](int i) {
return Ui::EmptyUserpic::UserpicColor(i).color2;
};
name->changes() | rpl::start_with_next([=] {
*previewTag = Ui::ChatsFilterTag(
name->getLastText().toUpper(),
palette(state->colorIndex.current())->c,
false);
preview->update();
}, preview->lifetime());
for (auto i = 0; i < kColorsCount; ++i) {
const auto button = Ui::CreateChild<UserpicBuilder::CircleButton>(
line);
@ -605,7 +596,10 @@ void EditFilterBox(
const auto color = palette(i);
button->setBrush(color);
if (progress == 1) {
*previewColor = color->c;
*previewTag = Ui::ChatsFilterTag(
name->getLastText().toUpper(),
color->c,
false);
if (i == kNoTag) {
*previewAlpha = 0.;
}
@ -628,7 +622,10 @@ void EditFilterBox(
buttons[was]->setSelectedProgress(1. - progress);
}
buttons[now]->setSelectedProgress(progress);
*previewColor = anim::color(c1, c2, progress);
*previewTag = Ui::ChatsFilterTag(
name->getLastText().toUpper(),
anim::color(c1, c2, progress),
false);
*previewAlpha = anim::interpolateF(a1, a2, progress);
preview->update();
}, 0., 1., st::universalDuration);

View file

@ -63,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "window/window_session_controller.h"
#include "window/window_peer_menu.h"
#include "ui/chat/chats_filter_tag.h"
#include "ui/effects/ripple_animation.h"
#include "ui/effects/loading_element.h"
#include "ui/widgets/multi_select.h"
@ -315,6 +316,9 @@ InnerWidget::InnerWidget(
session().settings().archiveCollapsedChanges() | rpl::map_to(false),
session().data().chatsFilters().changed() | rpl::map_to(true)
) | rpl::start_with_next([=](bool refreshHeight) {
if (refreshHeight) {
_chatsFilterTags.clear();
}
if (refreshHeight && _filterId) {
// Height of the main list will be refreshed in other way.
_shownList->updateHeights(_narrowRatio);
@ -4274,34 +4278,12 @@ QImage *InnerWidget::cacheChatsFilterTag(
if (roundedText.isEmpty() || colorIndex < 0) {
return nullptr;
}
const auto &roundedFont = st::dialogRowFilterTagFont;
const auto roundedWidth = roundedFont->width(roundedText)
+ roundedFont->spacew * 3;
const auto rect = QRect(0, 0, roundedWidth, roundedFont->height);
auto cache = QImage(
rect.size() * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
cache.setDevicePixelRatio(style::DevicePixelRatio());
cache.fill(Qt::transparent);
{
auto p = QPainter(&cache);
const auto pen = QPen(active
? st::dialogsBgActive
: Ui::EmptyUserpic::UserpicColor(colorIndex).color2);
p.setPen(Qt::NoPen);
p.setBrush(active
? st::dialogsTextFgActive->c
: anim::with_alpha(pen.color(), .15));
{
auto hq = PainterHighQualityEnabler(p);
const auto radius = roundedFont->height / 3.;
p.drawRoundedRect(rect, radius, radius);
}
p.setPen(pen);
p.setFont(roundedFont);
p.drawText(rect, roundedText, style::al_center);
}
return &_chatsFilterTags.emplace(key, std::move(cache)).first->second;
return &_chatsFilterTags.emplace(
key,
Ui::ChatsFilterTag(
std::move(roundedText),
Ui::EmptyUserpic::UserpicColor(colorIndex).color2->c,
active)).first->second;
}
bool InnerWidget::chooseHashtag() {

View file

@ -0,0 +1,91 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/chat/chats_filter_tag.h"
#include "ui/emoji_config.h"
#include "ui/painter.h"
#include "styles/style_dialogs.h"
namespace Ui {
QImage ChatsFilterTag(QString roundedText, QColor color, bool active) {
const auto &roundedFont = st::dialogRowFilterTagFont;
const auto additionalWidth = roundedFont->spacew * 3;
struct EmojiReplacement final {
QPixmap pixmap;
int from = -1;
int length = 0;
float64 x = -1;
};
auto emojiReplacements = std::vector<EmojiReplacement>();
auto ch = roundedText.constData();
const auto end = ch + roundedText.size();
while (ch != end) {
auto emojiLength = 0;
if (const auto emoji = Ui::Emoji::Find(ch, end, &emojiLength)) {
const auto factor = style::DevicePixelRatio();
emojiReplacements.emplace_back(
Ui::Emoji::SinglePixmap(
emoji,
st::normalFont->height * factor).scaledToHeight(
roundedFont->ascent * factor,
Qt::SmoothTransformation),
ch - roundedText.constData(),
emojiLength);
ch += emojiLength;
} else {
ch++;
}
}
if (!emojiReplacements.empty()) {
auto addedChars = 0;
for (auto &e : emojiReplacements) {
const auto pixmapWidth = e.pixmap.width()
/ style::DevicePixelRatio();
const auto spaces = 1 + pixmapWidth / roundedFont->spacew;
const auto placeholder = QString(spaces, ' ');
const auto from = e.from + addedChars;
e.x = roundedFont->width(roundedText.mid(0, from))
+ additionalWidth / 2.
+ (roundedFont->width(placeholder) - pixmapWidth) / 2.;
roundedText.replace(from, e.length, placeholder);
addedChars += spaces - e.length;
}
}
const auto roundedWidth = roundedFont->width(roundedText)
+ additionalWidth;
const auto rect = QRect(0, 0, roundedWidth, roundedFont->height);
auto cache = QImage(
rect.size() * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
cache.setDevicePixelRatio(style::DevicePixelRatio());
cache.fill(Qt::transparent);
{
auto p = QPainter(&cache);
const auto pen = QPen(active ? st::dialogsBgActive->c : color);
p.setPen(Qt::NoPen);
p.setBrush(active
? st::dialogsTextFgActive->c
: anim::with_alpha(pen.color(), .15));
{
auto hq = PainterHighQualityEnabler(p);
const auto radius = roundedFont->height / 3.;
p.drawRoundedRect(rect, radius, radius);
}
p.setPen(pen);
p.setFont(roundedFont);
p.drawText(rect, roundedText, style::al_center);
for (const auto &e : emojiReplacements) {
const auto h = e.pixmap.height() / style::DevicePixelRatio();
p.drawPixmap(QPointF(e.x, (rect.height() - h) / 2), e.pixmap);
}
}
return cache;
}
} // namespace Ui

View file

@ -0,0 +1,14 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Ui {
[[nodiscard]] QImage ChatsFilterTag(QString text, QColor color, bool active);
} // namespace Ui

View file

@ -334,6 +334,8 @@ PRIVATE
ui/chat/chat_style_radius.h
ui/chat/chat_theme.cpp
ui/chat/chat_theme.h
ui/chat/chats_filter_tag.cpp
ui/chat/chats_filter_tag.h
ui/chat/continuous_scroll.cpp
ui/chat/continuous_scroll.h
ui/chat/forward_options_box.cpp