tdesktop/Telegram/SourceFiles/ui/emoji_config.h

195 lines
4.1 KiB
C++

/*
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
#include "base/basic_types.h"
#include "base/binary_guard.h"
#include "emoji.h"
#include <QtGui/QPainter>
#include <QtGui/QPixmap>
#include <rpl/producer.h>
using EmojiPtr = const Ui::Emoji::One*;
namespace Ui {
namespace Emoji {
namespace internal {
[[nodiscard]] QString CacheFileFolder();
[[nodiscard]] QString SetDataPath(int id);
} // namespace internal
void Init();
void Clear();
void ClearIrrelevantCache();
struct Set {
int id = 0;
int postId = 0;
int size = 0;
QString name;
QString previewPath;
};
// Thread safe, callback is called on main thread.
void SwitchToSet(int id, Fn<void(bool)> callback);
std::vector<Set> Sets();
int CurrentSetId();
bool SetIsReady(int id);
rpl::producer<> Updated();
int GetSizeNormal();
int GetSizeLarge();
#if defined Q_OS_MAC && !defined OS_MAC_OLD
int GetSizeTouchbar();
#endif
class One {
struct CreationTag {
};
public:
One(One &&other) = default;
One(const QString &id, EmojiPtr original, uint32 index, bool hasPostfix, bool colorizable, const CreationTag &)
: _id(id)
, _original(original)
, _index(index)
, _hasPostfix(hasPostfix)
, _colorizable(colorizable) {
Expects(!_colorizable || !colored());
}
QString id() const {
return _id;
}
QString text() const {
return hasPostfix() ? (_id + QChar(kPostfix)) : _id;
}
bool colored() const {
return (_original != nullptr);
}
EmojiPtr original() const {
return _original ? _original : this;
}
QString nonColoredId() const {
return original()->id();
}
bool hasPostfix() const {
return _hasPostfix;
}
bool hasVariants() const {
return _colorizable || colored();
}
int variantsCount() const;
int variantIndex(EmojiPtr variant) const;
EmojiPtr variant(int index) const;
int index() const {
return _index;
}
int sprite() const {
return int(_index >> 9);
}
int row() const {
return int((_index >> 5) & 0x0FU);
}
int column() const {
return int(_index & 0x1FU);
}
QString toUrl() const {
return "emoji://e." + QString::number(index());
}
private:
const QString _id;
const EmojiPtr _original = nullptr;
const uint32 _index = 0;
const bool _hasPostfix = false;
const bool _colorizable = false;
friend void internal::Init();
};
inline EmojiPtr FromUrl(const QString &url) {
auto start = qstr("emoji://e.");
if (url.startsWith(start)) {
return internal::ByIndex(url.midRef(start.size()).toInt()); // skip emoji://e.
}
return nullptr;
}
inline EmojiPtr Find(const QChar *start, const QChar *end, int *outLength = nullptr) {
return internal::Find(start, end, outLength);
}
inline EmojiPtr Find(const QString &text, int *outLength = nullptr) {
return Find(text.constBegin(), text.constEnd(), outLength);
}
QString IdFromOldKey(uint64 oldKey);
inline EmojiPtr FromOldKey(uint64 oldKey) {
return Find(IdFromOldKey(oldKey));
}
inline int ColorIndexFromCode(uint32 code) {
switch (code) {
case 0xD83CDFFBU: return 1;
case 0xD83CDFFCU: return 2;
case 0xD83CDFFDU: return 3;
case 0xD83CDFFEU: return 4;
case 0xD83CDFFFU: return 5;
}
return 0;
}
inline int ColorIndexFromOldKey(uint64 oldKey) {
return ColorIndexFromCode(uint32(oldKey & 0xFFFFFFFFLLU));
}
QVector<EmojiPtr> GetDefaultRecent();
const QPixmap &SinglePixmap(EmojiPtr emoji, int fontHeight);
void Draw(QPainter &p, EmojiPtr emoji, int size, int x, int y);
class UniversalImages {
public:
explicit UniversalImages(int id);
int id() const;
bool ensureLoaded();
void clear();
void draw(QPainter &p, EmojiPtr emoji, int size, int x, int y) const;
// This method must be thread safe and so it is called after
// the _id value is fixed and all _sprites are loaded.
QImage generate(int size, int index) const;
private:
const int _id = 0;
std::vector<QImage> _sprites;
};
const std::shared_ptr<UniversalImages> &SourceImages();
void ClearSourceImages(const std::shared_ptr<UniversalImages> &images);
} // namespace Emoji
} // namespace Ui