mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Fixed emoji in chats filter tags.
This commit is contained in:
parent
ca0adba6cf
commit
cffce47eb1
5 changed files with 140 additions and 54 deletions
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
|
#include "ui/chat/chats_filter_tag.h"
|
||||||
#include "ui/effects/animation_value_f.h"
|
#include "ui/effects/animation_value_f.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/effects/panel_animation.h"
|
#include "ui/effects/panel_animation.h"
|
||||||
|
@ -544,31 +545,18 @@ void EditFilterBox(
|
||||||
colors->width(),
|
colors->width(),
|
||||||
h);
|
h);
|
||||||
}, preview->lifetime());
|
}, 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);
|
const auto previewAlpha = preview->lifetime().make_state<float64>(1);
|
||||||
preview->paintRequest() | rpl::start_with_next([=] {
|
preview->paintRequest() | rpl::start_with_next([=] {
|
||||||
auto p = QPainter(preview);
|
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);
|
p.setOpacity(*previewAlpha);
|
||||||
const auto roundedWidth = font->width(text) + font->spacew * 3;
|
const auto size = previewTag->size() / style::DevicePixelRatio();
|
||||||
const auto rect = QRect(
|
const auto rect = QRect(
|
||||||
preview->width() - roundedWidth - st::boxRowPadding.right(),
|
preview->width() - size.width() - st::boxRowPadding.right(),
|
||||||
(st::normalFont->height - font->height) / 2,
|
(st::normalFont->height - size.height()) / 2,
|
||||||
roundedWidth,
|
size.width(),
|
||||||
font->height);
|
size.height());
|
||||||
const auto pen = QPen(*previewColor);
|
p.drawImage(rect.topLeft(), *previewTag);
|
||||||
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);
|
|
||||||
if (p.opacity() < 1) {
|
if (p.opacity() < 1) {
|
||||||
p.setOpacity(1. - p.opacity());
|
p.setOpacity(1. - p.opacity());
|
||||||
p.setFont(st::normalFont);
|
p.setFont(st::normalFont);
|
||||||
|
@ -580,10 +568,6 @@ void EditFilterBox(
|
||||||
}
|
}
|
||||||
}, preview->lifetime());
|
}, preview->lifetime());
|
||||||
|
|
||||||
name->changes() | rpl::start_with_next([=] {
|
|
||||||
preview->update();
|
|
||||||
}, preview->lifetime());
|
|
||||||
|
|
||||||
const auto side = st::userpicBuilderEmojiAccentColorSize;
|
const auto side = st::userpicBuilderEmojiAccentColorSize;
|
||||||
const auto line = colors->add(
|
const auto line = colors->add(
|
||||||
Ui::CreateSkipWidget(colors, side),
|
Ui::CreateSkipWidget(colors, side),
|
||||||
|
@ -594,6 +578,13 @@ void EditFilterBox(
|
||||||
const auto palette = [](int i) {
|
const auto palette = [](int i) {
|
||||||
return Ui::EmptyUserpic::UserpicColor(i).color2;
|
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) {
|
for (auto i = 0; i < kColorsCount; ++i) {
|
||||||
const auto button = Ui::CreateChild<UserpicBuilder::CircleButton>(
|
const auto button = Ui::CreateChild<UserpicBuilder::CircleButton>(
|
||||||
line);
|
line);
|
||||||
|
@ -605,7 +596,10 @@ void EditFilterBox(
|
||||||
const auto color = palette(i);
|
const auto color = palette(i);
|
||||||
button->setBrush(color);
|
button->setBrush(color);
|
||||||
if (progress == 1) {
|
if (progress == 1) {
|
||||||
*previewColor = color->c;
|
*previewTag = Ui::ChatsFilterTag(
|
||||||
|
name->getLastText().toUpper(),
|
||||||
|
color->c,
|
||||||
|
false);
|
||||||
if (i == kNoTag) {
|
if (i == kNoTag) {
|
||||||
*previewAlpha = 0.;
|
*previewAlpha = 0.;
|
||||||
}
|
}
|
||||||
|
@ -628,7 +622,10 @@ void EditFilterBox(
|
||||||
buttons[was]->setSelectedProgress(1. - progress);
|
buttons[was]->setSelectedProgress(1. - progress);
|
||||||
}
|
}
|
||||||
buttons[now]->setSelectedProgress(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);
|
*previewAlpha = anim::interpolateF(a1, a2, progress);
|
||||||
preview->update();
|
preview->update();
|
||||||
}, 0., 1., st::universalDuration);
|
}, 0., 1., st::universalDuration);
|
||||||
|
|
|
@ -63,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
|
#include "ui/chat/chats_filter_tag.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/effects/loading_element.h"
|
#include "ui/effects/loading_element.h"
|
||||||
#include "ui/widgets/multi_select.h"
|
#include "ui/widgets/multi_select.h"
|
||||||
|
@ -315,6 +316,9 @@ InnerWidget::InnerWidget(
|
||||||
session().settings().archiveCollapsedChanges() | rpl::map_to(false),
|
session().settings().archiveCollapsedChanges() | rpl::map_to(false),
|
||||||
session().data().chatsFilters().changed() | rpl::map_to(true)
|
session().data().chatsFilters().changed() | rpl::map_to(true)
|
||||||
) | rpl::start_with_next([=](bool refreshHeight) {
|
) | rpl::start_with_next([=](bool refreshHeight) {
|
||||||
|
if (refreshHeight) {
|
||||||
|
_chatsFilterTags.clear();
|
||||||
|
}
|
||||||
if (refreshHeight && _filterId) {
|
if (refreshHeight && _filterId) {
|
||||||
// Height of the main list will be refreshed in other way.
|
// Height of the main list will be refreshed in other way.
|
||||||
_shownList->updateHeights(_narrowRatio);
|
_shownList->updateHeights(_narrowRatio);
|
||||||
|
@ -4274,34 +4278,12 @@ QImage *InnerWidget::cacheChatsFilterTag(
|
||||||
if (roundedText.isEmpty() || colorIndex < 0) {
|
if (roundedText.isEmpty() || colorIndex < 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const auto &roundedFont = st::dialogRowFilterTagFont;
|
return &_chatsFilterTags.emplace(
|
||||||
const auto roundedWidth = roundedFont->width(roundedText)
|
key,
|
||||||
+ roundedFont->spacew * 3;
|
Ui::ChatsFilterTag(
|
||||||
const auto rect = QRect(0, 0, roundedWidth, roundedFont->height);
|
std::move(roundedText),
|
||||||
auto cache = QImage(
|
Ui::EmptyUserpic::UserpicColor(colorIndex).color2->c,
|
||||||
rect.size() * style::DevicePixelRatio(),
|
active)).first->second;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::chooseHashtag() {
|
bool InnerWidget::chooseHashtag() {
|
||||||
|
|
91
Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp
Normal file
91
Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp
Normal 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
|
14
Telegram/SourceFiles/ui/chat/chats_filter_tag.h
Normal file
14
Telegram/SourceFiles/ui/chat/chats_filter_tag.h
Normal 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
|
|
@ -334,6 +334,8 @@ PRIVATE
|
||||||
ui/chat/chat_style_radius.h
|
ui/chat/chat_style_radius.h
|
||||||
ui/chat/chat_theme.cpp
|
ui/chat/chat_theme.cpp
|
||||||
ui/chat/chat_theme.h
|
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.cpp
|
||||||
ui/chat/continuous_scroll.h
|
ui/chat/continuous_scroll.h
|
||||||
ui/chat/forward_options_box.cpp
|
ui/chat/forward_options_box.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue