Merge branch 'emojis' into dev
|
@ -515,7 +515,7 @@
|
|||
6DB9C3763D02B1415CD9D565 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
LastUpgradeCheck = 0630;
|
||||
};
|
||||
buildConfigurationList = DAC4C1AA5EDEA1C85E9CA5E6 /* Build configuration list for PBXProject "MetaEmoji" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
|
@ -589,6 +589,7 @@
|
|||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
|
@ -677,6 +678,7 @@
|
|||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
|
|
|
@ -420,6 +420,16 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
|||
"lng_media_video" = "Video file";
|
||||
"lng_media_audio" = "Voice message";
|
||||
|
||||
"lng_emoji_category0" = "Frequently used";
|
||||
"lng_emoji_category1" = "People";
|
||||
"lng_emoji_category2" = "Nature";
|
||||
"lng_emoji_category3" = "Food & Drink";
|
||||
"lng_emoji_category4" = "Celebration";
|
||||
"lng_emoji_category5" = "Activity";
|
||||
"lng_emoji_category6" = "Travel & Places";
|
||||
"lng_emoji_category7" = "Objects & Symbols";
|
||||
"lng_emoji_category8" = "Stickers";
|
||||
|
||||
"lng_in_dlg_photo" = "Photo";
|
||||
"lng_in_dlg_video" = "Video";
|
||||
"lng_in_dlg_contact" = "Contact";
|
||||
|
|
|
@ -21,7 +21,6 @@ semibold: 'Open Sans Semibold';
|
|||
fsize: 13px;
|
||||
|
||||
spriteFile: ':/gui/art/sprite.png' / 2:':/gui/art/sprite_125x.png' / 3:':/gui/art/sprite_150x.png' / 4:':/gui/art/sprite_200x.png';
|
||||
emojisFile: ':/gui/art/emoji.png' / 2:':/gui/art/emoji_125x.png' / 3:':/gui/art/emoji_150x.png' / 4:':/gui/art/emoji_200x.png';
|
||||
emojiImgSize: 18px; // exceptional value for retina
|
||||
emojiSize: 18px;
|
||||
emojiPadding: 0px;
|
||||
|
@ -123,9 +122,9 @@ sysUnlock: sysButton(sysUpd) {
|
|||
img: sprite(207px, 22px, 19px, 19px);
|
||||
}
|
||||
titleBackButton: iconedButton(btnDefIconed) {
|
||||
icon: sprite(133px, 197px, 13px, 20px);
|
||||
icon: sprite(113px, 108px, 13px, 20px);
|
||||
iconPos: point(5px, 9px);
|
||||
downIcon: sprite(133px, 197px, 13px, 20px);
|
||||
downIcon: sprite(113px, 108px, 13px, 20px);
|
||||
downIconPos: point(5px, 10px);
|
||||
|
||||
bgColor: #c4d8e9;
|
||||
|
@ -998,7 +997,7 @@ replyHeight: 49px;
|
|||
replyTop: 8px;
|
||||
replyBottom: 6px;
|
||||
replyIconPos: point(13px, 13px);
|
||||
replyIcon: sprite(174px, 195px, 24px, 24px);
|
||||
replyIcon: sprite(343px, 197px, 24px, 24px);
|
||||
replyCancel: iconedButton(btnDefIconed) {
|
||||
icon: sprite(165px, 24px, 14px, 14px);
|
||||
iconPos: point(17px, 17px);
|
||||
|
@ -1009,7 +1008,7 @@ replyCancel: iconedButton(btnDefIconed) {
|
|||
width: 49px;
|
||||
height: 49px;
|
||||
}
|
||||
forwardIcon: sprite(368px, 173px, 24px, 24px);
|
||||
forwardIcon: sprite(368px, 197px, 24px, 24px);
|
||||
|
||||
historyScroll: flatScroll(scrollDef) {
|
||||
barColor: #89a0b47a;
|
||||
|
@ -1460,33 +1459,39 @@ emojiScroll: flatScroll(scrollDef) {
|
|||
topsh: 0px;
|
||||
bottomsh: 0px;
|
||||
}
|
||||
emojiRecentActive: sprite(290px, 287px, 20px, 20px);
|
||||
emojiRecentOver: sprite(311px, 287px, 20px, 20px);
|
||||
emojiRecent: sprite(6px, 197px, 20px, 20px);
|
||||
emojiPeopleActive: sprite(290px, 221px, 20px, 20px);
|
||||
emojiPeopleOver: sprite(311px, 221px, 20px, 20px);
|
||||
emojiRecentOver: sprite(290px, 221px, 20px, 20px);
|
||||
emojiRecentActive: sprite(290px, 242px, 20px, 20px);
|
||||
emojiPeople: sprite(27px, 197px, 20px, 20px);
|
||||
emojiNatureActive: sprite(245px, 266px, 20px, 20px);
|
||||
emojiNatureOver: sprite(266px, 266px, 20px, 20px);
|
||||
emojiPeopleOver: sprite(311px, 221px, 20px, 20px);
|
||||
emojiPeopleActive: sprite(311px, 242px, 20px, 20px);
|
||||
emojiNature: sprite(48px, 197px, 20px, 20px);
|
||||
emojiObjectsActive: sprite(290px, 242px, 20px, 20px);
|
||||
emojiObjectsOver: sprite(311px, 242px, 20px, 20px);
|
||||
emojiObjects: sprite(69px, 197px, 20px, 20px);
|
||||
emojiPlacesActive: sprite(245px, 287px, 20px, 20px);
|
||||
emojiPlacesOver: sprite(266px, 287px, 20px, 20px);
|
||||
emojiPlaces: sprite(90px, 197px, 20px, 20px);
|
||||
emojiSymbolsActive: sprite(290px, 266px, 20px, 20px);
|
||||
emojiSymbolsOver: sprite(311px, 266px, 20px, 20px);
|
||||
emojiSymbols: sprite(111px, 197px, 20px, 20px);
|
||||
emojiStickersActive: sprite(311px, 308px, 20px, 20px);
|
||||
emojiStickersOver: sprite(354px, 200px, 20px, 20px);
|
||||
emojiStickers: sprite(375px, 200px, 20px, 20px);
|
||||
emojiNatureOver: sprite(245px, 266px, 20px, 20px);
|
||||
emojiNatureActive: sprite(245px, 287px, 20px, 20px);
|
||||
emojiFood: sprite(69px, 197px, 20px, 20px);
|
||||
emojiFoodOver: sprite(266px, 266px, 20px, 20px);
|
||||
emojiFoodActive: sprite(266px, 287px, 20px, 20px);
|
||||
emojiCelebration: sprite(90px, 197px, 20px, 20px);
|
||||
emojiCelebrationOver: sprite(290px, 266px, 20px, 20px);
|
||||
emojiCelebrationActive: sprite(290px, 287px, 20px, 20px);
|
||||
emojiActivity: sprite(111px, 197px, 20px, 20px);
|
||||
emojiActivityOver: sprite(311px, 266px, 20px, 20px);
|
||||
emojiActivityActive: sprite(311px, 287px, 20px, 20px);
|
||||
emojiTravel: sprite(132px, 197px, 20px, 20px);
|
||||
emojiTravelOver: sprite(321px, 344px, 20px, 20px);
|
||||
emojiTravelActive: sprite(321px, 365px, 20px, 20px);
|
||||
emojiObjects: sprite(153px, 197px, 20px, 20px);
|
||||
emojiObjectsOver: sprite(342px, 344px, 20px, 20px);
|
||||
emojiObjectsActive: sprite(342px, 365px, 20px, 20px);
|
||||
emojiStickers: sprite(174px, 197px, 20px, 20px);
|
||||
emojiStickersOver: sprite(363px, 344px, 20px, 20px);
|
||||
emojiStickersActive: sprite(363px, 365px, 20px, 20px);
|
||||
rbEmoji: flatCheckbox {
|
||||
textColor: transparent;
|
||||
bgColor: transparent;
|
||||
disColor: transparent;
|
||||
|
||||
width: 29px;
|
||||
width: 28px;
|
||||
height: 36px;
|
||||
|
||||
textTop: 0px;
|
||||
|
@ -1523,6 +1528,38 @@ rbEmojiNature: flatCheckbox(rbEmoji) {
|
|||
disImageRect: emojiNature;
|
||||
chkDisImageRect: emojiNatureActive;
|
||||
}
|
||||
rbEmojiFood: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiFood;
|
||||
chkImageRect: emojiFoodActive;
|
||||
overImageRect: emojiFoodOver;
|
||||
chkOverImageRect: emojiFoodActive;
|
||||
disImageRect: emojiFood;
|
||||
chkDisImageRect: emojiFoodActive;
|
||||
}
|
||||
rbEmojiCelebration: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiCelebration;
|
||||
chkImageRect: emojiCelebrationActive;
|
||||
overImageRect: emojiCelebrationOver;
|
||||
chkOverImageRect: emojiCelebrationActive;
|
||||
disImageRect: emojiCelebration;
|
||||
chkDisImageRect: emojiCelebrationActive;
|
||||
}
|
||||
rbEmojiActivity: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiActivity;
|
||||
chkImageRect: emojiActivityActive;
|
||||
overImageRect: emojiActivityOver;
|
||||
chkOverImageRect: emojiActivityActive;
|
||||
disImageRect: emojiActivity;
|
||||
chkDisImageRect: emojiActivityActive;
|
||||
}
|
||||
rbEmojiTravel: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiTravel;
|
||||
chkImageRect: emojiTravelActive;
|
||||
overImageRect: emojiTravelOver;
|
||||
chkOverImageRect: emojiTravelActive;
|
||||
disImageRect: emojiTravel;
|
||||
chkDisImageRect: emojiTravelActive;
|
||||
}
|
||||
rbEmojiObjects: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiObjects;
|
||||
chkImageRect: emojiObjectsActive;
|
||||
|
@ -1531,22 +1568,6 @@ rbEmojiObjects: flatCheckbox(rbEmoji) {
|
|||
disImageRect: emojiObjects;
|
||||
chkDisImageRect: emojiObjectsActive;
|
||||
}
|
||||
rbEmojiPlaces: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiPlaces;
|
||||
chkImageRect: emojiPlacesActive;
|
||||
overImageRect: emojiPlacesOver;
|
||||
chkOverImageRect: emojiPlacesActive;
|
||||
disImageRect: emojiPlaces;
|
||||
chkDisImageRect: emojiPlacesActive;
|
||||
}
|
||||
rbEmojiSymbols: flatCheckbox(rbEmoji) {
|
||||
imageRect: emojiSymbols;
|
||||
chkImageRect: emojiSymbolsActive;
|
||||
overImageRect: emojiSymbolsOver;
|
||||
chkOverImageRect: emojiSymbolsActive;
|
||||
disImageRect: emojiSymbols;
|
||||
chkDisImageRect: emojiSymbolsActive;
|
||||
}
|
||||
rbEmojiStickers: flatCheckbox(rbEmojiRecent) {
|
||||
imageRect: emojiStickers;
|
||||
chkImageRect: emojiStickersActive;
|
||||
|
@ -1556,15 +1577,25 @@ rbEmojiStickers: flatCheckbox(rbEmojiRecent) {
|
|||
chkDisImageRect: emojiStickersActive;
|
||||
}
|
||||
emojiPanPadding: margins(5px, 0px, 0px, 5px);
|
||||
emojiPanSize: size(28px, 28px);
|
||||
emojiPanSub: 0px;
|
||||
emojiPanSize: size(35px, 35px);
|
||||
emojiPanDuration: 200;
|
||||
emojiPanHover: #f0f0f0;
|
||||
emojiPanRound: 2px;
|
||||
|
||||
emojiPanHeader: 25px;
|
||||
emojiPanHeaderFont: font(fsize semibold);
|
||||
emojiPanHeaderColor: #999;
|
||||
emojiPanHeaderLeft: 5px;
|
||||
emojiPanHeaderTop: 5px;
|
||||
emojiPanHeaderBg: #fffd;
|
||||
|
||||
emojiColorsPadding: 5px;
|
||||
emojiColorsSep: 1px;
|
||||
emojiColorsSepColor: #d5d5d5;
|
||||
|
||||
stickerPanRound: 3px;
|
||||
stickerPanPadding: 2px;
|
||||
stickerPanDelete: sprite(158px, 197px, 12px, 12px);
|
||||
stickerPanDelete: sprite(123px, 132px, 12px, 12px);
|
||||
stickerPanDeleteOpacity: 0.5;
|
||||
|
||||
mvBgColor: #222;
|
||||
|
@ -1654,7 +1685,7 @@ mvDocLink: linkButton(btnDefLink) {
|
|||
mvDeltaFromLastAction: 5px;
|
||||
mvSwipeDistance: 80px;
|
||||
|
||||
medviewSaveMsgCheck: sprite(341px, 174px, 22px, 18px);
|
||||
medviewSaveMsgCheck: sprite(311px, 309px, 22px, 18px);
|
||||
medviewSaveMsgFont: font(16px);
|
||||
medviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
|
||||
medviewSaveMsgCheckPos: point(23px, 21px);
|
||||
|
@ -1664,7 +1695,7 @@ medviewSaveMsgShown: 2000;
|
|||
medviewSaveMsgHiding: 2500;
|
||||
medviewSaveMsg: #000000b2;
|
||||
|
||||
mvTransparentBrush: sprite(148px, 197px, 8px, 8px);
|
||||
mvTransparentBrush: sprite(113px, 128px, 8px, 8px);
|
||||
|
||||
overviewPhotoSkip: 10px;
|
||||
overviewPhotoMinSize: 100px;
|
||||
|
|
|
@ -132,7 +132,7 @@ int main(int argc, const char * argv[]) {
|
|||
}
|
||||
|
||||
if (update) {
|
||||
writeLog(@"Starting update files iteration!");
|
||||
writeLog([@"Starting update files iteration, path: " stringByAppendingString: [workDir stringByAppendingString:@"tupdates/ready"]]);
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *srcDir = [workDir stringByAppendingString:@"tupdates/ready/"];
|
||||
|
@ -142,6 +142,7 @@ int main(int argc, const char * argv[]) {
|
|||
includingPropertiesForKeys:keys
|
||||
options:0
|
||||
errorHandler:^(NSURL *url, NSError *error) {
|
||||
writeLog([[[@"Error in enumerating " stringByAppendingString:[url absoluteString]] stringByAppendingString: @" error is: "] stringByAppendingString: [error description]]);
|
||||
return NO;
|
||||
}];
|
||||
for (NSURL *url in enumerator) {
|
||||
|
|
|
@ -73,9 +73,9 @@ namespace {
|
|||
|
||||
HistoryItem *hoveredItem = 0, *pressedItem = 0, *hoveredLinkItem = 0, *pressedLinkItem = 0, *contextItem = 0, *mousedItem = 0;
|
||||
|
||||
QPixmap *sprite = 0, *emojis = 0;
|
||||
QPixmap *sprite = 0, *emojis = 0, *emojisLarge = 0;
|
||||
|
||||
typedef QMap<uint32, QPixmap> EmojisMap;
|
||||
typedef QMap<uint64, QPixmap> EmojisMap;
|
||||
EmojisMap mainEmojisMap;
|
||||
QMap<int32, EmojisMap> otherEmojisMap;
|
||||
|
||||
|
@ -1528,11 +1528,15 @@ namespace App {
|
|||
}
|
||||
if (cRetina()) ::sprite->setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
emojiInit();
|
||||
if (!::emojis) {
|
||||
::emojis = new QPixmap(st::emojisFile);
|
||||
::emojis = new QPixmap(QLatin1String(EName));
|
||||
if (cRetina()) ::emojis->setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
initEmoji();
|
||||
if (!::emojisLarge) {
|
||||
::emojisLarge = new QPixmap(QLatin1String(EmojiNames[EIndex + 1]));
|
||||
if (cRetina()) ::emojisLarge->setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
}
|
||||
|
||||
void deinitMedia(bool completely) {
|
||||
|
@ -1548,6 +1552,8 @@ namespace App {
|
|||
::sprite = 0;
|
||||
delete ::emojis;
|
||||
::emojis = 0;
|
||||
delete ::emojisLarge;
|
||||
::emojisLarge = 0;
|
||||
mainEmojisMap.clear();
|
||||
otherEmojisMap.clear();
|
||||
|
||||
|
@ -1616,19 +1622,25 @@ namespace App {
|
|||
return *::emojis;
|
||||
}
|
||||
|
||||
const QPixmap &emojiSingle(const EmojiData *emoji, int32 fontHeight) {
|
||||
const QPixmap &emojisLarge() {
|
||||
return *::emojisLarge;
|
||||
}
|
||||
|
||||
const QPixmap &emojiSingle(EmojiPtr emoji, int32 fontHeight) {
|
||||
EmojisMap *map = &(fontHeight == st::taDefFlat.font->height ? mainEmojisMap : otherEmojisMap[fontHeight]);
|
||||
EmojisMap::const_iterator i = map->constFind(emoji->code);
|
||||
EmojisMap::const_iterator i = map->constFind(emojiKey(emoji));
|
||||
if (i == map->cend()) {
|
||||
QImage img(st::emojiImgSize + st::emojiPadding * cIntRetinaFactor() * 2, fontHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
QImage img(ESize + st::emojiPadding * cIntRetinaFactor() * 2, fontHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
if (cRetina()) img.setDevicePixelRatio(cRetinaFactor());
|
||||
{
|
||||
QPainter p(&img);
|
||||
QPainter::CompositionMode m = p.compositionMode();
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(0, 0, img.width(), img.height(), Qt::transparent);
|
||||
p.drawPixmap(QPoint(st::emojiPadding * cIntRetinaFactor(), (fontHeight * cIntRetinaFactor() - st::emojiImgSize) / 2), App::emojis(), QRect(emoji->x, emoji->y, st::emojiImgSize, st::emojiImgSize));
|
||||
p.setCompositionMode(m);
|
||||
emojiDraw(p, emoji, st::emojiPadding * cIntRetinaFactor(), (fontHeight * cIntRetinaFactor() - ESize) / 2);
|
||||
}
|
||||
i = map->insert(emoji->code, QPixmap::fromImage(img, Qt::ColorOnly));
|
||||
i = map->insert(emojiKey(emoji), QPixmap::fromImage(img, Qt::ColorOnly));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
|
|
|
@ -156,7 +156,8 @@ namespace App {
|
|||
|
||||
const QPixmap &sprite();
|
||||
const QPixmap &emojis();
|
||||
const QPixmap &emojiSingle(const EmojiData *emoji, int32 fontHeight);
|
||||
const QPixmap &emojisLarge();
|
||||
const QPixmap &emojiSingle(EmojiPtr emoji, int32 fontHeight);
|
||||
|
||||
void initMedia();
|
||||
void deinitMedia(bool completely = true);
|
||||
|
|
Before Width: | Height: | Size: 528 KiB |
BIN
Telegram/SourceFiles/art/emoji.webp
Normal file
After Width: | Height: | Size: 684 KiB |
Before Width: | Height: | Size: 722 KiB |
BIN
Telegram/SourceFiles/art/emoji_125x.webp
Normal file
After Width: | Height: | Size: 947 KiB |
Before Width: | Height: | Size: 1,003 KiB |
BIN
Telegram/SourceFiles/art/emoji_150x.webp
Normal file
After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 1.5 MiB |
BIN
Telegram/SourceFiles/art/emoji_200x.webp
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
Telegram/SourceFiles/art/emoji_250x.webp
Normal file
After Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 722 KiB |
Before Width: | Height: | Size: 531 KiB |
Before Width: | Height: | Size: 956 KiB |
Before Width: | Height: | Size: 402 KiB |
Before Width: | Height: | Size: 532 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 219 KiB |
|
@ -84,7 +84,7 @@ void EmojiBox::fillBlocks() {
|
|||
BlockRow currentRow;
|
||||
currentRow.reserve(replacesInRow);
|
||||
for (uint32 i = 0; i < replacesCount; ++i) {
|
||||
Block block(getEmoji(replaces[i].code), QString::fromUtf8(replaces[i].replace));
|
||||
Block block(emojiGet(replaces[i].code), QString::fromUtf8(replaces[i].replace));
|
||||
currentRow.push_back(block);
|
||||
if (uint32(currentRow.size()) == replacesInRow) {
|
||||
_blocks.push_back(currentRow);
|
||||
|
@ -125,8 +125,7 @@ void EmojiBox::paintEvent(QPaintEvent *e) {
|
|||
int32 rowSize = i->size(), left = (width() - rowSize * st::emojiReplaceWidth) / 2;
|
||||
for (BlockRow::const_iterator j = i->cbegin(), en = i->cend(); j != en; ++j) {
|
||||
if (j->emoji) {
|
||||
QPoint pos(left + (st::emojiReplaceWidth - st::emojiSize) / 2, top + (st::emojiReplaceHeight - _blockHeight) / 2);
|
||||
p.drawPixmap(pos, App::emojis(), QRect(j->emoji->x, j->emoji->y, st::emojiImgSize, st::emojiImgSize));
|
||||
emojiDraw(p, j->emoji, left + (st::emojiReplaceWidth - st::emojiSize) / 2, top + (st::emojiReplaceHeight - _blockHeight) / 2);
|
||||
}
|
||||
QRect trect(left, top + (st::emojiReplaceHeight + _blockHeight) / 2 - st::emojiTextFont->height, st::emojiReplaceWidth, st::emojiTextFont->height);
|
||||
p.drawText(trect, j->text, QTextOption(Qt::AlignHCenter | Qt::AlignTop));
|
||||
|
|
|
@ -132,7 +132,68 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class EmojiPanInner : public QWidget, public Animated {
|
||||
static const int EmojiColorsCount = 5;
|
||||
|
||||
class EmojiColorPicker : public TWidget, public Animated {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiColorPicker(QWidget *parent);
|
||||
|
||||
void showEmoji(uint32 code);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void showStart();
|
||||
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
public slots:
|
||||
|
||||
void hideStart(bool fast = false);
|
||||
|
||||
signals:
|
||||
|
||||
void emojiSelected(EmojiPtr emoji);
|
||||
void hidden();
|
||||
|
||||
private:
|
||||
|
||||
void drawVariant(Painter &p, int variant);
|
||||
|
||||
void updateSelected();
|
||||
|
||||
bool _ignoreShow;
|
||||
|
||||
EmojiPtr _variants[EmojiColorsCount + 1];
|
||||
|
||||
typedef QMap<int32, uint64> EmojiAnimations; // index - showing, -index - hiding
|
||||
EmojiAnimations _emojiAnimations;
|
||||
|
||||
float64 _hovers[EmojiColorsCount + 1];
|
||||
|
||||
int32 _selected, _pressedSel;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
bool _hiding;
|
||||
QPixmap _cache;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
|
||||
QTimer _hideTimer;
|
||||
|
||||
BoxShadow _shadow;
|
||||
|
||||
};
|
||||
|
||||
class EmojiPanInner : public TWidget, public Animated {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -145,39 +206,67 @@ public:
|
|||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void leaveToChildEvent(QEvent *e);
|
||||
void enterFromChildEvent(QEvent *e);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void hideFinish();
|
||||
|
||||
void showEmojiPack(DBIEmojiTab packIndex);
|
||||
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
DBIEmojiTab currentTab(int yOffset) const;
|
||||
|
||||
void refreshStickers();
|
||||
void refreshRecent();
|
||||
|
||||
void setScrollTop(int top);
|
||||
|
||||
public slots:
|
||||
|
||||
void updateSelected();
|
||||
void onSaveConfig();
|
||||
|
||||
void onShowPicker();
|
||||
void onPickerHidden();
|
||||
void onColorSelected(EmojiPtr emoji);
|
||||
|
||||
signals:
|
||||
|
||||
void emojiSelected(EmojiPtr emoji);
|
||||
void stickerSelected(DocumentData *sticker);
|
||||
|
||||
void scrollToY(int y);
|
||||
void disableScroll(bool dis);
|
||||
|
||||
private:
|
||||
|
||||
int countHeight();
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
|
||||
typedef QMap<int32, uint64> EmojiAnimations; // index - showing, -index - hiding
|
||||
EmojiAnimations _emojiAnimations;
|
||||
|
||||
int _top;
|
||||
int _counts[emojiTabCount], _count;
|
||||
|
||||
StickerPack _stickers;
|
||||
QVector<bool> _isUserGen;
|
||||
QVector<EmojiPtr> _emojis;
|
||||
QVector<float64> _hovers;
|
||||
QVector<EmojiPtr> _emojis[emojiTabCount];
|
||||
QVector<float64> _hovers[emojiTabCount + 1]; // + stickers hovers and stickers-x hovers
|
||||
|
||||
DBIEmojiTab _tab;
|
||||
int32 _selected, _xSelected, _pressedSel, _xPressedSel;
|
||||
float64 _stickerWidth;
|
||||
int32 _esize, _stickerSize;
|
||||
|
||||
int32 _selected, _pressedSel, _pickerSel;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
QTimer _saveConfigTimer;
|
||||
|
||||
EmojiColorPicker _picker;
|
||||
QTimer _showPickerTimer;
|
||||
|
||||
};
|
||||
|
||||
class EmojiPan : public TWidget, public Animated {
|
||||
|
@ -203,6 +292,8 @@ public:
|
|||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
|
||||
void refreshStickers();
|
||||
|
||||
public slots:
|
||||
|
||||
void hideStart();
|
||||
|
@ -212,6 +303,7 @@ public slots:
|
|||
void onWndActiveChanged();
|
||||
|
||||
void onTabChange();
|
||||
void onScroll();
|
||||
|
||||
signals:
|
||||
|
||||
|
@ -224,6 +316,8 @@ private:
|
|||
void showAll();
|
||||
void hideAll();
|
||||
|
||||
bool _noTabUpdate;
|
||||
|
||||
int32 _width, _height;
|
||||
bool _hiding;
|
||||
QPixmap _cache;
|
||||
|
@ -234,7 +328,7 @@ private:
|
|||
|
||||
BoxShadow _shadow;
|
||||
|
||||
FlatRadiobutton _recent, _people, _nature, _objects, _places, _symbols, _stickers;
|
||||
FlatRadiobutton _recent, _people, _nature, _food, _celebration, _activity, _travel, _objects, _stickers;
|
||||
|
||||
int32 _emojiPack;
|
||||
ScrollArea _scroll;
|
||||
|
|
|
@ -19,10 +19,94 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "gui/text.h"
|
||||
|
||||
void initEmoji();
|
||||
EmojiPtr getEmoji(uint32 code);
|
||||
void emojiInit();
|
||||
EmojiPtr emojiGet(uint32 code);
|
||||
EmojiPtr emojiGet(uint32 code, uint32 code2);
|
||||
EmojiPtr emojiGet(EmojiPtr emoji, uint32 color);
|
||||
EmojiPtr emojiGet(const QChar *from, const QChar *end);
|
||||
QString emojiGetSequence(int index);
|
||||
|
||||
void findEmoji(const QChar *ch, const QChar *e, const QChar *&newEmojiEnd, uint32 &emojiCode);
|
||||
inline uint64 emojiKey(EmojiPtr emoji) {
|
||||
uint64 key = emoji->code;
|
||||
if (emoji->code2) {
|
||||
key = (key << 32) | uint64(emoji->code2);
|
||||
} else if (emoji->color && ((emoji->color & 0xFFFF0000U) != 0xFFFF0000U)) {
|
||||
key = (key << 32) | uint64(emoji->color);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
inline EmojiPtr emojiFromKey(uint64 key) {
|
||||
uint32 code = uint32(key >> 32), code2 = uint32(key & 0xFFFFFFFFLLU);
|
||||
if (!code && code2) {
|
||||
code = code2;
|
||||
code2 = 0;
|
||||
}
|
||||
EmojiPtr emoji = emojiGet(code);
|
||||
if (emoji == TwoSymbolEmoji) {
|
||||
return emojiGet(code, code2);
|
||||
} else if (emoji && emoji->color && code2) {
|
||||
return emojiGet(emoji, code2);
|
||||
}
|
||||
return emoji;
|
||||
}
|
||||
|
||||
inline EmojiPtr emojiFromUrl(const QString &url) {
|
||||
return emojiFromKey(url.midRef(10).toULongLong(0, 16)); // skip emoji://e.
|
||||
}
|
||||
|
||||
inline EmojiPtr emojiFromText(const QChar *ch, const QChar *e, int &len) {
|
||||
QString tmp(ch, e - ch);
|
||||
QByteArray tmp2 = tmp.toUtf8();
|
||||
const char *tmp3 = tmp2.constData();
|
||||
EmojiPtr emoji = 0;
|
||||
if (ch + 1 < e && ((ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) || (((ch->unicode() >= 48 && ch->unicode() < 58) || ch->unicode() == 35) && (ch + 1)->unicode() == 0x20E3))) {
|
||||
uint32 code = (ch->unicode() << 16) | (ch + 1)->unicode();
|
||||
emoji = emojiGet(code);
|
||||
if (emoji) {
|
||||
if (emoji == TwoSymbolEmoji) { // check two symbol
|
||||
if (ch + 3 >= e) {
|
||||
emoji = 0;
|
||||
} else {
|
||||
uint32 code2 = ((uint32((ch + 2)->unicode()) << 16) | uint32((ch + 3)->unicode()));
|
||||
emoji = emojiGet(code, code2);
|
||||
}
|
||||
} else {
|
||||
if (ch + 2 < e && (ch + 2)->unicode() == 0x200D) { // check sequence
|
||||
EmojiPtr seq = emojiGet(ch, e);
|
||||
if (seq) {
|
||||
emoji = seq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ch < e) {
|
||||
emoji = emojiGet(ch->unicode());
|
||||
Q_ASSERT(emoji != TwoSymbolEmoji);
|
||||
}
|
||||
|
||||
if (emoji) {
|
||||
len = emoji->len + ((ch + emoji->len < e && (ch + emoji->len)->unicode() == 0xFE0F) ? 1 : 0);
|
||||
if (emoji->color && (ch + len + 1 < e && (ch + len)->isHighSurrogate() && (ch + len + 1)->isLowSurrogate())) { // color
|
||||
uint32 color = ((uint32((ch + len)->unicode()) << 16) | uint32((ch + len + 1)->unicode()));
|
||||
EmojiPtr col = emojiGet(emoji, color);
|
||||
if (col && col != emoji) {
|
||||
len += col->len - emoji->len;
|
||||
emoji = col;
|
||||
if (ch + len < e && (ch + len)->unicode() == 0xFE0F) {
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return emoji;
|
||||
}
|
||||
|
||||
extern int EmojiSizes[5], EIndex, ESize;
|
||||
extern const char *EmojiNames[5], *EName;
|
||||
|
||||
void emojiFind(const QChar *ch, const QChar *e, const QChar *&newEmojiEnd, uint32 &emojiCode);
|
||||
|
||||
inline bool emojiEdge(const QChar *ch) {
|
||||
return true;
|
||||
|
@ -48,7 +132,7 @@ inline QString replaceEmojis(const QString &text) {
|
|||
uint32 emojiCode = 0;
|
||||
const QChar *newEmojiEnd = 0;
|
||||
if (canFindEmoji) {
|
||||
findEmoji(ch, e, newEmojiEnd, emojiCode);
|
||||
emojiFind(ch, e, newEmojiEnd, emojiCode);
|
||||
}
|
||||
|
||||
while (currentLink < lnkCount && ch >= lnkRanges[currentLink].from + lnkRanges[currentLink].len) {
|
||||
|
@ -91,4 +175,5 @@ inline QString replaceEmojis(const QString &text) {
|
|||
return result;
|
||||
}
|
||||
|
||||
int emojiPackCount(DBIEmojiTab tab);
|
||||
EmojiPack emojiPack(DBIEmojiTab tab);
|
||||
|
|
|
@ -174,8 +174,7 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
|
|||
|
||||
if (!text.isEmpty()) {
|
||||
QTextCharFormat format = fragment.charFormat();
|
||||
QString imageName = static_cast<const QTextImageFormat*>(&format)->name();
|
||||
return getEmoji(imageName.mid(8).toUInt(0, 16));
|
||||
return emojiFromUrl(static_cast<const QTextImageFormat*>(&format)->name());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -288,7 +287,7 @@ void FlatTextarea::getSingleEmojiFragment(QString &text, QTextFragment &fragment
|
|||
}
|
||||
if (f.isImageFormat() && !t.isEmpty() && t.at(0).unicode() == QChar::ObjectReplacementCharacter) {
|
||||
QString imageName = static_cast<QTextImageFormat*>(&f)->name();
|
||||
if (imageName.midRef(0, 8) == qsl("emoji://")) {
|
||||
if (imageName.startsWith(QLatin1String("emoji://e."))) {
|
||||
fragment = fr;
|
||||
text = t;
|
||||
return;
|
||||
|
@ -372,10 +371,8 @@ QString FlatTextarea::getText(int32 start, int32 end) const {
|
|||
case QChar::ObjectReplacementCharacter:
|
||||
if (emojiText.isEmpty() && f.isImageFormat()) {
|
||||
QString imageName = static_cast<QTextImageFormat*>(&f)->name();
|
||||
if (imageName.midRef(0, 8) == qsl("emoji://")) {
|
||||
uint32 index = imageName.mid(8).toUInt(0, 16);
|
||||
const EmojiData *emoji = getEmoji(index);
|
||||
if (emoji) {
|
||||
if (imageName.startsWith(QLatin1String("emoji://e."))) {
|
||||
if (EmojiPtr emoji = emojiFromUrl(imageName)) {
|
||||
emojiText = textEmojiString(emoji);
|
||||
}
|
||||
}
|
||||
|
@ -520,7 +517,7 @@ void FlatTextarea::insertEmoji(EmojiPtr emoji, QTextCursor c) {
|
|||
c.removeSelectedText();
|
||||
|
||||
QPixmap img(App::emojiSingle(emoji, _st.font->height));
|
||||
QString url = qsl("emoji://") + QString::number(emoji->code, 16);
|
||||
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());
|
||||
|
@ -546,33 +543,20 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
|
|||
QTextFragment fragment(iter.fragment());
|
||||
if (!fragment.isValid()) continue;
|
||||
|
||||
int32 p = fragment.position(), e = p + fragment.length();
|
||||
if (p >= end || e <= start) {
|
||||
int32 fp = fragment.position(), fe = fp + fragment.length();
|
||||
if (fp >= end || fe <= start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString t(fragment.text());
|
||||
for (const QChar *ch = t.constData(), *e = ch + t.size(); ch != e; ++ch) {
|
||||
if (ch + 1 < e && (ch->isHighSurrogate() || (((ch->unicode() >= 48 && ch->unicode() < 58) || ch->unicode() == 35) && (ch + 1)->unicode() == 0x20E3))) {
|
||||
emoji = getEmoji((ch->unicode() << 16) | (ch + 1)->unicode());
|
||||
if (emoji) {
|
||||
if (emoji->len == 4 && (ch + 3 >= e || ((uint32((ch + 2)->unicode()) << 16) | uint32((ch + 3)->unicode())) != emoji->code2)) {
|
||||
emoji = 0;
|
||||
} else {
|
||||
emojiPosition = p + (ch - t.constData());
|
||||
emojiLen = emoji->len + ((ch + emoji->len < e && (ch + emoji->len)->unicode() == 0xFE0F) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++ch;
|
||||
} else {
|
||||
emoji = getEmoji(ch->unicode());
|
||||
if (emoji) {
|
||||
emojiPosition = p + (ch - t.constData());
|
||||
emojiLen = emoji->len + ((ch + emoji->len < e && (ch + emoji->len)->unicode() == 0xFE0F) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
const QChar *ch = t.constData(), *e = ch + t.size();
|
||||
for (; ch != e; ++ch) {
|
||||
emoji = emojiFromText(ch, e, emojiLen);
|
||||
if (emoji) {
|
||||
emojiPosition = fp + (ch - t.constData());
|
||||
break;
|
||||
}
|
||||
if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
|
||||
}
|
||||
if (emoji) break;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ void ScrollBar::updateBar(bool force) {
|
|||
}
|
||||
if (newBar != _bar) {
|
||||
_bar = newBar;
|
||||
update();
|
||||
parentWidget()->update(geometry());
|
||||
}
|
||||
if (_vertical) {
|
||||
bool newTopSh = (_st->topsh < 0) || (_area->scrollTop() > _st->topsh), newBottomSh = (_st->bottomsh < 0) || (_area->scrollTop() < _area->scrollTopMax() - _st->bottomsh);
|
||||
|
@ -143,7 +143,7 @@ bool ScrollBar::animStep(float64 ms) {
|
|||
a_bg.update(dt, anim::linear);
|
||||
a_bar.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
parentWidget()->update(geometry());
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -253,19 +253,16 @@ void ScrollBar::resizeEvent(QResizeEvent *e) {
|
|||
}
|
||||
|
||||
ScrollArea::ScrollArea(QWidget *parent, const style::flatScroll &st, bool handleTouch) : QScrollArea(parent),
|
||||
_st(st),
|
||||
_disabled(false), _st(st),
|
||||
hor(this, false, &_st), vert(this, true, &_st), topSh(this, &_st), bottomSh(this, &_st),
|
||||
_touchEnabled(handleTouch), _touchScroll(false), _touchPress(false), _touchRightButton(false),
|
||||
_touchScrollState(TouchScrollManual), _touchPrevPosValid(false), _touchWaitingAcceleration(false),
|
||||
_touchSpeedTime(0), _touchAccelerationTime(0), _touchTime(0), _widgetAcceptsTouch(false) {
|
||||
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SIGNAL(scrolled()));
|
||||
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SIGNAL(scrolled()));
|
||||
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onScrolled()));
|
||||
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onScrolled()));
|
||||
connect(&vert, SIGNAL(topShadowVisibility(bool)), &topSh, SLOT(changeVisibility(bool)));
|
||||
connect(&vert, SIGNAL(bottomShadowVisibility(bool)), &bottomSh, SLOT(changeVisibility(bool)));
|
||||
vert.updateBar(true);
|
||||
if (_st.hiding) {
|
||||
connect(this, SIGNAL(scrolled()), this, SLOT(onScrolled()));
|
||||
}
|
||||
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
@ -292,19 +289,31 @@ void ScrollArea::touchDeaccelerate(int32 elapsed) {
|
|||
}
|
||||
|
||||
void ScrollArea::onScrolled() {
|
||||
bool em = false;
|
||||
int32 horValue = horizontalScrollBar()->value(), vertValue = verticalScrollBar()->value();
|
||||
if (_horValue != horValue) {
|
||||
_horValue = horValue;
|
||||
if (_st.hiding) {
|
||||
hor.hideTimeout(_st.hiding);
|
||||
if (_disabled) {
|
||||
horizontalScrollBar()->setValue(_horValue);
|
||||
} else {
|
||||
_horValue = horValue;
|
||||
if (_st.hiding) {
|
||||
hor.hideTimeout(_st.hiding);
|
||||
}
|
||||
em = true;
|
||||
}
|
||||
}
|
||||
if (_vertValue != vertValue) {
|
||||
_vertValue = vertValue;
|
||||
if (_st.hiding) {
|
||||
vert.hideTimeout(_st.hiding);
|
||||
if (_disabled) {
|
||||
verticalScrollBar()->setValue(_vertValue);
|
||||
} else {
|
||||
_vertValue = vertValue;
|
||||
if (_st.hiding) {
|
||||
vert.hideTimeout(_st.hiding);
|
||||
}
|
||||
em = true;
|
||||
}
|
||||
}
|
||||
if (em) emit scrolled();
|
||||
}
|
||||
|
||||
int ScrollArea::scrollWidth() const {
|
||||
|
@ -528,6 +537,21 @@ void ScrollArea::touchScrollUpdated(const QPoint &screenPos) {
|
|||
touchUpdateSpeed();
|
||||
}
|
||||
|
||||
void ScrollArea::disableScroll(bool dis) {
|
||||
_disabled = dis;
|
||||
if (_disabled) {
|
||||
hor.hideTimeout(0);
|
||||
vert.hideTimeout(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollArea::scrollContentsBy(int dx, int dy) {
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
QScrollArea::scrollContentsBy(dx, dy);
|
||||
}
|
||||
|
||||
bool ScrollArea::touchScroll(const QPoint &delta) {
|
||||
int32 scTop = scrollTop(), scMax = scrollTopMax(), scNew = snap(scTop - delta.y(), 0, scMax);
|
||||
if (scNew == scTop) return false;
|
||||
|
@ -559,6 +583,7 @@ void ScrollArea::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
|
||||
void ScrollArea::enterEvent(QEvent *e) {
|
||||
if (_disabled) return;
|
||||
if (_st.hiding) {
|
||||
hor.hideTimeout(_st.hiding);
|
||||
vert.hideTimeout(_st.hiding);
|
||||
|
|
|
@ -134,6 +134,7 @@ public:
|
|||
public slots:
|
||||
|
||||
void scrollToY(int toTop, int toBottom = -1);
|
||||
void disableScroll(bool dis);
|
||||
void onScrolled();
|
||||
|
||||
void onTouchTimer();
|
||||
|
@ -146,6 +147,10 @@ signals:
|
|||
void scrollFinished();
|
||||
void geometryChanged();
|
||||
|
||||
protected:
|
||||
|
||||
void scrollContentsBy(int dx, int dy);
|
||||
|
||||
private:
|
||||
|
||||
bool touchScroll(const QPoint &delta);
|
||||
|
@ -156,6 +161,8 @@ private:
|
|||
void touchUpdateSpeed();
|
||||
void touchDeaccelerate(int32 elapsed);
|
||||
|
||||
bool _disabled;
|
||||
|
||||
style::flatScroll _st;
|
||||
ScrollBar hor, vert;
|
||||
ScrollShadow topSh, bottomSh;
|
||||
|
|
|
@ -240,20 +240,25 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink)
|
|||
}
|
||||
|
||||
QString textEmojiString(EmojiPtr emoji) {
|
||||
if ((emoji->code & 0xFFFF0000U) == 0xFFFF0000U) { // sequence
|
||||
return emojiGetSequence(emoji->code & 0xFFFFU);
|
||||
}
|
||||
|
||||
QString result;
|
||||
result.reserve(emoji->len + (emoji->postfix ? 1 : 0));
|
||||
switch (emoji->len) {
|
||||
case 1: result.append(QChar(emoji->code & 0xFFFF)); break;
|
||||
case 2:
|
||||
if (!(emoji->code >> 16)) {
|
||||
result.append(QChar(emoji->code & 0xFFFF));
|
||||
} else {
|
||||
result.append(QChar((emoji->code >> 16) & 0xFFFF));
|
||||
result.append(QChar(emoji->code & 0xFFFF));
|
||||
break;
|
||||
case 4:
|
||||
result.append(QChar((emoji->code >> 16) & 0xFFFF));
|
||||
result.append(QChar(emoji->code & 0xFFFF));
|
||||
result.append(QChar((emoji->code2 >> 16) & 0xFFFF));
|
||||
result.append(QChar(emoji->code2 & 0xFFFF));
|
||||
break;
|
||||
if (emoji->code2) {
|
||||
result.append(QChar((emoji->code2 >> 16) & 0xFFFF));
|
||||
result.append(QChar(emoji->code2 & 0xFFFF));
|
||||
}
|
||||
}
|
||||
if (emoji->color && ((emoji->color & 0xFFFF0000U) != 0xFFFF0000U)) {
|
||||
result.append(QChar((emoji->color >> 16) & 0xFFFF));
|
||||
result.append(QChar(emoji->color & 0xFFFF));
|
||||
}
|
||||
if (emoji->postfix) result.append(QChar(emoji->postfix));
|
||||
return result;
|
||||
|
@ -515,24 +520,15 @@ public:
|
|||
}
|
||||
|
||||
void parseEmojiFromCurrent() {
|
||||
const EmojiData *e = getEmoji(chInt);
|
||||
int len = 0, skipped = (chInt > 0xFFFFU) ? 1 : 0;
|
||||
EmojiPtr e = emojiFromText(ptr - skipped, end, len);
|
||||
if (!e) return;
|
||||
|
||||
if (e->len > 2) {
|
||||
if (ptr + 2 >= end || e->code2 != ((uint32((ptr + 1)->unicode()) << 16) | uint32((ptr + 2)->unicode()))) {
|
||||
return;
|
||||
} else {
|
||||
_t->_text.push_back(*++ptr);
|
||||
_t->_text.push_back(*++ptr);
|
||||
}
|
||||
}
|
||||
int emojiLen = e->len;
|
||||
if (ptr + 1 < end && (ptr + 1)->unicode() == 0xFE0F) {
|
||||
for (int l = len - skipped - 1; l > 0; --l) {
|
||||
_t->_text.push_back(*++ptr);
|
||||
++emojiLen;
|
||||
}
|
||||
|
||||
createBlock(-emojiLen);
|
||||
createBlock(-len);
|
||||
emoji = e;
|
||||
}
|
||||
|
||||
|
@ -1326,7 +1322,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
_p->drawPixmap(QPoint((glyphX + int(st::emojiPadding)).toInt(), _y + _yDelta + emojiY), App::emojis(), QRect(static_cast<EmojiBlock*>(currentBlock)->emoji->x, static_cast<EmojiBlock*>(currentBlock)->emoji->y, st::emojiImgSize, st::emojiImgSize));
|
||||
emojiDraw(*_p, static_cast<EmojiBlock*>(currentBlock)->emoji, (glyphX + int(st::emojiPadding)).toInt(), _y + _yDelta + emojiY);
|
||||
// } else if (_p && currentBlock->type() == TextBlockSkip) { // debug
|
||||
// _p->fillRect(QRect(x.toInt(), _y, currentBlock->width(), static_cast<SkipBlock*>(currentBlock)->height()), QColor(0, 0, 0, 32));
|
||||
}
|
||||
|
@ -4050,29 +4046,19 @@ bool textSplit(QString &sendingText, QString &leftText, int32 limit) {
|
|||
}
|
||||
}
|
||||
}
|
||||
EmojiPtr e = 0;
|
||||
if (ch->isHighSurrogate()) {
|
||||
if (ch + 1 < end && (ch + 1)->isLowSurrogate()) {
|
||||
e = getEmoji((ch->unicode() << 16) | (ch + 1)->unicode());
|
||||
if (!e) {
|
||||
++ch;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ch + 1 < end) {
|
||||
if (((ch->unicode() >= 48 && ch->unicode() < 58) || ch->unicode() == 35) && (ch + 1)->unicode() == 0x20E3) {
|
||||
e = getEmoji((ch->unicode() << 16) | (ch + 1)->unicode());
|
||||
} else if ((ch + 1)->unicode() == 0xFE0F) {
|
||||
e = getEmoji(ch->unicode());
|
||||
}
|
||||
}
|
||||
}
|
||||
int elen = 0;
|
||||
EmojiPtr e = emojiFromText(ch, end, elen);
|
||||
if (e) {
|
||||
ch += (e->len - 1);
|
||||
if (ch + 1 < end && (ch + 1)->unicode() == 0xFE0F) {
|
||||
++ch;
|
||||
++s;
|
||||
for (int i = 0; i < elen; ++i, ++ch, ++s) {
|
||||
if (ch->isHighSurrogate() && i + 1 < elen && (ch + 1)->isLowSurrogate()) {
|
||||
++ch;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
--ch;
|
||||
--s;
|
||||
} else if (ch->isHighSurrogate() && ch + 1 < end && (ch + 1)->isLowSurrogate()) {
|
||||
++ch;
|
||||
}
|
||||
if (s >= limit) {
|
||||
sendingText = leftText.mid(0, good - start);
|
||||
|
@ -4250,3 +4236,7 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
|||
|
||||
return lnkRanges;
|
||||
}
|
||||
|
||||
void emojiDraw(QPainter &p, EmojiPtr e, int x, int y) {
|
||||
p.drawPixmap(QPoint(x, y), App::emojis(), QRect(e->x * ESize, e->y * ESize, ESize, ESize));
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich = false);
|
|||
|
||||
#include "gui/emoji_config.h"
|
||||
|
||||
void emojiDraw(QPainter &p, EmojiPtr e, int x, int y);
|
||||
|
||||
#include "../../../QtStatic/qtbase/src/gui/text/qfontengine_p.h"
|
||||
|
||||
enum TextBlockType {
|
||||
|
|
|
@ -3448,9 +3448,9 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
|
|||
p.fillRect(QRect(width - pixwidth, 0, pixwidth, pixheight), st::black->b);
|
||||
}
|
||||
if (_pixw > pixwidth) {
|
||||
p.drawPixmap(QRect(width - pixwidth, (pixheight - _pixh) / 2, pixwidth, _pixh), pix, QRect((_pixw - pixwidth) / 2, 0, pixwidth, _pixh));
|
||||
p.drawPixmap(QRect(width - pixwidth, (pixheight - _pixh) / 2, pixwidth, _pixh), pix, QRect(cIntRetinaFactor() * (_pixw - pixwidth) / 2, 0, cIntRetinaFactor() * pixwidth, cIntRetinaFactor() * _pixh));
|
||||
} else if (_pixh > pixheight) {
|
||||
p.drawPixmap(QRect(width - pixwidth + (pixwidth - _pixw) / 2, 0, _pixw, pixheight), pix, QRect(0, (_pixh - pixheight) / 2, _pixw, pixheight));
|
||||
p.drawPixmap(QRect(width - pixwidth + (pixwidth - _pixw) / 2, 0, _pixw, pixheight), pix, QRect(0, cIntRetinaFactor() * (_pixh - pixheight) / 2, cIntRetinaFactor() * _pixw, cIntRetinaFactor() * pixheight));
|
||||
} else {
|
||||
p.drawPixmap(QPoint(width - pixwidth + (pixwidth - _pixw) / 2, (pixheight - _pixh) / 2), pix);
|
||||
}
|
||||
|
|
|
@ -1763,9 +1763,7 @@ void HistoryWidget::updateTyping(bool typing) {
|
|||
//}
|
||||
|
||||
void HistoryWidget::updateRecentStickers() {
|
||||
if (cEmojiTab() == dbietStickers) {
|
||||
_emojiPan.onTabChange();
|
||||
}
|
||||
_emojiPan.refreshStickers();
|
||||
}
|
||||
|
||||
void HistoryWidget::typingDone(const MTPBool &result, mtpRequestId req) {
|
||||
|
@ -1852,7 +1850,6 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
|||
}
|
||||
cSetRecentStickers(add);
|
||||
Local::writeRecentStickers();
|
||||
_emojiPan.onTabChange();
|
||||
}
|
||||
|
||||
const QVector<MTPStickerPack> &packs(d.vpacks.c_vector().v);
|
||||
|
@ -1862,23 +1859,11 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
|||
QString emoticon(qs(p.vemoticon));
|
||||
EmojiPtr e = 0;
|
||||
for (const QChar *ch = emoticon.constData(), *end = emoticon.constEnd(); ch != end; ++ch) {
|
||||
if (ch->isHighSurrogate()) {
|
||||
if (ch + 1 < end && (ch + 1)->isLowSurrogate()) {
|
||||
e = getEmoji((ch->unicode() << 16) | (ch + 1)->unicode());
|
||||
if (!e) {
|
||||
++ch;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ch + 1 < end) {
|
||||
if (((ch->unicode() >= 48 && ch->unicode() < 58) || ch->unicode() == 35) && (ch + 1)->unicode() == 0x20E3) {
|
||||
e = getEmoji((ch->unicode() << 16) | (ch + 1)->unicode());
|
||||
} else if ((ch + 1)->unicode() == 0xFE0F) {
|
||||
e = getEmoji(ch->unicode());
|
||||
}
|
||||
}
|
||||
}
|
||||
int len = 0;
|
||||
e = emojiFromText(ch, end, len);
|
||||
if (e) break;
|
||||
|
||||
if (ch + 1 < end && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
|
||||
}
|
||||
if (e) {
|
||||
const QVector<MTPlong> docs(p.vdocuments.c_vector().v);
|
||||
|
@ -1912,7 +1897,7 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
|||
}
|
||||
|
||||
// updateStickerPan();
|
||||
_emojiPan.onTabChange();
|
||||
_emojiPan.refreshStickers();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -905,24 +905,62 @@ namespace {
|
|||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
switch (v) {
|
||||
case dbietRecent: cSetEmojiTab(dbietRecent); break;
|
||||
case dbietPeople: cSetEmojiTab(dbietPeople); break;
|
||||
case dbietNature: cSetEmojiTab(dbietNature); break;
|
||||
case dbietObjects: cSetEmojiTab(dbietObjects); break;
|
||||
case dbietPlaces: cSetEmojiTab(dbietPlaces); break;
|
||||
case dbietSymbols: cSetEmojiTab(dbietSymbols); break;
|
||||
case dbietStickers: cSetEmojiTab(dbietStickers); break;
|
||||
case dbietRecent : cSetEmojiTab(dbietRecent ); break;
|
||||
case dbietPeople : cSetEmojiTab(dbietPeople ); break;
|
||||
case dbietNature : cSetEmojiTab(dbietNature ); break;
|
||||
case dbietFood : cSetEmojiTab(dbietFood ); break;
|
||||
case dbietCelebration: cSetEmojiTab(dbietCelebration); break;
|
||||
case dbietActivity : cSetEmojiTab(dbietActivity ); break;
|
||||
case dbietTravel : cSetEmojiTab(dbietTravel ); break;
|
||||
case dbietObjects : cSetEmojiTab(dbietObjects ); break;
|
||||
case dbietStickers : cSetEmojiTab(dbietStickers ); break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case dbiRecentEmojisOld: {
|
||||
RecentEmojisPreloadOld v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
if (!v.isEmpty()) {
|
||||
RecentEmojisPreload p;
|
||||
p.reserve(v.size());
|
||||
for (int i = 0; i < v.size(); ++i) {
|
||||
uint64 e(v.at(i).first);
|
||||
switch (e) {
|
||||
case 0xD83CDDEFLLU: e = 0xD83CDDEFD83CDDF5LLU; break;
|
||||
case 0xD83CDDF0LLU: e = 0xD83CDDF0D83CDDF7LLU; break;
|
||||
case 0xD83CDDE9LLU: e = 0xD83CDDE9D83CDDEALLU; break;
|
||||
case 0xD83CDDE8LLU: e = 0xD83CDDE8D83CDDF3LLU; break;
|
||||
case 0xD83CDDFALLU: e = 0xD83CDDFAD83CDDF8LLU; break;
|
||||
case 0xD83CDDEBLLU: e = 0xD83CDDEBD83CDDF7LLU; break;
|
||||
case 0xD83CDDEALLU: e = 0xD83CDDEAD83CDDF8LLU; break;
|
||||
case 0xD83CDDEELLU: e = 0xD83CDDEED83CDDF9LLU; break;
|
||||
case 0xD83CDDF7LLU: e = 0xD83CDDF7D83CDDFALLU; break;
|
||||
case 0xD83CDDECLLU: e = 0xD83CDDECD83CDDE7LLU; break;
|
||||
}
|
||||
p.push_back(qMakePair(e, v.at(i).second));
|
||||
}
|
||||
cSetRecentEmojisPreload(p);
|
||||
}
|
||||
} break;
|
||||
|
||||
case dbiRecentEmojis: {
|
||||
RecentEmojiPreload v;
|
||||
RecentEmojisPreload v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetRecentEmojisPreload(v);
|
||||
} break;
|
||||
|
||||
case dbiEmojiVariants: {
|
||||
EmojiColorVariants v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetEmojiVariants(v);
|
||||
} break;
|
||||
|
||||
case dbiDialogLastPath: {
|
||||
QString path;
|
||||
stream >> path;
|
||||
|
@ -1140,7 +1178,8 @@ namespace {
|
|||
|
||||
uint32 size = 11 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
size += sizeof(quint32) + sizeof(qint32) + cGetRecentEmojis().size() * (sizeof(uint32) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + cGetRecentEmojis().size() * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||
size += sizeof(quint32) + _stringSize(cDialogLastPath());
|
||||
|
||||
EncryptedDescriptor data(size);
|
||||
|
@ -1158,13 +1197,15 @@ namespace {
|
|||
data.stream << quint32(dbiEmojiTab) << qint32(cEmojiTab());
|
||||
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
||||
|
||||
RecentEmojiPreload v;
|
||||
RecentEmojisPreload v;
|
||||
v.reserve(cGetRecentEmojis().size());
|
||||
for (RecentEmojiPack::const_iterator i = cGetRecentEmojis().cbegin(), e = cGetRecentEmojis().cend(); i != e; ++i) {
|
||||
v.push_back(qMakePair(i->first->code, i->second));
|
||||
v.push_back(qMakePair(emojiKey(i->first), i->second));
|
||||
}
|
||||
data.stream << quint32(dbiRecentEmojis) << v;
|
||||
|
||||
data.stream << quint32(dbiEmojiVariants) << cEmojiVariants();
|
||||
|
||||
FileWriteDescriptor file(_userSettingsKey);
|
||||
file.writeEncrypted(data);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ bool gHasPasscode = false;
|
|||
|
||||
DBIEmojiTab gEmojiTab = dbietRecent;
|
||||
RecentEmojiPack gRecentEmojis;
|
||||
RecentEmojiPreload gRecentEmojisPreload;
|
||||
RecentEmojisPreload gRecentEmojisPreload;
|
||||
EmojiColorVariants gEmojiVariants;
|
||||
|
||||
AllStickers gStickers;
|
||||
QByteArray gStickersHash;
|
||||
|
@ -185,22 +186,22 @@ void settingsParseArgs(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
const RecentEmojiPack &cGetRecentEmojis() {
|
||||
RecentEmojiPack &cGetRecentEmojis() {
|
||||
if (cRecentEmojis().isEmpty()) {
|
||||
RecentEmojiPack r;
|
||||
if (!cRecentEmojisPreload().isEmpty()) {
|
||||
RecentEmojiPreload p(cRecentEmojisPreload());
|
||||
cSetRecentEmojisPreload(RecentEmojiPreload());
|
||||
RecentEmojisPreload p(cRecentEmojisPreload());
|
||||
cSetRecentEmojisPreload(RecentEmojisPreload());
|
||||
r.reserve(p.size());
|
||||
for (RecentEmojiPreload::const_iterator i = p.cbegin(), e = p.cend(); i != e; ++i) {
|
||||
uint32 code = ((i->first & 0xFFFFU) == 0xFE0FU) ? ((i->first >> 16) & 0xFFFFU) : i->first;
|
||||
EmojiPtr ep(getEmoji(code));
|
||||
for (RecentEmojisPreload::const_iterator i = p.cbegin(), e = p.cend(); i != e; ++i) {
|
||||
uint64 code = ((!(i->first & 0xFFFFFFFF00000000LLU) && (i->first & 0xFFFFU) == 0xFE0FU)) ? ((i->first >> 16) & 0xFFFFU) : i->first;
|
||||
EmojiPtr ep(emojiFromKey(code));
|
||||
if (!ep) continue;
|
||||
|
||||
if (ep->postfix) {
|
||||
int32 j = 0, l = r.size();
|
||||
for (; j < l; ++j) {
|
||||
if (r[j].first->code == code) {
|
||||
if (emojiKey(r[j].first) == code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -211,47 +212,47 @@ const RecentEmojiPack &cGetRecentEmojis() {
|
|||
r.push_back(qMakePair(ep, i->second));
|
||||
}
|
||||
}
|
||||
uint32 defaultRecent[] = {
|
||||
0xD83DDE02U,
|
||||
0xD83DDE18U,
|
||||
0x2764U,
|
||||
0xD83DDE0DU,
|
||||
0xD83DDE0AU,
|
||||
0xD83DDE01U,
|
||||
0xD83DDC4DU,
|
||||
0x263AU,
|
||||
0xD83DDE14U,
|
||||
0xD83DDE04U,
|
||||
0xD83DDE2DU,
|
||||
0xD83DDC8BU,
|
||||
0xD83DDE12U,
|
||||
0xD83DDE33U,
|
||||
0xD83DDE1CU,
|
||||
0xD83DDE48U,
|
||||
0xD83DDE09U,
|
||||
0xD83DDE03U,
|
||||
0xD83DDE22U,
|
||||
0xD83DDE1DU,
|
||||
0xD83DDE31U,
|
||||
0xD83DDE21U,
|
||||
0xD83DDE0FU,
|
||||
0xD83DDE1EU,
|
||||
0xD83DDE05U,
|
||||
0xD83DDE1AU,
|
||||
0xD83DDE4AU,
|
||||
0xD83DDE0CU,
|
||||
0xD83DDE00U,
|
||||
0xD83DDE0BU,
|
||||
0xD83DDE06U,
|
||||
0xD83DDC4CU,
|
||||
0xD83DDE10U,
|
||||
0xD83DDE15U,
|
||||
uint64 defaultRecent[] = {
|
||||
0xD83DDE02LLU,
|
||||
0xD83DDE18LLU,
|
||||
0x2764LLU,
|
||||
0xD83DDE0DLLU,
|
||||
0xD83DDE0ALLU,
|
||||
0xD83DDE01LLU,
|
||||
0xD83DDC4DLLU,
|
||||
0x263ALLU,
|
||||
0xD83DDE14LLU,
|
||||
0xD83DDE04LLU,
|
||||
0xD83DDE2DLLU,
|
||||
0xD83DDC8BLLU,
|
||||
0xD83DDE12LLU,
|
||||
0xD83DDE33LLU,
|
||||
0xD83DDE1CLLU,
|
||||
0xD83DDE48LLU,
|
||||
0xD83DDE09LLU,
|
||||
0xD83DDE03LLU,
|
||||
0xD83DDE22LLU,
|
||||
0xD83DDE1DLLU,
|
||||
0xD83DDE31LLU,
|
||||
0xD83DDE21LLU,
|
||||
0xD83DDE0FLLU,
|
||||
0xD83DDE1ELLU,
|
||||
0xD83DDE05LLU,
|
||||
0xD83DDE1ALLU,
|
||||
0xD83DDE4ALLU,
|
||||
0xD83DDE0CLLU,
|
||||
0xD83DDE00LLU,
|
||||
0xD83DDE0BLLU,
|
||||
0xD83DDE06LLU,
|
||||
0xD83DDC4CLLU,
|
||||
0xD83DDE10LLU,
|
||||
0xD83DDE15LLU,
|
||||
};
|
||||
for (int32 i = 0, s = sizeof(defaultRecent) / sizeof(defaultRecent[0]); i < s; ++i) {
|
||||
if (r.size() >= EmojiPadPerRow * EmojiPadRowsPerPage) break;
|
||||
|
||||
EmojiPtr ep(getEmoji(defaultRecent[i]));
|
||||
if (!ep) continue;
|
||||
EmojiPtr ep(emojiGet(defaultRecent[i]));
|
||||
if (!ep || ep == TwoSymbolEmoji) continue;
|
||||
|
||||
int32 j = 0, l = r.size();
|
||||
for (; j < l; ++j) {
|
||||
|
@ -265,5 +266,5 @@ const RecentEmojiPack &cGetRecentEmojis() {
|
|||
}
|
||||
cSetRecentEmojis(r);
|
||||
}
|
||||
return cRecentEmojis();
|
||||
return cRefRecentEmojis();
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ inline void cSet##Name(const Type &Name) { \
|
|||
g##Name = Name; \
|
||||
}
|
||||
|
||||
#define DeclareRefSetting(Type, Name) DeclareSetting(Type, Name) \
|
||||
inline Type &cRef##Name() { \
|
||||
return g##Name; \
|
||||
}
|
||||
|
||||
DeclareSetting(bool, Rtl);
|
||||
DeclareSetting(Qt::LayoutDirection, LangDir);
|
||||
inline bool rtl() {
|
||||
|
@ -153,23 +158,28 @@ T convertScale(T v) {
|
|||
DeclareSetting(DBIEmojiTab, EmojiTab);
|
||||
|
||||
struct EmojiData {
|
||||
EmojiData(uint16 x, uint16 y, uint32 code, uint32 code2, uint16 len, uint16 postfix = 0) : x(x), y(y), code(code), code2(code2), len(len), postfix(postfix) {
|
||||
EmojiData(uint16 x, uint16 y, uint32 code, uint32 code2, uint16 len, uint16 postfix, uint32 color) : x(x), y(y), code(code), code2(code2), len(len), postfix(postfix), color(color) {
|
||||
}
|
||||
uint16 x, y;
|
||||
uint32 code, code2;
|
||||
uint16 len;
|
||||
uint16 postfix;
|
||||
uint32 color;
|
||||
};
|
||||
|
||||
typedef const EmojiData *EmojiPtr;
|
||||
static EmojiPtr TwoSymbolEmoji = EmojiPtr(0x01);
|
||||
|
||||
typedef QVector<EmojiPtr> EmojiPack;
|
||||
typedef QVector<QPair<uint32, ushort> > RecentEmojiPreload;
|
||||
typedef QVector<QPair<uint32, ushort> > RecentEmojisPreloadOld;
|
||||
typedef QVector<QPair<uint64, ushort> > RecentEmojisPreload;
|
||||
typedef QVector<QPair<EmojiPtr, ushort> > RecentEmojiPack;
|
||||
DeclareSetting(RecentEmojiPack, RecentEmojis);
|
||||
DeclareSetting(RecentEmojiPreload, RecentEmojisPreload);
|
||||
typedef QMap<uint32, uint64> EmojiColorVariants;
|
||||
DeclareRefSetting(RecentEmojiPack, RecentEmojis);
|
||||
DeclareSetting(RecentEmojisPreload, RecentEmojisPreload);
|
||||
DeclareRefSetting(EmojiColorVariants, EmojiVariants);
|
||||
|
||||
const RecentEmojiPack &cGetRecentEmojis();
|
||||
RecentEmojiPack &cGetRecentEmojis();
|
||||
|
||||
struct DocumentData;
|
||||
typedef QVector<DocumentData*> StickerPack;
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
<file>art/sprite_125x.png</file>
|
||||
<file>art/sprite_150x.png</file>
|
||||
<file>art/sprite_200x.png</file>
|
||||
<file>art/emoji.png</file>
|
||||
<file>art/emoji_125x.png</file>
|
||||
<file>art/emoji_150x.png</file>
|
||||
<file>art/emoji_200x.png</file>
|
||||
<file>art/emoji.webp</file>
|
||||
<file>art/emoji_125x.webp</file>
|
||||
<file>art/emoji_150x.webp</file>
|
||||
<file>art/emoji_200x.webp</file>
|
||||
<file>art/emoji_250x.webp</file>
|
||||
<file>art/blank.gif</file>
|
||||
<file>art/icon256.png</file>
|
||||
<file>art/iconbig256.png</file>
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
<file>art/sprite_125x.png</file>
|
||||
<file>art/sprite_150x.png</file>
|
||||
<file>art/sprite_200x.png</file>
|
||||
<file>art/emoji.png</file>
|
||||
<file>art/emoji_125x.png</file>
|
||||
<file>art/emoji_150x.png</file>
|
||||
<file>art/emoji_200x.png</file>
|
||||
<file>art/emoji.webp</file>
|
||||
<file>art/emoji_125x.webp</file>
|
||||
<file>art/emoji_150x.webp</file>
|
||||
<file>art/emoji_200x.webp</file>
|
||||
<file>art/emoji_250x.webp</file>
|
||||
<file>art/blank.gif</file>
|
||||
<file>art/icon256.png</file>
|
||||
</qresource>
|
||||
|
|
|
@ -249,7 +249,7 @@ enum DataBlockId {
|
|||
dbiDownloadPath = 21,
|
||||
dbiScale = 22,
|
||||
dbiEmojiTab = 23,
|
||||
dbiRecentEmojis = 24,
|
||||
dbiRecentEmojisOld = 24,
|
||||
dbiLoggedPhoneNumber = 25,
|
||||
dbiMutedPeers = 26,
|
||||
// 27 reserved
|
||||
|
@ -261,6 +261,8 @@ enum DataBlockId {
|
|||
dbiTileBackground = 33,
|
||||
dbiAutoLock = 34,
|
||||
dbiDialogLastPath = 35,
|
||||
dbiRecentEmojis = 36,
|
||||
dbiEmojiVariants = 37,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
@ -318,14 +320,21 @@ enum DBIScale {
|
|||
};
|
||||
|
||||
enum DBIEmojiTab {
|
||||
dbietRecent = -1,
|
||||
dbietPeople = 0,
|
||||
dbietNature = 1,
|
||||
dbietObjects = 2,
|
||||
dbietPlaces = 3,
|
||||
dbietSymbols = 4,
|
||||
dbietStickers = 666,
|
||||
dbietRecent = -1,
|
||||
dbietPeople = 0,
|
||||
dbietNature = 1,
|
||||
dbietFood = 2,
|
||||
dbietCelebration = 3,
|
||||
dbietActivity = 4,
|
||||
dbietTravel = 5,
|
||||
dbietObjects = 6,
|
||||
dbietStickers = 666,
|
||||
};
|
||||
static const int emojiTabCount = 8;
|
||||
static const int emojiTabShift = 100000;
|
||||
inline DBIEmojiTab emojiTabAtIndex(int index) {
|
||||
return (index < 0 || index >= emojiTabCount) ? dbietRecent : DBIEmojiTab(index - 1);
|
||||
}
|
||||
|
||||
enum DBIPlatform {
|
||||
dbipWindows = 0,
|
||||
|
|
|
@ -61,18 +61,19 @@ compiler_rcc_make_all: GeneratedFiles/qrc_telegram.cpp
|
|||
compiler_rcc_clean:
|
||||
-$(DEL_FILE) GeneratedFiles/qrc_telegram.cpp
|
||||
GeneratedFiles/qrc_telegram.cpp: SourceFiles/telegram.qrc \
|
||||
SourceFiles/art/emoji.png \
|
||||
SourceFiles/art/emoji.webp \
|
||||
SourceFiles/art/blank.gif \
|
||||
SourceFiles/art/bg.jpg \
|
||||
SourceFiles/art/sprite_150x.png \
|
||||
SourceFiles/art/sprite.png \
|
||||
SourceFiles/art/icon256.png \
|
||||
SourceFiles/art/emoji_150x.png \
|
||||
SourceFiles/art/emoji_150x.webp \
|
||||
SourceFiles/art/sprite_200x.png \
|
||||
SourceFiles/art/newmsg.wav \
|
||||
SourceFiles/art/sprite_125x.png \
|
||||
SourceFiles/art/emoji_200x.png \
|
||||
SourceFiles/art/emoji_125x.png \
|
||||
SourceFiles/art/emoji_200x.webp \
|
||||
SourceFiles/art/emoji_250x.webp \
|
||||
SourceFiles/art/emoji_125x.webp \
|
||||
SourceFiles/art/fonts/OpenSans-Regular.ttf \
|
||||
SourceFiles/art/fonts/OpenSans-Bold.ttf \
|
||||
SourceFiles/art/fonts/OpenSans-Semibold.ttf \
|
||||
|
|