mirror of https://github.com/procxx/kepka.git
Leave only one image source type.
This commit is contained in:
parent
6513422e40
commit
d0c78eaddd
|
@ -117,68 +117,6 @@ constexpr auto kClearSourceTimeout = 10 * crl::time(1000);
|
|||
return list[index - 1];
|
||||
}
|
||||
|
||||
class ImageSource : public Images::Source {
|
||||
public:
|
||||
explicit ImageSource(
|
||||
EmojiPtr emoji,
|
||||
not_null<crl::object_on_queue<EmojiImageLoader>*> loader);
|
||||
|
||||
void load() override;
|
||||
QImage takeLoaded() override;
|
||||
|
||||
int width() override;
|
||||
int height() override;
|
||||
|
||||
private:
|
||||
// While HistoryView::Element-s are almost never destroyed
|
||||
// we make loading of the image lazy.
|
||||
not_null<crl::object_on_queue<EmojiImageLoader>*> _loader;
|
||||
EmojiPtr _emoji = nullptr;
|
||||
QImage _data;
|
||||
QSize _size;
|
||||
base::binary_guard _loading;
|
||||
|
||||
};
|
||||
|
||||
ImageSource::ImageSource(
|
||||
EmojiPtr emoji,
|
||||
not_null<crl::object_on_queue<EmojiImageLoader>*> loader)
|
||||
: _loader(loader)
|
||||
, _emoji(emoji)
|
||||
, _size(SingleSize()) {
|
||||
}
|
||||
|
||||
void ImageSource::load() {
|
||||
if (!_data.isNull() || _loading) {
|
||||
return;
|
||||
}
|
||||
_loader->with([
|
||||
this,
|
||||
emoji = _emoji,
|
||||
guard = _loading.make_guard()
|
||||
](EmojiImageLoader &loader) mutable {
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
crl::on_main(std::move(guard), [this, image = loader.prepare(emoji)]{
|
||||
_data = image;
|
||||
Auth().downloaderTaskFinished().notify();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
QImage ImageSource::takeLoaded() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
int ImageSource::width() {
|
||||
return _size.width();
|
||||
}
|
||||
|
||||
int ImageSource::height() {
|
||||
return _size.height();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EmojiImageLoader::EmojiImageLoader(
|
||||
|
@ -264,6 +202,10 @@ std::shared_ptr<UniversalImages> EmojiImageLoader::releaseImages() {
|
|||
|
||||
} // namespace details
|
||||
|
||||
QSize LargeEmojiImage::Size() {
|
||||
return details::SingleSize();
|
||||
}
|
||||
|
||||
EmojiPack::EmojiPack(not_null<Main::Session*> session)
|
||||
: _session(session)
|
||||
, _imageLoader(prepareSourceImages(), session->settings().largeEmoji())
|
||||
|
@ -347,13 +289,38 @@ auto EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) -> Sticker {
|
|||
return Sticker();
|
||||
}
|
||||
|
||||
std::shared_ptr<Image> EmojiPack::image(EmojiPtr emoji) {
|
||||
const auto i = _images.emplace(emoji, std::weak_ptr<Image>()).first;
|
||||
std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
|
||||
const auto i = _images.emplace(
|
||||
emoji,
|
||||
std::weak_ptr<LargeEmojiImage>()).first;
|
||||
if (const auto result = i->second.lock()) {
|
||||
return result;
|
||||
}
|
||||
auto result = std::make_shared<Image>(
|
||||
std::make_unique<details::ImageSource>(emoji, &_imageLoader));
|
||||
auto result = std::make_shared<LargeEmojiImage>();
|
||||
const auto raw = result.get();
|
||||
const auto weak = base::make_weak(_session.get());
|
||||
raw->load = [=] {
|
||||
_imageLoader.with([=](details::EmojiImageLoader &loader) mutable {
|
||||
crl::on_main(weak, [
|
||||
=,
|
||||
image = loader.prepare(emoji)
|
||||
]() mutable {
|
||||
const auto i = _images.find(emoji);
|
||||
if (i != end(_images)) {
|
||||
if (const auto strong = i->second.lock()) {
|
||||
if (!strong->image) {
|
||||
strong->load = nullptr;
|
||||
strong->image.emplace(
|
||||
std::make_unique<Images::ImageSource>(
|
||||
std::move(image)));
|
||||
_session->downloaderTaskFinished().notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
raw->load = nullptr;
|
||||
};
|
||||
i->second = result;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/text/text_isolated_emoji.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
#include <crl/crl_object_on_queue.h>
|
||||
|
||||
class Image;
|
||||
class HistoryItem;
|
||||
class DocumentData;
|
||||
|
||||
|
@ -40,6 +40,13 @@ class EmojiImageLoader;
|
|||
|
||||
using IsolatedEmoji = Ui::Text::IsolatedEmoji;
|
||||
|
||||
struct LargeEmojiImage {
|
||||
std::optional<Image> image;
|
||||
FnMut<void()> load;
|
||||
|
||||
[[nodiscard]] static QSize Size();
|
||||
};
|
||||
|
||||
class EmojiPack final {
|
||||
public:
|
||||
struct Sticker {
|
||||
|
@ -61,7 +68,7 @@ public:
|
|||
void remove(not_null<const HistoryItem*> item);
|
||||
|
||||
[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
|
||||
[[nodiscard]] std::shared_ptr<Image> image(EmojiPtr emoji);
|
||||
[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
|
||||
|
||||
private:
|
||||
class ImageLoader;
|
||||
|
@ -85,7 +92,7 @@ private:
|
|||
base::flat_map<
|
||||
IsolatedEmoji,
|
||||
base::flat_set<not_null<HistoryItem*>>> _items;
|
||||
base::flat_map<EmojiPtr, std::weak_ptr<Image>> _images;
|
||||
base::flat_map<EmojiPtr, std::weak_ptr<LargeEmojiImage>> _images;
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
crl::object_on_queue<details::EmojiImageLoader> _imageLoader;
|
||||
|
|
|
@ -20,10 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
using EmojiImage = Stickers::LargeEmojiImage;
|
||||
|
||||
auto ResolveImages(
|
||||
not_null<Main::Session*> session,
|
||||
const Ui::Text::IsolatedEmoji &emoji)
|
||||
-> std::array<std::shared_ptr<Image>, Ui::Text::kIsolatedEmojiLimit> {
|
||||
-> std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> {
|
||||
const auto single = [&](EmojiPtr emoji) {
|
||||
return emoji ? session->emojiStickersPack().image(emoji) : nullptr;
|
||||
};
|
||||
|
@ -33,7 +35,7 @@ auto ResolveImages(
|
|||
single(emoji.items[2]) } };
|
||||
}
|
||||
|
||||
auto NonEmpty(const std::array<std::shared_ptr<Image>, Ui::Text::kIsolatedEmojiLimit> &images) {
|
||||
auto NonEmpty(const std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> &images) {
|
||||
using namespace rpl::mappers;
|
||||
|
||||
return images | ranges::view::filter(_1 != nullptr);
|
||||
|
@ -54,7 +56,7 @@ QSize LargeEmoji::size() {
|
|||
const auto count = ranges::distance(NonEmpty(_images));
|
||||
Assert(count > 0);
|
||||
|
||||
const auto single = _images[0]->size() / cIntRetinaFactor();
|
||||
const auto single = EmojiImage::Size() / cIntRetinaFactor();
|
||||
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
|
||||
const auto inner = count * single.width() + (count - 1) * skip;
|
||||
const auto &padding = st::largeEmojiPadding;
|
||||
|
@ -71,16 +73,18 @@ void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
|
|||
const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top();
|
||||
const auto o = Data::FileOrigin();
|
||||
const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
|
||||
const auto size = EmojiImage::Size() / cIntRetinaFactor();
|
||||
for (const auto &image : images) {
|
||||
image->load();
|
||||
const auto w = image->width() / cIntRetinaFactor();
|
||||
if (image->loaded()) {
|
||||
const auto h = image->height() / cIntRetinaFactor();
|
||||
const auto w = size.width();
|
||||
if (const auto &prepared = image->image) {
|
||||
const auto h = size.height();
|
||||
const auto &c = st::msgStickerOverlay;
|
||||
const auto pixmap = selected
|
||||
? image->pixColored(o, c, w, h)
|
||||
: image->pix(o, w, h);
|
||||
? prepared->pixColored(o, c, w, h)
|
||||
: prepared->pix(o, w, h);
|
||||
p.drawPixmap(x, y, pixmap);
|
||||
} else if (image->load) {
|
||||
image->load();
|
||||
}
|
||||
x += w + skip;
|
||||
}
|
||||
|
|
|
@ -10,15 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/media/history_view_media_unwrapped.h"
|
||||
#include "ui/text/text_isolated_emoji.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
struct FileOrigin;
|
||||
} // namespace Data
|
||||
|
||||
namespace Lottie {
|
||||
class SinglePlayer;
|
||||
} // namespace Lottie
|
||||
namespace Stickers {
|
||||
struct LargeEmojiImage;
|
||||
} // namespace Stickers
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
|
@ -38,7 +36,7 @@ public:
|
|||
private:
|
||||
const not_null<Element*> _parent;
|
||||
const std::array<
|
||||
std::shared_ptr<Image>,
|
||||
std::shared_ptr<Stickers::LargeEmojiImage>,
|
||||
Ui::Text::kIsolatedEmojiLimit> _images;
|
||||
QSize _size;
|
||||
|
||||
|
|
Loading…
Reference in New Issue