2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

Update API scheme on layer 148: Topic icons.

This commit is contained in:
John Preston
2022-10-05 11:42:44 +04:00
parent f3c664859d
commit ae3496d6a4
31 changed files with 525 additions and 204 deletions

View File

@@ -18,11 +18,110 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_item.h"
#include "ui/painter.h"
#include "ui/color_int_conversion.h"
#include "styles/style_dialogs.h"
#include "styles/style_chat_helpers.h"
#include <QtSvg/QSvgRenderer>
namespace Data {
const base::flat_map<int32, QString> &ForumTopicIcons() {
static const auto Result = base::flat_map<int32, QString>{
{ 0x6FB9F0, u"blue"_q },
{ 0xFFD67E, u"yellow"_q },
{ 0xCB86DB, u"violet"_q },
{ 0x8EEE98, u"green"_q },
{ 0xFF93B2, u"rose"_q },
{ 0xFB6F5F, u"red"_q },
};
return Result;
}
const std::vector<int32> &ForumTopicColorIds() {
static const auto Result = ForumTopicIcons(
) | ranges::views::transform([](const auto &pair) {
return pair.first;
}) | ranges::to_vector;
return Result;
}
const QString &ForumTopicDefaultIcon() {
static const auto Result = u"gray"_q;
return Result;
}
const QString &ForumTopicIcon(int32 colorId) {
const auto &icons = ForumTopicIcons();
const auto i = icons.find(colorId);
return (i != end(icons)) ? i->second : ForumTopicDefaultIcon();
}
QString ForumTopicIconPath(const QString &name) {
return u":/gui/topic_icons/%1.svg"_q.arg(name);
}
QImage ForumTopicIconBackground(int32 colorId, int size) {
const auto ratio = style::DevicePixelRatio();
auto svg = QSvgRenderer(ForumTopicIconPath(ForumTopicIcon(colorId)));
auto result = QImage(
QSize(size, size) * ratio,
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(ratio);
result.fill(Qt::transparent);
auto p = QPainter(&result);
svg.render(&p, QRect(0, 0, size, size));
p.end();
return result;
}
QString ExtractNonEmojiLetter(const QString &title) {
const auto begin = title.data();
const auto end = begin + title.size();
for (auto ch = begin; ch != end;) {
auto length = 0;
if (Ui::Emoji::Find(ch, end, &length)) {
ch += length;
continue;
}
uint ucs4 = ch->unicode();
length = 1;
if (QChar::isHighSurrogate(ucs4) && ch + 1 != end) {
ushort low = ch[1].unicode();
if (QChar::isLowSurrogate(low)) {
ucs4 = QChar::surrogateToUcs4(ucs4, low);
length = 2;
}
}
if (!QChar::isLetterOrNumber(ucs4)) {
ch += length;
continue;
}
return QString(ch, length);
}
return QString();
}
QImage ForumTopicIconFrame(
int32 colorId,
const QString &title,
const style::ForumTopicIcon &st) {
auto background = ForumTopicIconBackground(colorId, st.size);
if (const auto one = ExtractNonEmojiLetter(title); !one.isEmpty()) {
auto p = QPainter(&background);
p.setPen(Qt::white);
p.drawText(
QRect(0, st.textTop, st.size, st.font->height * 2),
one,
style::al_top);
}
return background;
}
ForumTopic::ForumTopic(not_null<History*> history, MsgId rootId)
: Entry(&history->owner(), Type::ForumTopic)
, _history(history)
@@ -62,6 +161,7 @@ void ForumTopic::applyTopic(const MTPForumTopic &topic) {
} else {
applyIconId(0);
}
applyColorId(data.vicon_color().v);
const auto pinned = _list->pinned();
#if 0 // #TODO forum pinned
@@ -218,19 +318,29 @@ void ForumTopic::paintUserpic(
std::shared_ptr<Data::CloudImageView> &view,
const Dialogs::Ui::PaintContext &context) const {
const auto &st = context.st;
const auto position = QPoint(st->padding.left(), st->padding.top());
if (_icon) {
_icon->paint(p, {
.preview = st::windowBgOver->c,
.now = context.now,
.position = QPoint(st->padding.left(), st->padding.top()),
.position = position,
.paused = context.paused,
});
} else {
// #TODO forum
st::stickersPremium.paint(
p,
QPoint(st->padding.left(), st->padding.top()),
st->padding.left() * 2 + st::stickersPremium.width());
validateDefaultIcon();
const auto size = st::defaultForumTopicIcon.size;
const auto esize = st::emojiSize;
const auto shift = (esize - size) / 2;
p.drawImage(position + QPoint(shift, shift), _defaultIcon);
}
}
void ForumTopic::validateDefaultIcon() const {
if (_defaultIcon.isNull()) {
_defaultIcon = ForumTopicIconFrame(
_colorId,
_title,
st::defaultForumTopicIcon);
}
}
@@ -291,6 +401,7 @@ void ForumTopic::applyTitle(const QString &title) {
}
_title = isGeneral() ? "General! Topic." : title; // #TODO forum lang
++_titleVersion;
_defaultIcon = QImage();
indexTitleParts();
updateChatListEntry();
}
@@ -308,10 +419,21 @@ void ForumTopic::applyIconId(DocumentId iconId) {
[=] { updateChatListEntry(); },
Data::CustomEmojiManager::SizeTag::Normal)
: nullptr;
if (iconId) {
_defaultIcon = QImage();
}
}
updateChatListEntry();
}
int32 ForumTopic::colorId() const {
return _colorId;
}
void ForumTopic::applyColorId(int32 colorId) {
_colorId = colorId;
}
void ForumTopic::applyItemAdded(not_null<HistoryItem*> item) {
setLastMessage(item);
}