mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-11 09:19:35 +00:00
Add updating emoji on the run.
This commit is contained in:
parent
8190b10680
commit
79fea49272
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "lang/lang_cloud_manager.h"
|
||||
#include "lang/lang_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
@ -93,6 +94,11 @@ MainWindow::MainWindow() {
|
||||
updateGlobalMenu();
|
||||
}, lifetime());
|
||||
|
||||
Ui::Emoji::Updated(
|
||||
) | rpl::start_with_next([=] {
|
||||
Ui::ForceFullRepaint(this);
|
||||
}, lifetime());
|
||||
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
}
|
||||
|
@ -29,6 +29,13 @@ constexpr auto kSetVersion = uint32(1);
|
||||
constexpr auto kCacheVersion = uint32(3);
|
||||
constexpr auto kMaxId = uint32(1 << 8);
|
||||
|
||||
const auto kSets = {
|
||||
Set{ 0, 0, "Mac" },
|
||||
Set{ 1, 205, "Android" },
|
||||
Set{ 2, 206, "Twemoji" },
|
||||
Set{ 3, 237, "EmojiOne" },
|
||||
};
|
||||
|
||||
// Right now we can't allow users of Ui::Emoji to create custom sizes.
|
||||
// Any Instance::Instance() can invalidate Universal.id() and sprites.
|
||||
// So all Instance::Instance() should happen before async generations.
|
||||
@ -76,12 +83,13 @@ auto SizeNormal = -1;
|
||||
auto SizeLarge = -1;
|
||||
auto SpritesCount = -1;
|
||||
|
||||
std::unique_ptr<Instance> InstanceNormal;
|
||||
std::unique_ptr<Instance> InstanceLarge;
|
||||
std::shared_ptr<UniversalImages> Universal;
|
||||
auto InstanceNormal = std::unique_ptr<Instance>();
|
||||
auto InstanceLarge = std::unique_ptr<Instance>();
|
||||
auto Universal = std::shared_ptr<UniversalImages>();
|
||||
auto Updates = rpl::event_stream<>();
|
||||
|
||||
std::map<int, QPixmap> MainEmojiMap;
|
||||
std::map<int, std::map<int, QPixmap>> OtherEmojiMap;
|
||||
auto MainEmojiMap = std::map<int, QPixmap>();
|
||||
auto OtherEmojiMap = std::map<int, std::map<int, QPixmap>>();
|
||||
|
||||
int RowsCount(int index) {
|
||||
if (index + 1 < SpritesCount) {
|
||||
@ -158,9 +166,8 @@ void ClearCurrentSetId() {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
QFile(CurrentSettingPath()).remove();
|
||||
QDir(SetDataPath(id)).removeRecursively();
|
||||
Universal = std::make_shared<UniversalImages>(0);
|
||||
SwitchToSet(0);
|
||||
}
|
||||
|
||||
void SaveToFile(int id, const QImage &image, int size, int index) {
|
||||
@ -510,6 +517,45 @@ void ClearIrrelevantCache() {
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<Set> Sets() {
|
||||
return kSets;
|
||||
}
|
||||
|
||||
int CurrentSetId() {
|
||||
Expects(Universal != nullptr);
|
||||
|
||||
return Universal->id();
|
||||
}
|
||||
|
||||
bool SwitchToSet(int id) {
|
||||
Expects(IsValidSetId(id));
|
||||
|
||||
if (Universal && Universal->id() == id) {
|
||||
return true;
|
||||
}
|
||||
auto universal = std::make_shared<UniversalImages>(id);
|
||||
if (!universal->ensureLoaded()) {
|
||||
return false;
|
||||
}
|
||||
auto setting = QFile(CurrentSettingPath());
|
||||
if (!id) {
|
||||
setting.remove();
|
||||
} else if (setting.open(QIODevice::WriteOnly)) {
|
||||
auto stream = QDataStream(&setting);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
stream << qint32(id);
|
||||
}
|
||||
Universal = std::move(universal);
|
||||
MainEmojiMap.clear();
|
||||
OtherEmojiMap.clear();
|
||||
Updates.fire({});
|
||||
return true;
|
||||
}
|
||||
|
||||
rpl::producer<> Updated() {
|
||||
return Updates.events();
|
||||
}
|
||||
|
||||
int GetSizeNormal() {
|
||||
Expects(SizeNormal > 0);
|
||||
|
||||
@ -833,7 +879,6 @@ void Instance::checkUniversalImages() {
|
||||
}
|
||||
if (!Universal->ensureLoaded() && Universal->id() != 0) {
|
||||
ClearCurrentSetId();
|
||||
Universal->ensureLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,17 @@ void Clear();
|
||||
|
||||
void ClearIrrelevantCache();
|
||||
|
||||
struct Set {
|
||||
int id = 0;
|
||||
int postId = 0;
|
||||
QString name;
|
||||
};
|
||||
|
||||
std::vector<Set> Sets();
|
||||
int CurrentSetId();
|
||||
bool SwitchToSet(int id);
|
||||
rpl::producer<> Updated();
|
||||
|
||||
int GetSizeNormal();
|
||||
int GetSizeLarge();
|
||||
|
||||
|
@ -45,6 +45,49 @@ const auto kClearFormatSequence = QKeySequence("ctrl+shift+n");
|
||||
const auto kMonospaceSequence = QKeySequence("ctrl+shift+m");
|
||||
const auto kEditLinkSequence = QKeySequence("ctrl+k");
|
||||
|
||||
class InputDocument : public QTextDocument {
|
||||
public:
|
||||
InputDocument(QObject *parent, const style::InputField &st);
|
||||
|
||||
protected:
|
||||
QVariant loadResource(int type, const QUrl &name) override;
|
||||
|
||||
private:
|
||||
const style::InputField &_st;
|
||||
std::map<QUrl, QVariant> _emojiCache;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
InputDocument::InputDocument(QObject *parent, const style::InputField &st)
|
||||
: QTextDocument(parent)
|
||||
, _st(st) {
|
||||
Ui::Emoji::Updated(
|
||||
) | rpl::start_with_next([=] {
|
||||
_emojiCache.clear();
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
QVariant InputDocument::loadResource(int type, const QUrl &name) {
|
||||
if (type != QTextDocument::ImageResource
|
||||
|| name.scheme() != qstr("emoji")) {
|
||||
return QTextDocument::loadResource(type, name);
|
||||
}
|
||||
const auto i = _emojiCache.find(name);
|
||||
if (i != _emojiCache.end()) {
|
||||
return i->second;
|
||||
}
|
||||
auto result = [&] {
|
||||
if (const auto emoji = Ui::Emoji::FromUrl(name.toDisplayString())) {
|
||||
const auto height = _st.font->height;
|
||||
return QVariant(Ui::Emoji::SinglePixmap(emoji, height));
|
||||
}
|
||||
return QVariant();
|
||||
}();
|
||||
_emojiCache.emplace(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsNewline(QChar ch) {
|
||||
return (kNewlineChars.indexOf(ch) >= 0);
|
||||
}
|
||||
@ -727,10 +770,6 @@ public:
|
||||
Inner(not_null<InputField*> parent) : QTextEdit(parent) {
|
||||
}
|
||||
|
||||
QVariant loadResource(int type, const QUrl &name) override {
|
||||
return outer()->loadResource(type, name);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool viewportEvent(QEvent *e) override {
|
||||
return outer()->viewportEventInner(e);
|
||||
@ -1141,6 +1180,8 @@ InputField::InputField(
|
||||
, _inner(std::make_unique<Inner>(this))
|
||||
, _lastTextWithTags(value)
|
||||
, _placeholderFactory(std::move(placeholderFactory)) {
|
||||
_inner->setDocument(Ui::CreateChild<InputDocument>(_inner.get(), _st));
|
||||
|
||||
_inner->setAcceptRichText(false);
|
||||
resize(_st.width, _minHeight);
|
||||
|
||||
@ -1233,14 +1274,6 @@ bool InputField::viewportEventInner(QEvent *e) {
|
||||
return _inner->QTextEdit::viewportEvent(e);
|
||||
}
|
||||
|
||||
QVariant InputField::loadResource(int type, const QUrl &name) {
|
||||
const auto imageName = name.toDisplayString();
|
||||
if (const auto emoji = Ui::Emoji::FromUrl(imageName)) {
|
||||
return QVariant(Ui::Emoji::SinglePixmap(emoji, _st.font->height));
|
||||
}
|
||||
return _inner->QTextEdit::loadResource(type, name);
|
||||
}
|
||||
|
||||
void InputField::updatePalette() {
|
||||
auto p = _inner->palette();
|
||||
p.setColor(QPalette::Text, _st.textFg->c);
|
||||
|
@ -341,7 +341,6 @@ private:
|
||||
|
||||
void handleContentsChanged();
|
||||
bool viewportEventInner(QEvent *e);
|
||||
QVariant loadResource(int type, const QUrl &name);
|
||||
void handleTouchEvent(QTouchEvent *e);
|
||||
|
||||
void updatePalette();
|
||||
|
Loading…
Reference in New Issue
Block a user