mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Featured stickers section done in StickersPanel.
EmojiPan moved to a separate module stickers/emoji_pan. FFmpeg linked by msvs linker flags in GYP to use ".a" extension.
This commit is contained in:
parent
82d92d21f6
commit
ff657347b8
19 changed files with 4703 additions and 4252 deletions
Binary file not shown.
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 177 KiB |
Binary file not shown.
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 241 KiB |
|
@ -1866,6 +1866,8 @@ emojiSymbolsActive: sprite(287px, 286px, 21px, 22px);
|
|||
stickersSettings: sprite(140px, 124px, 21px, 22px);
|
||||
savedGifsOver: sprite(329px, 286px, 21px, 22px);
|
||||
savedGifsActive: sprite(350px, 286px, 21px, 22px);
|
||||
featuredStickersOver: sprite(329px, 264px, 21px, 22px);
|
||||
featuredStickersActive: sprite(350px, 264px, 21px, 22px);
|
||||
|
||||
stickersSettingsUnreadSize: 17px;
|
||||
stickersSettingsUnreadPosition: point(4px, 5px);
|
||||
|
|
|
@ -684,6 +684,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
"lng_switch_stickers" = "Stickers";
|
||||
"lng_switch_stickers_gifs" = "GIFs & Stickers";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_stickers_featured_add" = "Add";
|
||||
|
||||
"lng_saved_gifs" = "Saved GIFs";
|
||||
"lng_inline_bot_results" = "Results from {inline_bot}";
|
||||
|
|
|
@ -959,17 +959,17 @@ void AppClass::killDownloadSessions() {
|
|||
void AppClass::photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file) {
|
||||
if (!App::self()) return;
|
||||
|
||||
QMap<FullMsgId, PeerId>::iterator i = photoUpdates.find(msgId);
|
||||
auto i = photoUpdates.find(msgId);
|
||||
if (i != photoUpdates.end()) {
|
||||
PeerId id = i.value();
|
||||
auto id = i.value();
|
||||
if (MTP::authedId() && peerToUser(id) == MTP::authedId()) {
|
||||
MTP::send(MTPphotos_UploadProfilePhoto(file, MTP_string(""), MTP_inputGeoPointEmpty(), MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100))), rpcDone(&AppClass::selfPhotoDone), rpcFail(&AppClass::peerPhotoFail, id));
|
||||
} else if (peerIsChat(id)) {
|
||||
History *hist = App::history(id);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_EditChatPhoto(hist->peer->asChat()->inputChat, MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&AppClass::chatPhotoDone, id), rpcFail(&AppClass::peerPhotoFail, id), 0, 0, hist->sendRequestId);
|
||||
auto history = App::history(id);
|
||||
history->sendRequestId = MTP::send(MTPmessages_EditChatPhoto(history->peer->asChat()->inputChat, MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&AppClass::chatPhotoDone, id), rpcFail(&AppClass::peerPhotoFail, id), 0, 0, history->sendRequestId);
|
||||
} else if (peerIsChannel(id)) {
|
||||
History *hist = App::history(id);
|
||||
hist->sendRequestId = MTP::send(MTPchannels_EditPhoto(hist->peer->asChannel()->inputChannel, MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&AppClass::chatPhotoDone, id), rpcFail(&AppClass::peerPhotoFail, id), 0, 0, hist->sendRequestId);
|
||||
auto history = App::history(id);
|
||||
history->sendRequestId = MTP::send(MTPchannels_EditPhoto(history->peer->asChannel()->inputChannel, MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&AppClass::chatPhotoDone, id), rpcFail(&AppClass::peerPhotoFail, id), 0, 0, history->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "stickersetbox.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "stickers/stickers.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "apiwrap.h"
|
||||
#include "localstorage.h"
|
||||
|
@ -37,54 +38,6 @@ constexpr int kArchivedLimitPerPage = 30;
|
|||
|
||||
} // namespace
|
||||
|
||||
namespace Stickers {
|
||||
|
||||
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
|
||||
auto &v = d.vsets.c_vector().v;
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
Stickers::Order archived;
|
||||
archived.reserve(v.size());
|
||||
QMap<uint64, uint64> setsToRequest;
|
||||
for_const (auto &stickerSet, v) {
|
||||
const MTPDstickerSet *setData = nullptr;
|
||||
switch (stickerSet.type()) {
|
||||
case mtpc_stickerSetCovered: {
|
||||
auto &d = stickerSet.c_stickerSetCovered();
|
||||
if (d.vset.type() == mtpc_stickerSet) {
|
||||
setData = &d.vset.c_stickerSet();
|
||||
}
|
||||
} break;
|
||||
case mtpc_stickerSetMultiCovered: {
|
||||
auto &d = stickerSet.c_stickerSetMultiCovered();
|
||||
if (d.vset.type() == mtpc_stickerSet) {
|
||||
setData = &d.vset.c_stickerSet();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if (setData) {
|
||||
auto set = Stickers::feedSet(*setData);
|
||||
if (set->stickers.isEmpty()) {
|
||||
setsToRequest.insert(set->id, set->access);
|
||||
}
|
||||
auto index = order.indexOf(set->id);
|
||||
if (index >= 0) {
|
||||
order.removeAt(index);
|
||||
}
|
||||
archived.push_back(set->id);
|
||||
}
|
||||
}
|
||||
if (!setsToRequest.isEmpty()) {
|
||||
for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
||||
App::api()->scheduleStickerSetRequest(i.key(), i.value());
|
||||
}
|
||||
App::api()->requestStickerSets();
|
||||
}
|
||||
Local::writeArchivedStickers();
|
||||
Ui::showLayer(new StickersBox(archived), KeepOtherLayers);
|
||||
}
|
||||
|
||||
} // namespace Stickers
|
||||
|
||||
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget()
|
||||
, _input(set) {
|
||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||
|
@ -215,12 +168,13 @@ void StickerSetInner::installDone(const MTPmessages_StickerSetInstallResult &res
|
|||
|
||||
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
|
||||
Stickers::applyArchivedResult(result.c_messages_stickerSetInstallResultArchive());
|
||||
} else if (wasArchived) {
|
||||
Local::writeArchivedStickers();
|
||||
} else {
|
||||
if (wasArchived) {
|
||||
Local::writeArchivedStickers();
|
||||
}
|
||||
Local::writeInstalledStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
Local::writeInstalledStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
emit installed(_setId);
|
||||
}
|
||||
|
||||
|
@ -864,59 +818,13 @@ void StickersInner::installSet(uint64 setId) {
|
|||
|
||||
MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_boolFalse()), rpcDone(&StickersInner::installDone), rpcFail(&StickersInner::installFail, setId));
|
||||
|
||||
auto flags = it->flags;
|
||||
it->flags &= ~(MTPDstickerSet::Flag::f_archived | MTPDstickerSet_ClientFlag::f_unread);
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
auto changedFlags = flags ^ it->flags;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int insertAtIndex = 0, currentIndex = order.indexOf(setId);
|
||||
if (currentIndex != insertAtIndex) {
|
||||
if (currentIndex > 0) {
|
||||
order.removeAt(currentIndex);
|
||||
}
|
||||
order.insert(insertAtIndex, setId);
|
||||
}
|
||||
|
||||
auto custom = sets.find(Stickers::CustomSetId);
|
||||
if (custom != sets.cend()) {
|
||||
for_const (auto sticker, it->stickers) {
|
||||
int removeIndex = custom->stickers.indexOf(sticker);
|
||||
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||
}
|
||||
if (custom->stickers.isEmpty()) {
|
||||
sets.erase(custom);
|
||||
}
|
||||
}
|
||||
Local::writeInstalledStickers();
|
||||
if (changedFlags & MTPDstickerSet_ClientFlag::f_unread) Local::writeFeaturedStickers();
|
||||
if (changedFlags & MTPDstickerSet::Flag::f_archived) {
|
||||
auto index = Global::RefArchivedStickerSetsOrder().indexOf(setId);
|
||||
if (index >= 0) {
|
||||
Global::RefArchivedStickerSetsOrder().removeAt(index);
|
||||
Local::writeArchivedStickers();
|
||||
}
|
||||
}
|
||||
emit App::main()->stickersUpdated();
|
||||
Stickers::installLocally(setId);
|
||||
}
|
||||
|
||||
void StickersInner::installDone(const MTPmessages_StickerSetInstallResult &result) {
|
||||
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
|
||||
Stickers::applyArchivedResult(result.c_messages_stickerSetInstallResultArchive());
|
||||
Local::writeInstalledStickers();
|
||||
Local::writeArchivedStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
// TEST DATA ONLY
|
||||
//MTPVector<MTPStickerSet> v = MTP_vector<MTPStickerSet>(0);
|
||||
//for (auto &set : Global::RefStickerSets()) {
|
||||
// if (rand() < RAND_MAX / 2) {
|
||||
// set.flags |= MTPDstickerSet::Flag::f_archived;
|
||||
// v._vector().v.push_back(MTP_stickerSet(MTP_flags(set.flags), MTP_long(set.id), MTP_long(set.access), MTP_string(set.title), MTP_string(set.shortName), MTP_int(set.count), MTP_int(set.hash)));
|
||||
// }
|
||||
//}
|
||||
//Stickers::applyArchivedResult(MTP_messages_stickerSetInstallResultArchive(v).c_messages_stickerSetInstallResultArchive());
|
||||
}
|
||||
|
||||
bool StickersInner::installFail(uint64 setId, const RPCError &error) {
|
||||
|
@ -929,19 +837,7 @@ bool StickersInner::installFail(uint64 setId, const RPCError &error) {
|
|||
return true;
|
||||
}
|
||||
|
||||
it->flags &= ~MTPDstickerSet::Flag::f_installed;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int currentIndex = order.indexOf(setId);
|
||||
if (currentIndex >= 0) {
|
||||
order.removeAt(currentIndex);
|
||||
}
|
||||
|
||||
Local::writeInstalledStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
|
||||
Ui::showLayer(new InformBox(lang(lng_stickers_not_found)), KeepOtherLayers);
|
||||
|
||||
Stickers::undoInstallLocally(setId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,7 +27,6 @@ class Dropdown : public TWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Dropdown(QWidget *parent, const style::dropdown &st = st::dropdownDef);
|
||||
|
||||
IconedButton *addButton(IconedButton *button);
|
||||
|
@ -61,11 +60,9 @@ public:
|
|||
}
|
||||
|
||||
signals:
|
||||
|
||||
void hiding();
|
||||
|
||||
public slots:
|
||||
|
||||
void hideStart();
|
||||
void hideFinish();
|
||||
|
||||
|
@ -75,20 +72,19 @@ public slots:
|
|||
void buttonStateChanged(int oldState, ButtonStateChangeSource source);
|
||||
|
||||
private:
|
||||
|
||||
void adjustButtons();
|
||||
|
||||
bool _ignore;
|
||||
bool _ignore = false;
|
||||
|
||||
typedef QVector<IconedButton*> Buttons;
|
||||
Buttons _buttons;
|
||||
|
||||
int32 _selected;
|
||||
int32 _selected = -1;
|
||||
|
||||
const style::dropdown &_st;
|
||||
|
||||
int32 _width, _height;
|
||||
bool _hiding;
|
||||
bool _hiding = false;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
Animation _a_appearance;
|
||||
|
@ -103,7 +99,6 @@ class DragArea : public TWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
DragArea(QWidget *parent);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
@ -133,18 +128,15 @@ public:
|
|||
}
|
||||
|
||||
signals:
|
||||
|
||||
void dropped(const QMimeData *data);
|
||||
|
||||
public slots:
|
||||
|
||||
void hideStart();
|
||||
void hideFinish();
|
||||
|
||||
void showStart();
|
||||
|
||||
private:
|
||||
|
||||
bool _hiding, _in;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
|
@ -156,588 +148,3 @@ private:
|
|||
QString _text, _subtext;
|
||||
|
||||
};
|
||||
|
||||
namespace InlineBots {
|
||||
namespace Layout {
|
||||
class ItemBase;
|
||||
} // namespace Layout
|
||||
class Result;
|
||||
} // namespace InlineBots
|
||||
|
||||
namespace internal {
|
||||
|
||||
constexpr int InlineItemsMaxPerRow = 5;
|
||||
constexpr int EmojiColorsCount = 5;
|
||||
|
||||
using InlineResult = InlineBots::Result;
|
||||
using InlineResults = QList<InlineBots::Result*>;
|
||||
using InlineItem = InlineBots::Layout::ItemBase;
|
||||
|
||||
struct InlineCacheEntry {
|
||||
~InlineCacheEntry() {
|
||||
clearResults();
|
||||
}
|
||||
QString nextOffset;
|
||||
QString switchPmText, switchPmStartToken;
|
||||
InlineResults results; // owns this results list
|
||||
void clearResults();
|
||||
};
|
||||
|
||||
class EmojiColorPicker : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiColorPicker();
|
||||
|
||||
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);
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
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;
|
||||
Animation _a_selected;
|
||||
|
||||
float64 _hovers[EmojiColorsCount + 1];
|
||||
|
||||
int32 _selected, _pressedSel;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
bool _hiding;
|
||||
QPixmap _cache;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
Animation _a_appearance;
|
||||
|
||||
QTimer _hideTimer;
|
||||
|
||||
BoxShadow _shadow;
|
||||
|
||||
};
|
||||
|
||||
class EmojiPanel;
|
||||
class EmojiPanInner : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiPanInner();
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
void hideFinish();
|
||||
|
||||
void showEmojiPack(DBIEmojiTab packIndex);
|
||||
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
DBIEmojiTab currentTab(int yOffset) const;
|
||||
|
||||
void refreshRecent();
|
||||
|
||||
void setScrollTop(int top);
|
||||
|
||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||
|
||||
public slots:
|
||||
|
||||
void updateSelected();
|
||||
|
||||
void onShowPicker();
|
||||
void onPickerHidden();
|
||||
void onColorSelected(EmojiPtr emoji);
|
||||
|
||||
bool checkPickerHide();
|
||||
|
||||
signals:
|
||||
|
||||
void selected(EmojiPtr emoji);
|
||||
|
||||
void switchToStickers();
|
||||
|
||||
void scrollToY(int y);
|
||||
void disableScroll(bool dis);
|
||||
|
||||
void needRefreshPanels();
|
||||
void saveConfigDelayed(int32 delay);
|
||||
|
||||
private:
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
int32 countHeight();
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
|
||||
QRect emojiRect(int tab, int sel);
|
||||
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _animations;
|
||||
Animation _a_selected;
|
||||
|
||||
int32 _top, _counts[emojiTabCount];
|
||||
|
||||
QVector<EmojiPtr> _emojis[emojiTabCount];
|
||||
QVector<float64> _hovers[emojiTabCount];
|
||||
|
||||
int32 _esize;
|
||||
|
||||
int32 _selected, _pressedSel, _pickerSel;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
EmojiColorPicker _picker;
|
||||
QTimer _showPickerTimer;
|
||||
};
|
||||
|
||||
struct StickerIcon {
|
||||
StickerIcon(uint64 setId) : setId(setId), sticker(0), pixw(0), pixh(0) {
|
||||
}
|
||||
StickerIcon(uint64 setId, DocumentData *sticker, int32 pixw, int32 pixh) : setId(setId), sticker(sticker), pixw(pixw), pixh(pixh) {
|
||||
}
|
||||
uint64 setId;
|
||||
DocumentData *sticker;
|
||||
int32 pixw, pixh;
|
||||
};
|
||||
|
||||
class StickerPanInner : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
StickerPanInner();
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
|
||||
void hideFinish(bool completely);
|
||||
void showFinish();
|
||||
void showStickerSet(uint64 setId);
|
||||
void updateShowingSavedGifs();
|
||||
|
||||
bool showSectionIcons() const;
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
void refreshStickers();
|
||||
void refreshRecentStickers(bool resize = true);
|
||||
void refreshSavedGifs();
|
||||
int refreshInlineRows(UserData *bot, const InlineCacheEntry *results, bool resultsDeleted);
|
||||
void refreshRecent();
|
||||
void inlineBotChanged();
|
||||
void hideInlineRowsPanel();
|
||||
void clearInlineRowsPanel();
|
||||
|
||||
void fillIcons(QList<StickerIcon> &icons);
|
||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||
|
||||
void setScrollTop(int top);
|
||||
void preloadImages();
|
||||
|
||||
uint64 currentSet(int yOffset) const;
|
||||
|
||||
void notify_inlineItemLayoutChanged(const InlineItem *layout);
|
||||
void ui_repaintInlineItem(const InlineItem *layout);
|
||||
bool ui_isInlineItemVisible(const InlineItem *layout);
|
||||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
bool inlineResultsShown() const {
|
||||
return _showingInlineItems && !_showingSavedGifs;
|
||||
}
|
||||
int32 countHeight(bool plain = false);
|
||||
|
||||
~StickerPanInner();
|
||||
|
||||
private slots:
|
||||
|
||||
void updateSelected();
|
||||
void onSettings();
|
||||
void onPreview();
|
||||
void onUpdateInlineItems();
|
||||
void onSwitchPm();
|
||||
|
||||
signals:
|
||||
|
||||
void selected(DocumentData *sticker);
|
||||
void selected(PhotoData *photo);
|
||||
void selected(InlineBots::Result *result, UserData *bot);
|
||||
|
||||
void removing(quint64 setId);
|
||||
|
||||
void refreshIcons();
|
||||
void emptyInlineRows();
|
||||
|
||||
void switchToEmoji();
|
||||
|
||||
void scrollToY(int y);
|
||||
void scrollUpdated();
|
||||
void disableScroll(bool dis);
|
||||
void needRefreshPanels();
|
||||
|
||||
void saveConfigDelayed(int32 delay);
|
||||
|
||||
private:
|
||||
|
||||
void paintInlineItems(Painter &p, const QRect &r);
|
||||
void paintStickers(Painter &p, const QRect &r);
|
||||
|
||||
void refreshSwitchPmButton(const InlineCacheEntry *entry);
|
||||
|
||||
void appendSet(uint64 setId);
|
||||
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
QRect stickerRect(int tab, int sel);
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _animations;
|
||||
Animation _a_selected;
|
||||
|
||||
int32 _top;
|
||||
|
||||
struct DisplayedSet {
|
||||
DisplayedSet(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) {
|
||||
}
|
||||
uint64 id;
|
||||
MTPDstickerSet::Flags flags;
|
||||
QString title;
|
||||
QVector<float64> hovers;
|
||||
StickerPack pack;
|
||||
};
|
||||
QList<DisplayedSet> _sets;
|
||||
QList<bool> _custom;
|
||||
|
||||
bool _showingSavedGifs, _showingInlineItems;
|
||||
bool _setGifCommand;
|
||||
UserData *_inlineBot;
|
||||
QString _inlineBotTitle;
|
||||
uint64 _lastScrolled;
|
||||
QTimer _updateInlineItems;
|
||||
bool _inlineWithThumb;
|
||||
|
||||
std_::unique_ptr<BoxButton> _switchPmButton;
|
||||
QString _switchPmStartToken;
|
||||
|
||||
typedef QVector<InlineItem*> InlineItems;
|
||||
struct InlineRow {
|
||||
InlineRow() : height(0) {
|
||||
}
|
||||
int32 height;
|
||||
InlineItems items;
|
||||
};
|
||||
typedef QVector<InlineRow> InlineRows;
|
||||
InlineRows _inlineRows;
|
||||
void clearInlineRows(bool resultsDeleted);
|
||||
|
||||
using GifLayouts = QMap<DocumentData*, InlineItem*>;
|
||||
GifLayouts _gifLayouts;
|
||||
InlineItem *layoutPrepareSavedGif(DocumentData *doc, int32 position);
|
||||
|
||||
using InlineLayouts = QMap<InlineResult*, InlineItem*>;
|
||||
InlineLayouts _inlineLayouts;
|
||||
InlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
||||
|
||||
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
||||
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
||||
|
||||
InlineRow &layoutInlineRow(InlineRow &row, int32 sumWidth = 0);
|
||||
void deleteUnusedGifLayouts();
|
||||
|
||||
void deleteUnusedInlineLayouts();
|
||||
|
||||
int32 validateExistingInlineRows(const InlineResults &results);
|
||||
int32 _selected, _pressedSel;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
LinkButton _settings;
|
||||
|
||||
QTimer _previewTimer;
|
||||
bool _previewShown;
|
||||
};
|
||||
|
||||
class EmojiPanel : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // Stickers::NoneSetId if in emoji
|
||||
void setText(const QString &text);
|
||||
void setDeleteVisible(bool isVisible);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
|
||||
int32 wantedY() const {
|
||||
return _wantedY;
|
||||
}
|
||||
void setWantedY(int32 y) {
|
||||
_wantedY = y;
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void deleteClicked(quint64 setId);
|
||||
void mousePressed();
|
||||
|
||||
public slots:
|
||||
|
||||
void onDelete();
|
||||
|
||||
private:
|
||||
|
||||
void updateText();
|
||||
|
||||
int32 _wantedY;
|
||||
QString _text, _fullText;
|
||||
uint64 _setId;
|
||||
bool _special, _deleteVisible;
|
||||
IconedButton *_delete;
|
||||
|
||||
};
|
||||
|
||||
class EmojiSwitchButton : public Button {
|
||||
public:
|
||||
|
||||
EmojiSwitchButton(QWidget *parent, bool toStickers); // otherwise toEmoji
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void updateText(const QString &inlineBotUsername = QString());
|
||||
|
||||
protected:
|
||||
|
||||
bool _toStickers;
|
||||
QString _text;
|
||||
int32 _textWidth;
|
||||
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
class EmojiPan : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiPan(QWidget *parent);
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void moveBottom(int32 bottom, bool force = false);
|
||||
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void otherEnter();
|
||||
void otherLeave();
|
||||
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
bool event(QEvent *e);
|
||||
|
||||
void fastHide();
|
||||
bool hiding() const {
|
||||
return _hiding || _hideTimer.isActive();
|
||||
}
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void step_slide(float64 ms, bool timer);
|
||||
void step_icons(uint64 ms, bool timer);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
void stickersInstalled(uint64 setId);
|
||||
|
||||
void queryInlineBot(UserData *bot, PeerData *peer, QString query);
|
||||
void clearInlineBot();
|
||||
|
||||
bool overlaps(const QRect &globalRect) {
|
||||
if (isHidden() || !_cache.isNull()) return false;
|
||||
|
||||
return QRect(st::dropdownDef.padding.left(),
|
||||
st::dropdownDef.padding.top(),
|
||||
_width - st::dropdownDef.padding.left() - st::dropdownDef.padding.right(),
|
||||
_height - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom()
|
||||
).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
||||
}
|
||||
|
||||
void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
||||
void ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout);
|
||||
bool ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout);
|
||||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
bool inlineResultsShown() const {
|
||||
return s_inner.inlineResultsShown();
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void refreshStickers();
|
||||
void refreshSavedGifs();
|
||||
|
||||
void hideStart();
|
||||
void hideFinish();
|
||||
|
||||
void showStart();
|
||||
void onWndActiveChanged();
|
||||
|
||||
void onTabChange();
|
||||
void onScrollEmoji();
|
||||
void onScrollStickers();
|
||||
void onSwitch();
|
||||
|
||||
void onRemoveSet(quint64 setId);
|
||||
void onRemoveSetSure();
|
||||
void onDelayedHide();
|
||||
|
||||
void onRefreshIcons();
|
||||
void onRefreshPanels();
|
||||
|
||||
void onSaveConfig();
|
||||
void onSaveConfigDelayed(int32 delay);
|
||||
|
||||
void onInlineRequest();
|
||||
void onEmptyInlineRows();
|
||||
|
||||
signals:
|
||||
|
||||
void emojiSelected(EmojiPtr emoji);
|
||||
void stickerSelected(DocumentData *sticker);
|
||||
void photoSelected(PhotoData *photo);
|
||||
void inlineResultSelected(InlineBots::Result *result, UserData *bot);
|
||||
|
||||
void updateStickers();
|
||||
|
||||
private:
|
||||
void paintStickerSettingsIcon(Painter &p) const;
|
||||
|
||||
void validateSelectedIcon(bool animated = false);
|
||||
|
||||
int32 _maxHeight, _contentMaxHeight, _contentHeight, _contentHeightEmoji, _contentHeightStickers;
|
||||
bool _horizontal;
|
||||
void updateContentHeight();
|
||||
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child);
|
||||
void hideAnimated();
|
||||
void prepareShowHideCache();
|
||||
|
||||
void updateSelected();
|
||||
void updateIcons();
|
||||
|
||||
void prepareTab(int32 &left, int32 top, int32 _width, FlatRadiobutton &tab);
|
||||
void updatePanelsPositions(const QVector<internal::EmojiPanel*> &panels, int32 st);
|
||||
|
||||
void showAll();
|
||||
void hideAll();
|
||||
|
||||
bool _noTabUpdate;
|
||||
|
||||
int32 _width, _height, _bottom;
|
||||
bool _hiding;
|
||||
QPixmap _cache;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
Animation _a_appearance;
|
||||
|
||||
QTimer _hideTimer;
|
||||
|
||||
BoxShadow _shadow;
|
||||
|
||||
FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols;
|
||||
QList<internal::StickerIcon> _icons;
|
||||
QVector<float64> _iconHovers;
|
||||
int32 _iconOver, _iconSel, _iconDown;
|
||||
bool _iconsDragging;
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _iconAnimations;
|
||||
Animation _a_icons;
|
||||
QPoint _iconsMousePos, _iconsMouseDown;
|
||||
int32 _iconsLeft, _iconsTop;
|
||||
int32 _iconsStartX, _iconsMax;
|
||||
anim::ivalue _iconsX, _iconSelX;
|
||||
uint64 _iconsStartAnim;
|
||||
|
||||
bool _stickersShown, _shownFromInlineQuery;
|
||||
QPixmap _fromCache, _toCache;
|
||||
anim::ivalue a_fromCoord, a_toCoord;
|
||||
anim::fvalue a_fromAlpha, a_toAlpha;
|
||||
Animation _a_slide;
|
||||
|
||||
ScrollArea e_scroll;
|
||||
internal::EmojiPanInner e_inner;
|
||||
QVector<internal::EmojiPanel*> e_panels;
|
||||
internal::EmojiSwitchButton e_switch;
|
||||
ScrollArea s_scroll;
|
||||
internal::StickerPanInner s_inner;
|
||||
QVector<internal::EmojiPanel*> s_panels;
|
||||
internal::EmojiSwitchButton s_switch;
|
||||
|
||||
uint64 _removingSetId;
|
||||
|
||||
QTimer _saveConfigTimer;
|
||||
|
||||
// inline bots
|
||||
typedef QMap<QString, internal::InlineCacheEntry*> InlineCache;
|
||||
InlineCache _inlineCache;
|
||||
QTimer _inlineRequestTimer;
|
||||
|
||||
void inlineBotChanged();
|
||||
int32 showInlineRows(bool newResults);
|
||||
bool hideOnNoInlineResults();
|
||||
void recountContentMaxHeight();
|
||||
bool refreshInlineRows(int32 *added = 0);
|
||||
UserData *_inlineBot;
|
||||
PeerData *_inlineQueryPeer = nullptr;
|
||||
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
||||
mtpRequestId _inlineRequestId;
|
||||
void inlineResultsDone(const MTPmessages_BotResults &result);
|
||||
bool inlineResultsFail(const RPCError &error);
|
||||
|
||||
};
|
||||
|
|
|
@ -193,11 +193,12 @@ enum Flags {
|
|||
|
||||
namespace Stickers {
|
||||
|
||||
static const uint64 DefaultSetId = 0; // for backward compatibility
|
||||
static const uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL;
|
||||
static const uint64 RecentSetId = 0xFFFFFFFFFFFFFFFEULL; // for emoji/stickers panel, should not appear in Sets
|
||||
static const uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel, should not appear in Sets
|
||||
static const uint64 CloudRecentSetId = 0xFFFFFFFFFFFFFFFCULL; // for cloud-stored recent stickers
|
||||
constexpr uint64 DefaultSetId = 0; // for backward compatibility
|
||||
constexpr uint64 CustomSetId = 0xFFFFFFFFFFFFFFFFULL;
|
||||
constexpr uint64 RecentSetId = 0xFFFFFFFFFFFFFFFEULL; // for emoji/stickers panel, should not appear in Sets
|
||||
constexpr uint64 NoneSetId = 0xFFFFFFFFFFFFFFFDULL; // for emoji/stickers panel, should not appear in Sets
|
||||
constexpr uint64 CloudRecentSetId = 0xFFFFFFFFFFFFFFFCULL; // for cloud-stored recent stickers
|
||||
constexpr uint64 FeaturedSetId = 0xFFFFFFFFFFFFFFFBULL; // for emoji/stickers panel, should not appear in Sets
|
||||
struct Set {
|
||||
Set(uint64 id, uint64 access, const QString &title, const QString &shortName, int32 count, int32 hash, MTPDstickerSet::Flags flags)
|
||||
: id(id)
|
||||
|
|
|
@ -35,8 +35,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "history/history_service_layout.h"
|
||||
#include "profile/profile_members_widget.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "stickers/emoji_pan.h"
|
||||
#include "lang.h"
|
||||
#include "application.h"
|
||||
#include "dropdown.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "passcodewidget.h"
|
||||
|
@ -3055,11 +3057,11 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
|||
connect(&_field, SIGNAL(linksChanged()), this, SLOT(onPreviewCheck()));
|
||||
connect(App::wnd()->windowHandle(), SIGNAL(visibleChanged(bool)), this, SLOT(onWindowVisibleChanged()));
|
||||
connect(&_scrollTimer, SIGNAL(timeout()), this, SLOT(onScrollTimer()));
|
||||
connect(&_emojiPan, SIGNAL(emojiSelected(EmojiPtr)), &_field, SLOT(onEmojiInsert(EmojiPtr)));
|
||||
connect(&_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*)));
|
||||
connect(&_emojiPan, SIGNAL(photoSelected(PhotoData*)), this, SLOT(onPhotoSend(PhotoData*)));
|
||||
connect(&_emojiPan, SIGNAL(inlineResultSelected(InlineBots::Result*,UserData*)), this, SLOT(onInlineResultSend(InlineBots::Result*,UserData*)));
|
||||
connect(&_emojiPan, SIGNAL(updateStickers()), this, SLOT(updateStickers()));
|
||||
connect(_emojiPan, SIGNAL(emojiSelected(EmojiPtr)), &_field, SLOT(onEmojiInsert(EmojiPtr)));
|
||||
connect(_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*)));
|
||||
connect(_emojiPan, SIGNAL(photoSelected(PhotoData*)), this, SLOT(onPhotoSend(PhotoData*)));
|
||||
connect(_emojiPan, SIGNAL(inlineResultSelected(InlineBots::Result*,UserData*)), this, SLOT(onInlineResultSend(InlineBots::Result*,UserData*)));
|
||||
connect(_emojiPan, SIGNAL(updateStickers()), this, SLOT(updateStickers()));
|
||||
connect(&_sendActionStopTimer, SIGNAL(timeout()), this, SLOT(onCancelSendAction()));
|
||||
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout()));
|
||||
if (audioCapture()) {
|
||||
|
@ -3130,25 +3132,25 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
|||
_silent.hide();
|
||||
_cmdStart.hide();
|
||||
|
||||
_attachDocument.installEventFilter(&_attachType);
|
||||
_attachPhoto.installEventFilter(&_attachType);
|
||||
_attachEmoji.installEventFilter(&_emojiPan);
|
||||
_attachDocument.installEventFilter(_attachType);
|
||||
_attachPhoto.installEventFilter(_attachType);
|
||||
_attachEmoji.installEventFilter(_emojiPan);
|
||||
|
||||
connect(&_kbShow, SIGNAL(clicked()), this, SLOT(onKbToggle()));
|
||||
connect(&_kbHide, SIGNAL(clicked()), this, SLOT(onKbToggle()));
|
||||
connect(&_cmdStart, SIGNAL(clicked()), this, SLOT(onCmdStart()));
|
||||
|
||||
connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachDocument, lang(lng_attach_file))), SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
||||
connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachPhoto, lang(lng_attach_photo))), SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
||||
_attachType.hide();
|
||||
_emojiPan.hide();
|
||||
_attachDragDocument.hide();
|
||||
_attachDragPhoto.hide();
|
||||
connect(_attachType->addButton(new IconedButton(this, st::dropdownAttachDocument, lang(lng_attach_file))), SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
||||
connect(_attachType->addButton(new IconedButton(this, st::dropdownAttachPhoto, lang(lng_attach_photo))), SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
||||
_attachType->hide();
|
||||
_emojiPan->hide();
|
||||
_attachDragDocument->hide();
|
||||
_attachDragPhoto->hide();
|
||||
|
||||
_topShadow.hide();
|
||||
|
||||
connect(&_attachDragDocument, SIGNAL(dropped(const QMimeData*)), this, SLOT(onDocumentDrop(const QMimeData*)));
|
||||
connect(&_attachDragPhoto, SIGNAL(dropped(const QMimeData*)), this, SLOT(onPhotoDrop(const QMimeData*)));
|
||||
connect(_attachDragDocument, SIGNAL(dropped(const QMimeData*)), this, SLOT(onDocumentDrop(const QMimeData*)));
|
||||
connect(_attachDragPhoto, SIGNAL(dropped(const QMimeData*)), this, SLOT(onPhotoDrop(const QMimeData*)));
|
||||
|
||||
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
|
||||
|
||||
|
@ -3157,7 +3159,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
|||
|
||||
void HistoryWidget::start() {
|
||||
connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated()));
|
||||
connect(App::main(), SIGNAL(savedGifsUpdated()), &_emojiPan, SLOT(refreshSavedGifs()));
|
||||
connect(App::main(), SIGNAL(savedGifsUpdated()), _emojiPan, SLOT(refreshSavedGifs()));
|
||||
|
||||
updateRecentStickers();
|
||||
if (App::main()) emit App::main()->savedGifsUpdated();
|
||||
|
@ -3166,7 +3168,7 @@ void HistoryWidget::start() {
|
|||
}
|
||||
|
||||
void HistoryWidget::onStickersUpdated() {
|
||||
_emojiPan.refreshStickers();
|
||||
_emojiPan->refreshStickers();
|
||||
updateStickersByEmoji();
|
||||
}
|
||||
|
||||
|
@ -3228,9 +3230,9 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
|
|||
inlineBotChanged();
|
||||
}
|
||||
if (_inlineBot->username == cInlineGifBotUsername() && query.isEmpty()) {
|
||||
_emojiPan.clearInlineBot();
|
||||
_emojiPan->clearInlineBot();
|
||||
} else {
|
||||
_emojiPan.queryInlineBot(_inlineBot, _peer, query);
|
||||
_emojiPan->queryInlineBot(_inlineBot, _peer, query);
|
||||
}
|
||||
if (!_fieldAutocomplete->isHidden()) {
|
||||
_fieldAutocomplete->hideStart();
|
||||
|
@ -3450,11 +3452,11 @@ void HistoryWidget::updateSendAction(History *history, SendActionType type, int3
|
|||
}
|
||||
|
||||
void HistoryWidget::updateRecentStickers() {
|
||||
_emojiPan.refreshStickers();
|
||||
_emojiPan->refreshStickers();
|
||||
}
|
||||
|
||||
void HistoryWidget::stickersInstalled(uint64 setId) {
|
||||
_emojiPan.stickersInstalled(setId);
|
||||
_emojiPan->stickersInstalled(setId);
|
||||
}
|
||||
|
||||
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
|
||||
|
@ -4380,11 +4382,11 @@ void HistoryWidget::updateNotifySettings() {
|
|||
}
|
||||
|
||||
bool HistoryWidget::contentOverlapped(const QRect &globalRect) {
|
||||
return (_attachDragDocument.overlaps(globalRect) ||
|
||||
_attachDragPhoto.overlaps(globalRect) ||
|
||||
_attachType.overlaps(globalRect) ||
|
||||
return (_attachDragDocument->overlaps(globalRect) ||
|
||||
_attachDragPhoto->overlaps(globalRect) ||
|
||||
_attachType->overlaps(globalRect) ||
|
||||
_fieldAutocomplete->overlaps(globalRect) ||
|
||||
_emojiPan.overlaps(globalRect));
|
||||
_emojiPan->overlaps(globalRect));
|
||||
}
|
||||
|
||||
void HistoryWidget::updateReportSpamStatus() {
|
||||
|
@ -4516,8 +4518,8 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_cmdStart.hide();
|
||||
_attachType.hide();
|
||||
_emojiPan.hide();
|
||||
_attachType->hide();
|
||||
_emojiPan->hide();
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->cancel.hide();
|
||||
_pinnedBar->shadow.hide();
|
||||
|
@ -4579,8 +4581,8 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_cmdStart.hide();
|
||||
_attachType.hide();
|
||||
_emojiPan.hide();
|
||||
_attachType->hide();
|
||||
_emojiPan->hide();
|
||||
if (!_field.isHidden()) {
|
||||
_field.hide();
|
||||
resizeEvent(0);
|
||||
|
@ -4715,8 +4717,8 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_cmdStart.hide();
|
||||
_attachType.hide();
|
||||
_emojiPan.hide();
|
||||
_attachType->hide();
|
||||
_emojiPan->hide();
|
||||
_kbScroll.hide();
|
||||
if (!_field.isHidden()) {
|
||||
_field.hide();
|
||||
|
@ -5257,8 +5259,8 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
|||
onDraftSave();
|
||||
|
||||
if (!_fieldAutocomplete->isHidden()) _fieldAutocomplete->hideStart();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
if (!_attachType->isHidden()) _attachType->hideStart();
|
||||
if (!_emojiPan->isHidden()) _emojiPan->hideStart();
|
||||
|
||||
if (replyTo < 0) cancelReply(lastKeyboardUsed);
|
||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
||||
|
@ -5586,7 +5588,7 @@ void HistoryWidget::onPhotoSelect() {
|
|||
_attachDocument.clearState();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.show();
|
||||
_attachType.fastHide();
|
||||
_attachType->fastHide();
|
||||
|
||||
if (cDefaultAttach() != dbidaPhoto) {
|
||||
cSetDefaultAttach(dbidaPhoto);
|
||||
|
@ -5614,7 +5616,7 @@ void HistoryWidget::onDocumentSelect() {
|
|||
_attachPhoto.clearState();
|
||||
_attachPhoto.hide();
|
||||
_attachDocument.show();
|
||||
_attachType.fastHide();
|
||||
_attachType->fastHide();
|
||||
|
||||
if (cDefaultAttach() != dbidaDocument) {
|
||||
cSetDefaultAttach(dbidaDocument);
|
||||
|
@ -5651,14 +5653,14 @@ void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
|
|||
}
|
||||
|
||||
void HistoryWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto.isHidden() || !_attachDragDocument.isHidden()) {
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||
_attachDrag = DragStateNone;
|
||||
updateDragAreas();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::leaveEvent(QEvent *e) {
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto.isHidden() || !_attachDragDocument.isHidden()) {
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||
_attachDrag = DragStateNone;
|
||||
updateDragAreas();
|
||||
}
|
||||
|
@ -5706,7 +5708,7 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
|
|||
_replyForwardPressed = false;
|
||||
update(0, _field.y() - st::sendPadding - st::replyHeight, width(), st::replyHeight);
|
||||
}
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto.isHidden() || !_attachDragDocument.isHidden()) {
|
||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||
_attachDrag = DragStateNone;
|
||||
updateDragAreas();
|
||||
}
|
||||
|
@ -5961,24 +5963,24 @@ void HistoryWidget::updateDragAreas() {
|
|||
_field.setAcceptDrops(!_attachDrag);
|
||||
switch (_attachDrag) {
|
||||
case DragStateNone:
|
||||
_attachDragDocument.otherLeave();
|
||||
_attachDragPhoto.otherLeave();
|
||||
_attachDragDocument->otherLeave();
|
||||
_attachDragPhoto->otherLeave();
|
||||
break;
|
||||
case DragStateFiles:
|
||||
_attachDragDocument.otherEnter();
|
||||
_attachDragDocument.setText(lang(lng_drag_files_here), lang(lng_drag_to_send_files));
|
||||
_attachDragPhoto.fastHide();
|
||||
_attachDragDocument->otherEnter();
|
||||
_attachDragDocument->setText(lang(lng_drag_files_here), lang(lng_drag_to_send_files));
|
||||
_attachDragPhoto->fastHide();
|
||||
break;
|
||||
case DragStatePhotoFiles:
|
||||
_attachDragDocument.otherEnter();
|
||||
_attachDragDocument.setText(lang(lng_drag_images_here), lang(lng_drag_to_send_no_compression));
|
||||
_attachDragPhoto.otherEnter();
|
||||
_attachDragPhoto.setText(lang(lng_drag_photos_here), lang(lng_drag_to_send_quick));
|
||||
_attachDragDocument->otherEnter();
|
||||
_attachDragDocument->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_no_compression));
|
||||
_attachDragPhoto->otherEnter();
|
||||
_attachDragPhoto->setText(lang(lng_drag_photos_here), lang(lng_drag_to_send_quick));
|
||||
break;
|
||||
case DragStateImage:
|
||||
_attachDragDocument.fastHide();
|
||||
_attachDragPhoto.otherEnter();
|
||||
_attachDragPhoto.setText(lang(lng_drag_images_here), lang(lng_drag_to_send_quick));
|
||||
_attachDragDocument->fastHide();
|
||||
_attachDragPhoto->otherEnter();
|
||||
_attachDragPhoto->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_quick));
|
||||
break;
|
||||
};
|
||||
resizeEvent(0);
|
||||
|
@ -6460,8 +6462,8 @@ void HistoryWidget::moveFieldControls() {
|
|||
|
||||
right = w;
|
||||
_fieldBarCancel.move(right - _fieldBarCancel.width(), _field.y() - st::sendPadding - _fieldBarCancel.height());
|
||||
_attachType.move(0, _attachDocument.y() - _attachType.height());
|
||||
_emojiPan.moveBottom(_attachEmoji.y());
|
||||
_attachType->move(0, _attachDocument.y() - _attachType->height());
|
||||
_emojiPan->moveBottom(_attachEmoji.y());
|
||||
|
||||
_botStart.setGeometry(0, bottom - _botStart.height(), w, _botStart.height());
|
||||
_unblock.setGeometry(0, bottom - _unblock.height(), w, _unblock.height());
|
||||
|
@ -6491,7 +6493,7 @@ void HistoryWidget::clearInlineBot() {
|
|||
inlineBotChanged();
|
||||
_field.finishPlaceholder();
|
||||
}
|
||||
_emojiPan.clearInlineBot();
|
||||
_emojiPan->clearInlineBot();
|
||||
onCheckFieldAutocomplete();
|
||||
}
|
||||
|
||||
|
@ -6958,15 +6960,15 @@ void HistoryWidget::onUpdateHistoryItems() {
|
|||
}
|
||||
|
||||
void HistoryWidget::ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout) {
|
||||
_emojiPan.ui_repaintInlineItem(layout);
|
||||
_emojiPan->ui_repaintInlineItem(layout);
|
||||
}
|
||||
|
||||
bool HistoryWidget::ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout) {
|
||||
return _emojiPan.ui_isInlineItemVisible(layout);
|
||||
return _emojiPan->ui_isInlineItemVisible(layout);
|
||||
}
|
||||
|
||||
bool HistoryWidget::ui_isInlineItemBeingChosen() {
|
||||
return _emojiPan.ui_isInlineItemBeingChosen();
|
||||
return _emojiPan->ui_isInlineItemBeingChosen();
|
||||
}
|
||||
|
||||
PeerData *HistoryWidget::ui_getPeerForMouseAction() {
|
||||
|
@ -6980,7 +6982,7 @@ void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
|||
}
|
||||
|
||||
void HistoryWidget::notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) {
|
||||
_emojiPan.notify_inlineItemLayoutChanged(layout);
|
||||
_emojiPan->notify_inlineItemLayoutChanged(layout);
|
||||
}
|
||||
|
||||
void HistoryWidget::notify_handlePendingHistoryUpdate() {
|
||||
|
@ -7015,25 +7017,25 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
|||
|
||||
_historyToEnd->moveToRight(st::historyToDownPosition.x(), _scroll.y() + _scroll.height() - _historyToEnd->height() - st::historyToDownPosition.y());
|
||||
|
||||
_emojiPan.setMaxHeight(height() - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom() - _attachEmoji.height());
|
||||
_emojiPan->setMaxHeight(height() - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom() - _attachEmoji.height());
|
||||
if (_membersDropdown) {
|
||||
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
|
||||
}
|
||||
|
||||
switch (_attachDrag) {
|
||||
case DragStateFiles:
|
||||
_attachDragDocument.resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||
_attachDragDocument.move(st::dragMargin.left(), st::dragMargin.top());
|
||||
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
||||
break;
|
||||
case DragStatePhotoFiles:
|
||||
_attachDragDocument.resize(width() - st::dragMargin.left() - st::dragMargin.right(), (height() - st::dragMargin.top() - st::dragMargin.bottom()) / 2);
|
||||
_attachDragDocument.move(st::dragMargin.left(), st::dragMargin.top());
|
||||
_attachDragPhoto.resize(_attachDragDocument.width(), _attachDragDocument.height());
|
||||
_attachDragPhoto.move(st::dragMargin.left(), height() - _attachDragPhoto.height() - st::dragMargin.bottom());
|
||||
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), (height() - st::dragMargin.top() - st::dragMargin.bottom()) / 2);
|
||||
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
||||
_attachDragPhoto->resize(_attachDragDocument->width(), _attachDragDocument->height());
|
||||
_attachDragPhoto->move(st::dragMargin.left(), height() - _attachDragPhoto->height() - st::dragMargin.bottom());
|
||||
break;
|
||||
case DragStateImage:
|
||||
_attachDragPhoto.resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||
_attachDragPhoto.move(st::dragMargin.left(), st::dragMargin.top());
|
||||
_attachDragPhoto->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||
_attachDragPhoto->move(st::dragMargin.left(), st::dragMargin.top());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7530,8 +7532,8 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
|
|||
}
|
||||
|
||||
if (!_fieldAutocomplete->isHidden()) _fieldAutocomplete->hideStart();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
if (!_attachType->isHidden()) _attachType->hideStart();
|
||||
if (!_emojiPan->isHidden()) _emojiPan->hideStart();
|
||||
|
||||
_field.setFocus();
|
||||
}
|
||||
|
@ -7600,10 +7602,10 @@ bool HistoryWidget::pinnedMsgVisibilityUpdated() {
|
|||
if (_membersDropdown) {
|
||||
_membersDropdown->raise();
|
||||
}
|
||||
_attachType.raise();
|
||||
_emojiPan.raise();
|
||||
_attachDragDocument.raise();
|
||||
_attachDragPhoto.raise();
|
||||
_attachType->raise();
|
||||
_emojiPan->raise();
|
||||
_attachDragDocument->raise();
|
||||
_attachDragPhoto->raise();
|
||||
|
||||
updatePinnedBar();
|
||||
result = true;
|
||||
|
@ -7701,8 +7703,8 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
|
|||
}
|
||||
|
||||
if (!_fieldAutocomplete->isHidden()) _fieldAutocomplete->hideStart();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
if (!_attachType->isHidden()) _attachType->hideStart();
|
||||
if (!_emojiPan->isHidden()) _emojiPan->hideStart();
|
||||
|
||||
_field.setFocus();
|
||||
}
|
||||
|
@ -7747,8 +7749,8 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
|
|||
App::historyRegRandom(randomId, newId);
|
||||
|
||||
if (!_fieldAutocomplete->isHidden()) _fieldAutocomplete->hideStart();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
if (!_attachType->isHidden()) _attachType->hideStart();
|
||||
if (!_emojiPan->isHidden()) _emojiPan->hideStart();
|
||||
|
||||
_field.setFocus();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "localimageloader.h"
|
||||
#include "ui/boxshadow.h"
|
||||
#include "dropdown.h"
|
||||
#include "history/history_common.h"
|
||||
#include "history/field_autocomplete.h"
|
||||
#include "window/section_widget.h"
|
||||
|
@ -39,6 +38,10 @@ class HistoryDownButton;
|
|||
class InnerDropdown;
|
||||
} // namespace Ui
|
||||
|
||||
class Dropdown;
|
||||
class DragArea;
|
||||
class EmojiPan;
|
||||
|
||||
class HistoryWidget;
|
||||
class HistoryInner : public TWidget, public AbstractTooltipShower {
|
||||
Q_OBJECT
|
||||
|
@ -1124,10 +1127,10 @@ private:
|
|||
ChildWidget<Ui::InnerDropdown> _membersDropdown = { nullptr };
|
||||
QTimer _membersDropdownShowTimer;
|
||||
|
||||
Dropdown _attachType;
|
||||
EmojiPan _emojiPan;
|
||||
ChildWidget<Dropdown> _attachType;
|
||||
ChildWidget<EmojiPan> _emojiPan;
|
||||
DragState _attachDrag = DragStateNone;
|
||||
DragArea _attachDragDocument, _attachDragPhoto;
|
||||
ChildWidget<DragArea> _attachDragDocument, _attachDragPhoto;
|
||||
|
||||
int32 _selCount; // < 0 - text selected, focus list, not _field
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "window/section_widget.h"
|
||||
#include "window/top_bar_widget.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "dropdown.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
#include "dialogswidget.h"
|
||||
|
|
3704
Telegram/SourceFiles/stickers/emoji_pan.cpp
Normal file
3704
Telegram/SourceFiles/stickers/emoji_pan.cpp
Normal file
File diff suppressed because it is too large
Load diff
657
Telegram/SourceFiles/stickers/emoji_pan.h
Normal file
657
Telegram/SourceFiles/stickers/emoji_pan.h
Normal file
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/twidget.h"
|
||||
#include "ui/boxshadow.h"
|
||||
|
||||
namespace InlineBots {
|
||||
namespace Layout {
|
||||
class ItemBase;
|
||||
} // namespace Layout
|
||||
class Result;
|
||||
} // namespace InlineBots
|
||||
|
||||
namespace internal {
|
||||
|
||||
constexpr int InlineItemsMaxPerRow = 5;
|
||||
constexpr int EmojiColorsCount = 5;
|
||||
|
||||
using InlineResult = InlineBots::Result;
|
||||
using InlineResults = QList<InlineBots::Result*>;
|
||||
using InlineItem = InlineBots::Layout::ItemBase;
|
||||
|
||||
struct InlineCacheEntry {
|
||||
~InlineCacheEntry() {
|
||||
clearResults();
|
||||
}
|
||||
QString nextOffset;
|
||||
QString switchPmText, switchPmStartToken;
|
||||
InlineResults results; // owns this results list
|
||||
void clearResults();
|
||||
};
|
||||
|
||||
class EmojiColorPicker : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiColorPicker();
|
||||
|
||||
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);
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
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 = false;
|
||||
|
||||
EmojiPtr _variants[EmojiColorsCount + 1];
|
||||
|
||||
typedef QMap<int32, uint64> EmojiAnimations; // index - showing, -index - hiding
|
||||
EmojiAnimations _emojiAnimations;
|
||||
Animation _a_selected;
|
||||
|
||||
float64 _hovers[EmojiColorsCount + 1];
|
||||
|
||||
int _selected = -1;
|
||||
int _pressedSel = -1;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
bool _hiding = false;
|
||||
QPixmap _cache;
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
Animation _a_appearance;
|
||||
|
||||
QTimer _hideTimer;
|
||||
|
||||
BoxShadow _shadow;
|
||||
|
||||
};
|
||||
|
||||
class EmojiPanel;
|
||||
class EmojiPanInner : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmojiPanInner();
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
void hideFinish();
|
||||
|
||||
void showEmojiPack(DBIEmojiTab packIndex);
|
||||
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
DBIEmojiTab currentTab(int yOffset) const;
|
||||
|
||||
void refreshRecent();
|
||||
|
||||
void setScrollTop(int top);
|
||||
|
||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||
|
||||
public slots:
|
||||
|
||||
void updateSelected();
|
||||
|
||||
void onShowPicker();
|
||||
void onPickerHidden();
|
||||
void onColorSelected(EmojiPtr emoji);
|
||||
|
||||
bool checkPickerHide();
|
||||
|
||||
signals:
|
||||
|
||||
void selected(EmojiPtr emoji);
|
||||
|
||||
void switchToStickers();
|
||||
|
||||
void scrollToY(int y);
|
||||
void disableScroll(bool dis);
|
||||
|
||||
void needRefreshPanels();
|
||||
void saveConfigDelayed(int32 delay);
|
||||
|
||||
private:
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
int countHeight();
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
|
||||
QRect emojiRect(int tab, int sel);
|
||||
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _animations;
|
||||
Animation _a_selected;
|
||||
|
||||
int _top = 0, _counts[emojiTabCount];
|
||||
|
||||
QVector<EmojiPtr> _emojis[emojiTabCount];
|
||||
QVector<float64> _hovers[emojiTabCount];
|
||||
|
||||
int32 _esize;
|
||||
|
||||
int _selected = -1;
|
||||
int _pressedSel = -1;
|
||||
int _pickerSel = -1;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
EmojiColorPicker _picker;
|
||||
QTimer _showPickerTimer;
|
||||
};
|
||||
|
||||
struct StickerIcon {
|
||||
StickerIcon(uint64 setId) : setId(setId) {
|
||||
}
|
||||
StickerIcon(uint64 setId, DocumentData *sticker, int32 pixw, int32 pixh) : setId(setId), sticker(sticker), pixw(pixw), pixh(pixh) {
|
||||
}
|
||||
uint64 setId;
|
||||
DocumentData *sticker = nullptr;
|
||||
int pixw = 0;
|
||||
int pixh = 0;
|
||||
};
|
||||
|
||||
class StickerPanInner : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
StickerPanInner();
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||
|
||||
void step_selected(uint64 ms, bool timer);
|
||||
|
||||
void hideFinish(bool completely);
|
||||
void showFinish();
|
||||
void showStickerSet(uint64 setId);
|
||||
void updateShowingSavedGifs();
|
||||
|
||||
bool showSectionIcons() const;
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
void refreshStickers();
|
||||
void refreshRecentStickers(bool resize = true);
|
||||
void refreshSavedGifs();
|
||||
int refreshInlineRows(UserData *bot, const InlineCacheEntry *results, bool resultsDeleted);
|
||||
void refreshRecent();
|
||||
void inlineBotChanged();
|
||||
void hideInlineRowsPanel();
|
||||
void clearInlineRowsPanel();
|
||||
|
||||
void fillIcons(QList<StickerIcon> &icons);
|
||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||
|
||||
void setScrollTop(int top);
|
||||
void preloadImages();
|
||||
|
||||
uint64 currentSet(int yOffset) const;
|
||||
|
||||
void notify_inlineItemLayoutChanged(const InlineItem *layout);
|
||||
void ui_repaintInlineItem(const InlineItem *layout);
|
||||
bool ui_isInlineItemVisible(const InlineItem *layout);
|
||||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
bool inlineResultsShown() const {
|
||||
return (_section == Section::Inlines);
|
||||
}
|
||||
int countHeight(bool plain = false);
|
||||
|
||||
~StickerPanInner();
|
||||
|
||||
private slots:
|
||||
void updateSelected();
|
||||
void onSettings();
|
||||
void onPreview();
|
||||
void onUpdateInlineItems();
|
||||
void onSwitchPm();
|
||||
|
||||
signals:
|
||||
void selected(DocumentData *sticker);
|
||||
void selected(PhotoData *photo);
|
||||
void selected(InlineBots::Result *result, UserData *bot);
|
||||
|
||||
void displaySet(quint64 setId);
|
||||
void installSet(quint64 setId);
|
||||
void removeSet(quint64 setId);
|
||||
|
||||
void refreshIcons();
|
||||
void emptyInlineRows();
|
||||
|
||||
void switchToEmoji();
|
||||
|
||||
void scrollToY(int y);
|
||||
void scrollUpdated();
|
||||
void disableScroll(bool dis);
|
||||
void needRefreshPanels();
|
||||
|
||||
void saveConfigDelayed(int32 delay);
|
||||
|
||||
private:
|
||||
struct Set {
|
||||
Set(uint64 id, MTPDstickerSet::Flags flags, const QString &title, int32 hoversSize, const StickerPack &pack = StickerPack()) : id(id), flags(flags), title(title), hovers(hoversSize, 0), pack(pack) {
|
||||
}
|
||||
uint64 id;
|
||||
MTPDstickerSet::Flags flags;
|
||||
QString title;
|
||||
QVector<float64> hovers;
|
||||
StickerPack pack;
|
||||
};
|
||||
using Sets = QList<Set>;
|
||||
Sets &shownSets() {
|
||||
return (_section == Section::Featured) ? _featuredSets : _mySets;
|
||||
}
|
||||
const Sets &shownSets() const {
|
||||
return const_cast<StickerPanInner*>(this)->shownSets();
|
||||
}
|
||||
int featuredRowHeight() const;
|
||||
|
||||
bool showingInlineItems() const { // Gifs or Inline results
|
||||
return (_section == Section::Inlines) || (_section == Section::Gifs);
|
||||
}
|
||||
|
||||
void paintInlineItems(Painter &p, const QRect &r);
|
||||
void paintStickers(Painter &p, const QRect &r);
|
||||
void paintSticker(Painter &p, Set &set, int y, int index);
|
||||
bool featuredHasAddButton(int index) const;
|
||||
int featuredContentWidth() const;
|
||||
QRect featuredAddRect(int y) const;
|
||||
|
||||
void refreshSwitchPmButton(const InlineCacheEntry *entry);
|
||||
|
||||
void appendSet(Sets &to, uint64 setId);
|
||||
|
||||
void selectEmoji(EmojiPtr emoji);
|
||||
QRect stickerRect(int tab, int sel);
|
||||
|
||||
int32 _maxHeight;
|
||||
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _animations;
|
||||
Animation _a_selected;
|
||||
|
||||
int _top = 0;
|
||||
|
||||
Sets _mySets;
|
||||
Sets _featuredSets;
|
||||
QList<bool> _custom;
|
||||
|
||||
enum class Section {
|
||||
Inlines,
|
||||
Gifs,
|
||||
Featured,
|
||||
Stickers,
|
||||
};
|
||||
Section _section = Section::Stickers;
|
||||
bool _setGifCommand = false;
|
||||
UserData *_inlineBot;
|
||||
QString _inlineBotTitle;
|
||||
uint64 _lastScrolled = 0;
|
||||
QTimer _updateInlineItems;
|
||||
bool _inlineWithThumb = false;
|
||||
|
||||
std_::unique_ptr<BoxButton> _switchPmButton;
|
||||
QString _switchPmStartToken;
|
||||
|
||||
typedef QVector<InlineItem*> InlineItems;
|
||||
struct InlineRow {
|
||||
InlineRow() : height(0) {
|
||||
}
|
||||
int32 height;
|
||||
InlineItems items;
|
||||
};
|
||||
typedef QVector<InlineRow> InlineRows;
|
||||
InlineRows _inlineRows;
|
||||
void clearInlineRows(bool resultsDeleted);
|
||||
|
||||
using GifLayouts = QMap<DocumentData*, InlineItem*>;
|
||||
GifLayouts _gifLayouts;
|
||||
InlineItem *layoutPrepareSavedGif(DocumentData *doc, int32 position);
|
||||
|
||||
using InlineLayouts = QMap<InlineResult*, InlineItem*>;
|
||||
InlineLayouts _inlineLayouts;
|
||||
InlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
||||
|
||||
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
||||
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
||||
|
||||
InlineRow &layoutInlineRow(InlineRow &row, int32 sumWidth = 0);
|
||||
void deleteUnusedGifLayouts();
|
||||
|
||||
void deleteUnusedInlineLayouts();
|
||||
|
||||
int validateExistingInlineRows(const InlineResults &results);
|
||||
void selectInlineResult(int row, int column);
|
||||
void removeRecentSticker(int tab, int index);
|
||||
|
||||
int _selected = -1;
|
||||
int _pressed = -1;
|
||||
int _selectedFeaturedSet = -1;
|
||||
int _pressedFeaturedSet = -1;
|
||||
int _selectedFeaturedSetAdd = -1;
|
||||
int _pressedFeaturedSetAdd = -1;
|
||||
QPoint _lastMousePos;
|
||||
|
||||
QString _addText;
|
||||
int _addWidth;
|
||||
|
||||
LinkButton _settings;
|
||||
|
||||
QTimer _previewTimer;
|
||||
bool _previewShown = false;
|
||||
};
|
||||
|
||||
class EmojiPanel : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool special, int32 wantedY); // Stickers::NoneSetId if in emoji
|
||||
void setText(const QString &text);
|
||||
void setDeleteVisible(bool isVisible);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
|
||||
int32 wantedY() const {
|
||||
return _wantedY;
|
||||
}
|
||||
void setWantedY(int32 y) {
|
||||
_wantedY = y;
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void deleteClicked(quint64 setId);
|
||||
void mousePressed();
|
||||
|
||||
public slots:
|
||||
|
||||
void onDelete();
|
||||
|
||||
private:
|
||||
|
||||
void updateText();
|
||||
|
||||
int32 _wantedY;
|
||||
QString _text, _fullText;
|
||||
uint64 _setId;
|
||||
bool _special, _deleteVisible;
|
||||
IconedButton *_delete;
|
||||
|
||||
};
|
||||
|
||||
class EmojiSwitchButton : public Button {
|
||||
public:
|
||||
|
||||
EmojiSwitchButton(QWidget *parent, bool toStickers); // otherwise toEmoji
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void updateText(const QString &inlineBotUsername = QString());
|
||||
|
||||
protected:
|
||||
|
||||
bool _toStickers;
|
||||
QString _text;
|
||||
int32 _textWidth;
|
||||
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
class EmojiPan : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmojiPan(QWidget *parent);
|
||||
|
||||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void moveBottom(int32 bottom, bool force = false);
|
||||
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void otherEnter();
|
||||
void otherLeave();
|
||||
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
bool event(QEvent *e);
|
||||
|
||||
void fastHide();
|
||||
bool hiding() const {
|
||||
return _hiding || _hideTimer.isActive();
|
||||
}
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void step_slide(float64 ms, bool timer);
|
||||
void step_icons(uint64 ms, bool timer);
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
void stickersInstalled(uint64 setId);
|
||||
|
||||
void queryInlineBot(UserData *bot, PeerData *peer, QString query);
|
||||
void clearInlineBot();
|
||||
|
||||
bool overlaps(const QRect &globalRect) {
|
||||
if (isHidden() || !_cache.isNull()) return false;
|
||||
|
||||
return QRect(st::dropdownDef.padding.left(),
|
||||
st::dropdownDef.padding.top(),
|
||||
_width - st::dropdownDef.padding.left() - st::dropdownDef.padding.right(),
|
||||
_height - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom()
|
||||
).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
||||
}
|
||||
|
||||
void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout);
|
||||
void ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout);
|
||||
bool ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout);
|
||||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
bool inlineResultsShown() const {
|
||||
return s_inner.inlineResultsShown();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void refreshStickers();
|
||||
void refreshSavedGifs();
|
||||
|
||||
void hideStart();
|
||||
void hideFinish();
|
||||
|
||||
void showStart();
|
||||
void onWndActiveChanged();
|
||||
|
||||
void onTabChange();
|
||||
void onScrollEmoji();
|
||||
void onScrollStickers();
|
||||
void onSwitch();
|
||||
|
||||
void onDisplaySet(quint64 setId);
|
||||
void onInstallSet(quint64 setId);
|
||||
void onRemoveSet(quint64 setId);
|
||||
void onRemoveSetSure();
|
||||
void onDelayedHide();
|
||||
|
||||
void onRefreshIcons();
|
||||
void onRefreshPanels();
|
||||
|
||||
void onSaveConfig();
|
||||
void onSaveConfigDelayed(int32 delay);
|
||||
|
||||
void onInlineRequest();
|
||||
void onEmptyInlineRows();
|
||||
|
||||
signals:
|
||||
void emojiSelected(EmojiPtr emoji);
|
||||
void stickerSelected(DocumentData *sticker);
|
||||
void photoSelected(PhotoData *photo);
|
||||
void inlineResultSelected(InlineBots::Result *result, UserData *bot);
|
||||
|
||||
void updateStickers();
|
||||
|
||||
private:
|
||||
bool preventAutoHide() const;
|
||||
void installSetDone(const MTPmessages_StickerSetInstallResult &result);
|
||||
bool installSetFail(uint64 setId, const RPCError &error);
|
||||
|
||||
void paintStickerSettingsIcon(Painter &p) const;
|
||||
void paintFeaturedStickerSetsBadge(Painter &p, int iconLeft) const;
|
||||
|
||||
void validateSelectedIcon(bool animated = false);
|
||||
void updateContentHeight();
|
||||
|
||||
void leaveToChildEvent(QEvent *e, QWidget *child);
|
||||
void hideAnimated();
|
||||
void prepareShowHideCache();
|
||||
|
||||
void updateSelected();
|
||||
void updateIcons();
|
||||
|
||||
void prepareTab(int32 &left, int32 top, int32 _width, FlatRadiobutton &tab);
|
||||
void updatePanelsPositions(const QVector<internal::EmojiPanel*> &panels, int32 st);
|
||||
|
||||
void showAll();
|
||||
void hideAll();
|
||||
|
||||
int32 _maxHeight, _contentMaxHeight, _contentHeight, _contentHeightEmoji, _contentHeightStickers;
|
||||
bool _horizontal = false;
|
||||
|
||||
bool _noTabUpdate = false;
|
||||
|
||||
int32 _width, _height, _bottom;
|
||||
bool _hiding = false;
|
||||
QPixmap _cache;
|
||||
|
||||
anim::fvalue a_opacity = { 0. };
|
||||
Animation _a_appearance;
|
||||
|
||||
QTimer _hideTimer;
|
||||
|
||||
BoxShadow _shadow;
|
||||
|
||||
FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols;
|
||||
QList<internal::StickerIcon> _icons;
|
||||
QVector<float64> _iconHovers;
|
||||
int _iconOver = -1;
|
||||
int _iconSel = 0;
|
||||
int _iconDown = -1;
|
||||
bool _iconsDragging = false;
|
||||
typedef QMap<int32, uint64> Animations; // index - showing, -index - hiding
|
||||
Animations _iconAnimations;
|
||||
Animation _a_icons;
|
||||
QPoint _iconsMousePos, _iconsMouseDown;
|
||||
int _iconsLeft = 0;
|
||||
int _iconsTop = 0;
|
||||
int _iconsStartX = 0;
|
||||
int _iconsMax = 0;
|
||||
anim::ivalue _iconsX = { 0, 0 };
|
||||
anim::ivalue _iconSelX = { 0, 0 };
|
||||
uint64 _iconsStartAnim = 0;
|
||||
|
||||
bool _stickersShown = false;
|
||||
bool _shownFromInlineQuery = false;
|
||||
QPixmap _fromCache, _toCache;
|
||||
anim::ivalue a_fromCoord, a_toCoord;
|
||||
anim::fvalue a_fromAlpha, a_toAlpha;
|
||||
Animation _a_slide;
|
||||
|
||||
ScrollArea e_scroll;
|
||||
internal::EmojiPanInner e_inner;
|
||||
QVector<internal::EmojiPanel*> e_panels;
|
||||
internal::EmojiSwitchButton e_switch;
|
||||
ScrollArea s_scroll;
|
||||
internal::StickerPanInner s_inner;
|
||||
QVector<internal::EmojiPanel*> s_panels;
|
||||
internal::EmojiSwitchButton s_switch;
|
||||
|
||||
uint64 _displayingSetId = 0;
|
||||
uint64 _removingSetId = 0;
|
||||
|
||||
QTimer _saveConfigTimer;
|
||||
|
||||
// inline bots
|
||||
typedef QMap<QString, internal::InlineCacheEntry*> InlineCache;
|
||||
InlineCache _inlineCache;
|
||||
QTimer _inlineRequestTimer;
|
||||
|
||||
void inlineBotChanged();
|
||||
int32 showInlineRows(bool newResults);
|
||||
bool hideOnNoInlineResults();
|
||||
void recountContentMaxHeight();
|
||||
bool refreshInlineRows(int32 *added = 0);
|
||||
UserData *_inlineBot = nullptr;
|
||||
PeerData *_inlineQueryPeer = nullptr;
|
||||
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
||||
mtpRequestId _inlineRequestId = 0;
|
||||
void inlineResultsDone(const MTPmessages_BotResults &result);
|
||||
bool inlineResultsFail(const RPCError &error);
|
||||
|
||||
};
|
143
Telegram/SourceFiles/stickers/stickers.cpp
Normal file
143
Telegram/SourceFiles/stickers/stickers.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "lang.h"
|
||||
|
||||
#include "boxes/stickersetbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "apiwrap.h"
|
||||
#include "localstorage.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
namespace Stickers {
|
||||
|
||||
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
|
||||
auto &v = d.vsets.c_vector().v;
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
Stickers::Order archived;
|
||||
archived.reserve(v.size());
|
||||
QMap<uint64, uint64> setsToRequest;
|
||||
for_const (auto &stickerSet, v) {
|
||||
const MTPDstickerSet *setData = nullptr;
|
||||
switch (stickerSet.type()) {
|
||||
case mtpc_stickerSetCovered: {
|
||||
auto &d = stickerSet.c_stickerSetCovered();
|
||||
if (d.vset.type() == mtpc_stickerSet) {
|
||||
setData = &d.vset.c_stickerSet();
|
||||
}
|
||||
} break;
|
||||
case mtpc_stickerSetMultiCovered: {
|
||||
auto &d = stickerSet.c_stickerSetMultiCovered();
|
||||
if (d.vset.type() == mtpc_stickerSet) {
|
||||
setData = &d.vset.c_stickerSet();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if (setData) {
|
||||
auto set = Stickers::feedSet(*setData);
|
||||
if (set->stickers.isEmpty()) {
|
||||
setsToRequest.insert(set->id, set->access);
|
||||
}
|
||||
auto index = order.indexOf(set->id);
|
||||
if (index >= 0) {
|
||||
order.removeAt(index);
|
||||
}
|
||||
archived.push_back(set->id);
|
||||
}
|
||||
}
|
||||
if (!setsToRequest.isEmpty()) {
|
||||
for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
||||
App::api()->scheduleStickerSetRequest(i.key(), i.value());
|
||||
}
|
||||
App::api()->requestStickerSets();
|
||||
}
|
||||
Local::writeInstalledStickers();
|
||||
Local::writeArchivedStickers();
|
||||
Ui::showLayer(new StickersBox(archived), KeepOtherLayers);
|
||||
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
void installLocally(uint64 setId) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto flags = it->flags;
|
||||
it->flags &= ~(MTPDstickerSet::Flag::f_archived | MTPDstickerSet_ClientFlag::f_unread);
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
auto changedFlags = flags ^ it->flags;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int insertAtIndex = 0, currentIndex = order.indexOf(setId);
|
||||
if (currentIndex != insertAtIndex) {
|
||||
if (currentIndex > 0) {
|
||||
order.removeAt(currentIndex);
|
||||
}
|
||||
order.insert(insertAtIndex, setId);
|
||||
}
|
||||
|
||||
auto custom = sets.find(Stickers::CustomSetId);
|
||||
if (custom != sets.cend()) {
|
||||
for_const (auto sticker, it->stickers) {
|
||||
int removeIndex = custom->stickers.indexOf(sticker);
|
||||
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||
}
|
||||
if (custom->stickers.isEmpty()) {
|
||||
sets.erase(custom);
|
||||
}
|
||||
}
|
||||
Local::writeInstalledStickers();
|
||||
if (changedFlags & MTPDstickerSet_ClientFlag::f_unread) Local::writeFeaturedStickers();
|
||||
if (changedFlags & MTPDstickerSet::Flag::f_archived) {
|
||||
auto index = Global::RefArchivedStickerSetsOrder().indexOf(setId);
|
||||
if (index >= 0) {
|
||||
Global::RefArchivedStickerSetsOrder().removeAt(index);
|
||||
Local::writeArchivedStickers();
|
||||
}
|
||||
}
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
void undoInstallLocally(uint64 setId) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
it->flags &= ~MTPDstickerSet::Flag::f_installed;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int currentIndex = order.indexOf(setId);
|
||||
if (currentIndex >= 0) {
|
||||
order.removeAt(currentIndex);
|
||||
}
|
||||
|
||||
Local::writeInstalledStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
|
||||
Ui::showLayer(new InformBox(lang(lng_stickers_not_found)), KeepOtherLayers);
|
||||
}
|
||||
|
||||
} // namespace Stickers
|
29
Telegram/SourceFiles/stickers/stickers.h
Normal file
29
Telegram/SourceFiles/stickers/stickers.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Stickers {
|
||||
|
||||
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d);
|
||||
void installLocally(uint64 setId);
|
||||
void undoInstallLocally(uint64 setId);
|
||||
|
||||
} // namespace Stickers
|
39
Telegram/SourceFiles/stickers/stickers.style
Normal file
39
Telegram/SourceFiles/stickers/stickers.style
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
using "basic.style";
|
||||
|
||||
featuredStickersHeader: 45px;
|
||||
featuredStickersSkip: 15px;
|
||||
|
||||
featuredStickersHeaderFont: semiboldFont;
|
||||
featuredStickersHeaderFg: windowTextFg;
|
||||
featuredStickersHeaderTop: 0px;
|
||||
featuredStickersSubheaderFont: normalFont;
|
||||
featuredStickersSubheaderFg: #777;
|
||||
featuredStickersSubheaderTop: 20px;
|
||||
|
||||
featuredStickersAddTop: 3px;
|
||||
featuredStickersAdd: RoundButton(defaultActiveButton) {
|
||||
width: -17px;
|
||||
height: 26px;
|
||||
textTop: 4px;
|
||||
downTextTop: 5px;
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
'<(src_loc)/overview/overview.style',
|
||||
'<(src_loc)/profile/profile.style',
|
||||
'<(src_loc)/settings/settings.style',
|
||||
'<(src_loc)/stickers/stickers.style',
|
||||
'<(src_loc)/ui/widgets/widgets.style',
|
||||
],
|
||||
'langpacks': [
|
||||
|
@ -377,6 +378,10 @@
|
|||
'<(src_loc)/settings/settings_scale_widget.h',
|
||||
'<(src_loc)/settings/settings_widget.cpp',
|
||||
'<(src_loc)/settings/settings_widget.h',
|
||||
'<(src_loc)/stickers/emoji_pan.cpp',
|
||||
'<(src_loc)/stickers/emoji_pan.h',
|
||||
'<(src_loc)/stickers/stickers.cpp',
|
||||
'<(src_loc)/stickers/stickers.h',
|
||||
'<(src_loc)/ui/buttons/history_down_button.cpp',
|
||||
'<(src_loc)/ui/buttons/history_down_button.h',
|
||||
'<(src_loc)/ui/buttons/icon_button.cpp',
|
||||
|
|
|
@ -39,11 +39,6 @@
|
|||
'lib_exif',
|
||||
'OpenAL32',
|
||||
'common',
|
||||
'libavformat/libavformat.a',
|
||||
'libavcodec/libavcodec.a',
|
||||
'libavutil/libavutil.a',
|
||||
'libswresample/libswresample.a',
|
||||
'libswscale/libswscale.a',
|
||||
'opus',
|
||||
'celt',
|
||||
'silk_common',
|
||||
|
@ -52,6 +47,17 @@
|
|||
'lib/exception_handler',
|
||||
'lib/crash_generation_client',
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCLinkerTool': {
|
||||
'AdditionalOptions': [
|
||||
'libavformat/libavformat.a',
|
||||
'libavcodec/libavcodec.a',
|
||||
'libavutil/libavutil.a',
|
||||
'libswresample/libswresample.a',
|
||||
'libswscale/libswscale.a',
|
||||
],
|
||||
},
|
||||
},
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'include_dirs': [
|
||||
|
|
Loading…
Add table
Reference in a new issue