Enabled sending stickers from the sticker set preview box.

This commit is contained in:
John Preston 2016-09-11 11:38:14 +03:00
parent 8419a56e10
commit c7e8b153bb
6 changed files with 98 additions and 29 deletions

View File

@ -39,7 +39,7 @@ constexpr int kArchivedLimitPerPage = 30;
} // namespace } // namespace
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget() StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : ScrolledWidget()
, _input(set) { , _input(set) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
switch (set.type()) { switch (set.type()) {
@ -49,6 +49,8 @@ StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget()
MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet)); MTP::send(MTPmessages_GetStickerSet(_input), rpcDone(&StickerSetInner::gotSet), rpcFail(&StickerSetInner::failedSet));
App::main()->updateStickers(); App::main()->updateStickers();
setMouseTracking(true);
_previewTimer.setSingleShot(true); _previewTimer.setSingleShot(true);
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview())); connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
} }
@ -56,15 +58,20 @@ StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget()
void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) { void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
_pack.clear(); _pack.clear();
_emoji.clear(); _emoji.clear();
_packOvers.clear();
_selected = -1;
setCursor(style::cur_default);
if (set.type() == mtpc_messages_stickerSet) { if (set.type() == mtpc_messages_stickerSet) {
auto &d(set.c_messages_stickerSet()); auto &d(set.c_messages_stickerSet());
auto &v(d.vdocuments.c_vector().v); auto &v(d.vdocuments.c_vector().v);
_pack.reserve(v.size()); _pack.reserve(v.size());
_packOvers.reserve(v.size());
for (int i = 0, l = v.size(); i < l; ++i) { for (int i = 0, l = v.size(); i < l; ++i) {
auto doc = App::feedDocument(v.at(i)); auto doc = App::feedDocument(v.at(i));
if (!doc || !doc->sticker()) continue; if (!doc || !doc->sticker()) continue;
_pack.push_back(doc); _pack.push_back(doc);
_packOvers.push_back(FloatAnimation());
} }
auto &packs(d.vpacks.c_vector().v); auto &packs(d.vpacks.c_vector().v);
for (int i = 0, l = packs.size(); i < l; ++i) { for (int i = 0, l = packs.size(); i < l; ++i) {
@ -113,6 +120,8 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
} }
_loaded = true; _loaded = true;
updateSelected();
emit updateButtons(); emit updateButtons();
} }
@ -188,15 +197,16 @@ bool StickerSetInner::installFail(const RPCError &error) {
} }
void StickerSetInner::mousePressEvent(QMouseEvent *e) { void StickerSetInner::mousePressEvent(QMouseEvent *e) {
int32 index = stickerFromGlobalPos(e->globalPos()); int index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size()) { if (index >= 0 && index < _pack.size()) {
_previewTimer.start(QApplication::startDragTime()); _previewTimer.start(QApplication::startDragTime());
} }
} }
void StickerSetInner::mouseMoveEvent(QMouseEvent *e) { void StickerSetInner::mouseMoveEvent(QMouseEvent *e) {
updateSelected();
if (_previewShown >= 0) { if (_previewShown >= 0) {
int32 index = stickerFromGlobalPos(e->globalPos()); int index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size() && index != _previewShown) { if (index >= 0 && index < _pack.size() && index != _previewShown) {
_previewShown = index; _previewShown = index;
Ui::showMediaPreview(_pack.at(_previewShown)); Ui::showMediaPreview(_pack.at(_previewShown));
@ -205,11 +215,47 @@ void StickerSetInner::mouseMoveEvent(QMouseEvent *e) {
} }
void StickerSetInner::mouseReleaseEvent(QMouseEvent *e) { void StickerSetInner::mouseReleaseEvent(QMouseEvent *e) {
_previewTimer.stop(); if (_previewShown >= 0) {
_previewShown = -1;
return;
}
if (_previewTimer.isActive()) {
_previewTimer.stop();
int index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size()) {
if (auto main = App::main()) {
if (main->onSendSticker(_pack.at(index))) {
Ui::hideSettingsAndLayer();
}
}
}
}
}
void StickerSetInner::updateSelected() {
auto index = stickerFromGlobalPos(QCursor::pos());
if (index != _selected) {
startOverAnimation(_selected, 1., 0.);
_selected = index;
startOverAnimation(_selected, 0., 1.);
setCursor(_selected >= 0 ? style::cur_pointer : style::cur_default);
}
}
void StickerSetInner::startOverAnimation(int index, float64 from, float64 to) {
if (index >= 0 && index < _packOvers.size()) {
START_ANIMATION(_packOvers[index], func([this, index]() {
int row = index / StickerPanPerRow;
int column = index % StickerPanPerRow;
int left = st::stickersPadding.left() + column * st::stickersSize.width();
int top = st::stickersPadding.top() + row * st::stickersSize.height();
rtlupdate(left, top, st::stickersSize.width(), st::stickersSize.height());
}), from, to, st::emojiPanDuration, anim::linear);
}
} }
void StickerSetInner::onPreview() { void StickerSetInner::onPreview() {
int32 index = stickerFromGlobalPos(QCursor::pos()); int index = stickerFromGlobalPos(QCursor::pos());
if (index >= 0 && index < _pack.size()) { if (index >= 0 && index < _pack.size()) {
_previewShown = index; _previewShown = index;
Ui::showMediaPreview(_pack.at(_previewShown)); Ui::showMediaPreview(_pack.at(_previewShown));
@ -241,10 +287,19 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
for (int32 j = 0; j < StickerPanPerRow; ++j) { for (int32 j = 0; j < StickerPanPerRow; ++j) {
int32 index = i * StickerPanPerRow + j; int32 index = i * StickerPanPerRow + j;
if (index >= _pack.size()) break; if (index >= _pack.size()) break;
t_assert(index < _packOvers.size());
DocumentData *doc = _pack.at(index); DocumentData *doc = _pack.at(index);
QPoint pos(st::stickersPadding.left() + j * st::stickersSize.width(), st::stickersPadding.top() + i * st::stickersSize.height()); QPoint pos(st::stickersPadding.left() + j * st::stickersSize.width(), st::stickersPadding.top() + i * st::stickersSize.height());
if (auto over = _packOvers[index].current((index == _selected) ? 1. : 0.)) {
p.setOpacity(over);
QPoint tl(pos);
if (rtl()) tl.setX(width() - tl.x() - st::stickersSize.width());
App::roundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, StickerHoverCorners);
p.setOpacity(1);
}
bool goodThumb = !doc->thumb->isNull() && ((doc->thumb->width() >= 128) || (doc->thumb->height() >= 128)); bool goodThumb = !doc->thumb->isNull() && ((doc->thumb->width() >= 128) || (doc->thumb->height() >= 128));
if (goodThumb) { if (goodThumb) {
doc->thumb->load(); doc->thumb->load();
@ -272,10 +327,9 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
} }
} }
void StickerSetInner::setScrollBottom(int32 bottom) { void StickerSetInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
if (bottom == _bottom) return; _visibleTop = visibleTop;
_visibleBottom = visibleBottom;
_bottom = bottom;
} }
bool StickerSetInner::loaded() const { bool StickerSetInner::loaded() const {
@ -364,7 +418,9 @@ void StickerSetBox::onUpdateButtons() {
} }
void StickerSetBox::onScroll() { void StickerSetBox::onScroll() {
_inner.setScrollBottom(scrollArea()->scrollTop() + scrollArea()->height()); auto scroll = scrollArea();
auto scrollTop = scroll->scrollTop();
_inner.setVisibleTopBottom(scrollTop, scrollTop + scroll->height());
} }
void StickerSetBox::showAll() { void StickerSetBox::showAll() {

View File

@ -24,30 +24,30 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
class ConfirmBox; class ConfirmBox;
class StickerSetInner : public TWidget, public RPCSender { class StickerSetInner : public ScrolledWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
StickerSetInner(const MTPInputStickerSet &set); StickerSetInner(const MTPInputStickerSet &set);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void paintEvent(QPaintEvent *e);
bool loaded() const; bool loaded() const;
int32 notInstalled() const; int32 notInstalled() const;
bool official() const; bool official() const;
QString title() const; QString title() const;
QString shortName() const; QString shortName() const;
void setScrollBottom(int32 bottom); void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
void install(); void install();
~StickerSetInner(); ~StickerSetInner();
public slots: protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void paintEvent(QPaintEvent *e) override;
private slots:
void onPreview(); void onPreview();
signals: signals:
@ -55,7 +55,9 @@ signals:
void installed(uint64 id); void installed(uint64 id);
private: private:
int32 stickerFromGlobalPos(const QPoint &p) const; void updateSelected();
void startOverAnimation(int index, float64 from, float64 to);
int stickerFromGlobalPos(const QPoint &p) const;
void gotSet(const MTPmessages_StickerSet &set); void gotSet(const MTPmessages_StickerSet &set);
bool failedSet(const RPCError &error); bool failedSet(const RPCError &error);
@ -63,6 +65,7 @@ private:
void installDone(const MTPmessages_StickerSetInstallResult &result); void installDone(const MTPmessages_StickerSetInstallResult &result);
bool installFail(const RPCError &error); bool installFail(const RPCError &error);
QVector<FloatAnimation> _packOvers;
StickerPack _pack; StickerPack _pack;
StickersByEmojiMap _emoji; StickersByEmojiMap _emoji;
bool _loaded = false; bool _loaded = false;
@ -73,13 +76,17 @@ private:
int32 _setHash = 0; int32 _setHash = 0;
MTPDstickerSet::Flags _setFlags = 0; MTPDstickerSet::Flags _setFlags = 0;
int32 _bottom = 0; int _visibleTop = 0;
int _visibleBottom = 0;
MTPInputStickerSet _input; MTPInputStickerSet _input;
mtpRequestId _installRequest = 0; mtpRequestId _installRequest = 0;
int _selected = -1;
QTimer _previewTimer; QTimer _previewTimer;
int32 _previewShown = -1; int _previewShown = -1;
}; };
class StickerSetBox : public ScrollableBox, public RPCSender { class StickerSetBox : public ScrollableBox, public RPCSender {

View File

@ -7458,8 +7458,8 @@ void HistoryWidget::onFieldTabbed() {
} }
} }
void HistoryWidget::onStickerSend(DocumentData *sticker) { bool HistoryWidget::onStickerSend(DocumentData *sticker) {
sendExistingDocument(sticker, QString()); return sendExistingDocument(sticker, QString());
} }
void HistoryWidget::onPhotoSend(PhotoData *photo) { void HistoryWidget::onPhotoSend(PhotoData *photo) {
@ -7646,14 +7646,14 @@ void HistoryWidget::ReplyEditMessageDataCallback::call(ChannelData *channel, Msg
} }
} }
void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption) { bool HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &caption) {
if (!_history || !doc || !canSendMessages(_peer)) { if (!_history || !doc || !canSendMessages(_peer)) {
return; return false;
} }
MTPInputDocument mtpInput = doc->mtpInput(); MTPInputDocument mtpInput = doc->mtpInput();
if (mtpInput.type() == mtpc_inputDocumentEmpty) { if (mtpInput.type() == mtpc_inputDocumentEmpty) {
return; return false;
} }
App::main()->readServerHistory(_history); App::main()->readServerHistory(_history);
@ -7707,6 +7707,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
if (!_emojiPan->isHidden()) _emojiPan->hideStart(); if (!_emojiPan->isHidden()) _emojiPan->hideStart();
_field.setFocus(); _field.setFocus();
return true;
} }
void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption) { void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption) {

View File

@ -803,7 +803,7 @@ public slots:
void onTextChange(); void onTextChange();
void onFieldTabbed(); void onFieldTabbed();
void onStickerSend(DocumentData *sticker); bool onStickerSend(DocumentData *sticker);
void onPhotoSend(PhotoData *photo); void onPhotoSend(PhotoData *photo);
void onInlineResultSend(InlineBots::Result *result, UserData *bot); void onInlineResultSend(InlineBots::Result *result, UserData *bot);
@ -913,7 +913,7 @@ private:
void call(ChannelData *channel, MsgId msgId) const override; void call(ChannelData *channel, MsgId msgId) const override;
}; };
void sendExistingDocument(DocumentData *doc, const QString &caption); bool sendExistingDocument(DocumentData *doc, const QString &caption);
void sendExistingPhoto(PhotoData *photo, const QString &caption); void sendExistingPhoto(PhotoData *photo, const QString &caption);
void drawField(Painter &p, const QRect &rect); void drawField(Painter &p, const QRect &rect);

View File

@ -1712,6 +1712,10 @@ void MainWidget::onShareContactCancel() {
_history->cancelShareContact(); _history->cancelShareContact();
} }
bool MainWidget::onSendSticker(DocumentData *document) {
return _history->onStickerSend(document);
}
void MainWidget::dialogsCancelled() { void MainWidget::dialogsCancelled() {
if (_hider) { if (_hider) {
_hider->startHide(); _hider->startHide();

View File

@ -212,6 +212,7 @@ public:
void onSendFileCancel(const FileLoadResultPtr &file); void onSendFileCancel(const FileLoadResultPtr &file);
void onShareContactConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter); void onShareContactConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter);
void onShareContactCancel(); void onShareContactCancel();
bool onSendSticker(DocumentData *sticker);
void destroyData(); void destroyData();
void updateOnlineDisplayIn(int32 msecs); void updateOnlineDisplayIn(int32 msecs);