optimized emoji insertion

This commit is contained in:
John Preston 2015-07-13 13:45:09 +03:00
parent 5a38cb4581
commit afa28e9754
2 changed files with 36 additions and 11 deletions

View File

@ -174,7 +174,10 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
if (!text.isEmpty()) {
QTextCharFormat format = fragment.charFormat();
return emojiFromUrl(static_cast<const QTextImageFormat*>(&format)->name());
QString imageName = static_cast<QTextImageFormat*>(&format)->name();
if (imageName.startsWith(qstr("emoji://e."))) {
return emojiFromUrl(imageName);
}
}
return 0;
}
@ -530,17 +533,25 @@ void FlatTextarea::insertFromMimeData(const QMimeData *source) {
}
void FlatTextarea::insertEmoji(EmojiPtr emoji, QTextCursor c) {
c.removeSelectedText();
QPixmap img(App::emojiSingle(emoji, _st.font->height));
QString url = qsl("emoji://e.") + QString::number(emojiKey(emoji), 16);
document()->addResource(QTextDocument::ImageResource, QUrl(url), QVariant(img));
QTextImageFormat imageFormat;
imageFormat.setWidth(img.width() / cIntRetinaFactor());
imageFormat.setHeight(img.height() / cIntRetinaFactor());
imageFormat.setName(url);
int32 ew = ESize + st::emojiPadding * cIntRetinaFactor() * 2, eh = _st.font->height * cIntRetinaFactor();
imageFormat.setWidth(ew / cIntRetinaFactor());
imageFormat.setHeight(eh / cIntRetinaFactor());
imageFormat.setName(qsl("emoji://e.") + QString::number(emojiKey(emoji), 16));
imageFormat.setVerticalAlignment(QTextCharFormat::AlignBaseline);
c.insertImage(imageFormat);
static QString objectReplacement(QChar::ObjectReplacementCharacter);
c.insertText(objectReplacement, imageFormat);
}
QVariant FlatTextarea::loadResource(int type, const QUrl &name) {
QString imageName = name.toDisplayString();
if (imageName.startsWith(qstr("emoji://e."))) {
if (EmojiPtr emoji = emojiFromUrl(imageName)) {
return QVariant(App::emojiSingle(emoji, _st.font->height));
}
}
return QVariant();
}
void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
@ -579,6 +590,10 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
if (emoji) break;
}
if (emoji) {
if (!document()->pageSize().isNull()) {
document()->setPageSize(QSizeF(0, 0));
}
QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
int32 removedUpto = c.position();
@ -608,6 +623,8 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
}
void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int charsAdded) {
if (_replacingEmojis) return;
if (!_links.isEmpty()) {
bool changed = false;
for (LinkRanges::iterator i = _links.begin(); i != _links.end();) {
@ -624,7 +641,7 @@ void FlatTextarea::onDocumentContentsChange(int position, int charsRemoved, int
if (changed) emit linksChanged();
}
if (_replacingEmojis || document()->availableRedoSteps() > 0) return;
if (document()->availableRedoSteps() > 0) return;
const int takeBack = 3;
@ -647,6 +664,8 @@ void FlatTextarea::onDocumentContentsChanged() {
_insertions.clear();
} else {
_replacingEmojis = true;
QSizeF s = document()->pageSize();
do {
Insertion i = _insertions.front();
_insertions.pop_front();
@ -654,6 +673,10 @@ void FlatTextarea::onDocumentContentsChanged() {
processDocumentContentsChange(i.first, i.second);
}
} while (!_insertions.isEmpty());
if (document()->pageSize() != s) {
document()->setPageSize(s);
}
_replacingEmojis = false;
}
}

View File

@ -103,6 +103,8 @@ protected:
return QTextEdit::leaveEvent(e);
}
QVariant loadResource(int type, const QUrl &name);
private:
void getSingleEmojiFragment(QString &text, QTextFragment &fragment) const;