tdesktop/Telegram/SourceFiles/history/view/media/history_view_large_emoji.cpp

93 lines
2.7 KiB
C++
Raw Normal View History

2019-08-02 18:19:14 +00:00
/*
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 "history/view/media/history_view_large_emoji.h"
#include "main/main_session.h"
#include "chat_helpers/stickers_emoji_pack.h"
#include "history/view/history_view_element.h"
#include "history/history_item.h"
#include "history/history.h"
#include "ui/image/image.h"
#include "data/data_file_origin.h"
#include "layout.h"
2020-10-10 09:15:37 +00:00
#include "styles/style_chat.h"
2019-08-02 18:19:14 +00:00
namespace HistoryView {
namespace {
2020-05-29 14:29:21 +00:00
using EmojiImage = Stickers::LargeEmojiImage;
2019-08-05 11:44:40 +00:00
auto ResolveImages(
not_null<Main::Session*> session,
const Ui::Text::IsolatedEmoji &emoji)
2020-05-29 14:29:21 +00:00
-> std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> {
2019-08-05 11:44:40 +00:00
const auto single = [&](EmojiPtr emoji) {
return emoji ? session->emojiStickersPack().image(emoji) : nullptr;
};
return { {
single(emoji.items[0]),
single(emoji.items[1]),
single(emoji.items[2]) } };
}
2020-05-29 14:29:21 +00:00
auto NonEmpty(const std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> &images) {
2019-08-05 11:44:40 +00:00
using namespace rpl::mappers;
return images | ranges::view::filter(_1 != nullptr);
2019-08-02 18:19:14 +00:00
}
} // namespace
LargeEmoji::LargeEmoji(
not_null<Element*> parent,
2019-08-05 11:44:40 +00:00
const Ui::Text::IsolatedEmoji &emoji)
2019-08-02 18:19:14 +00:00
: _parent(parent)
2019-08-05 11:44:40 +00:00
, _images(ResolveImages(&parent->data()->history()->session(), emoji)) {
2019-08-02 18:19:14 +00:00
}
QSize LargeEmoji::size() {
2019-08-05 11:44:40 +00:00
using namespace rpl::mappers;
const auto count = ranges::distance(NonEmpty(_images));
Assert(count > 0);
2020-05-29 14:29:21 +00:00
const auto single = EmojiImage::Size() / cIntRetinaFactor();
2019-08-05 11:44:40 +00:00
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
const auto inner = count * single.width() + (count - 1) * skip;
2019-08-02 18:19:14 +00:00
const auto &padding = st::largeEmojiPadding;
_size = QSize(
2019-08-05 11:44:40 +00:00
padding.left() + inner + padding.right(),
padding.top() + single.height() + padding.bottom());
2019-08-02 18:19:14 +00:00
return _size;
}
void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
2019-08-05 11:44:40 +00:00
auto &&images = NonEmpty(_images);
2019-08-02 18:19:14 +00:00
const auto &padding = st::largeEmojiPadding;
2019-08-05 11:44:40 +00:00
auto x = r.x() + (r.width() - _size.width()) / 2 + padding.left();
const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top();
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
2020-05-29 14:29:21 +00:00
const auto size = EmojiImage::Size() / cIntRetinaFactor();
2019-08-05 11:44:40 +00:00
for (const auto &image : images) {
2020-05-29 14:29:21 +00:00
const auto w = size.width();
if (const auto &prepared = image->image) {
const auto h = size.height();
2019-08-05 11:44:40 +00:00
const auto &c = st::msgStickerOverlay;
const auto pixmap = selected
2020-05-29 15:10:25 +00:00
? prepared->pixColored(c, w, h)
: prepared->pix(w, h);
2019-08-05 11:44:40 +00:00
p.drawPixmap(x, y, pixmap);
2020-05-29 14:29:21 +00:00
} else if (image->load) {
image->load();
2019-08-05 11:44:40 +00:00
}
x += w + skip;
}
2019-08-02 18:19:14 +00:00
}
} // namespace HistoryView