2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-09-02 15:35:51 +00:00

savedgifs -> contextitems in stickers panel, fixed atomic uint64, now with mutex :(

This commit is contained in:
John Preston
2015-12-30 14:47:39 +08:00
parent 96a698a4dc
commit cbb0219812
15 changed files with 661 additions and 448 deletions

View File

@@ -1213,7 +1213,8 @@ void EmojiPanInner::showEmojiPack(DBIEmojiTab packIndex) {
StickerPanInner::StickerPanInner() : TWidget()
, _a_selected(animation(this, &StickerPanInner::step_selected))
, _top(0)
, _showingGifs(cShowingSavedGifs())
, _showingSavedGifs(cShowingSavedGifs())
, _showingContextItems(_showingSavedGifs)
, _selected(-1)
, _pressedSel(-1)
, _settings(this, lang(lng_stickers_you_have))
@@ -1246,8 +1247,11 @@ void StickerPanInner::setScrollTop(int top) {
int StickerPanInner::countHeight() {
int result = 0, minLastH = _maxHeight - st::rbEmoji.height - st::stickerPanPadding;
if (_showingGifs) {
result = st::emojiPanHeader + _gifRows.count() * (st::savedGifHeight + st::savedGifsSkip) - st::savedGifsSkip;
if (_showingContextItems) {
result = st::emojiPanHeader;
for (int i = 0, l = _contextRows.count(); i < l; ++i) {
result += _contextRows.at(i).height;
}
} else {
for (int i = 0; i < _sets.size(); ++i) {
int cnt = _sets.at(i).pack.size(), rows = (cnt / StickerPanPerRow) + ((cnt % StickerPanPerRow) ? 1 : 0);
@@ -1284,33 +1288,36 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
}
p.fillRect(r, st::white);
if (_showingGifs) {
paintSavedGifs(p, r);
if (_showingContextItems) {
paintContextItems(p, r);
} else {
paintStickers(p, r);
}
}
void StickerPanInner::paintSavedGifs(Painter &p, const QRect &r) {
uint64 ms = getms();
void StickerPanInner::paintContextItems(Painter &p, const QRect &r) {
ContextPaintContext context(getms(), false, _previewShown);
int32 fromrow = floorclamp(r.y() - st::emojiPanHeader, st::savedGifHeight + st::savedGifsSkip, 0, _gifRows.size());
int32 torow = ceilclamp(r.y() + r.height() - st::emojiPanHeader - st::savedGifsSkip, st::savedGifHeight + st::savedGifsSkip, 0, _gifRows.size());
int32 top = st::emojiPanHeader;
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
for (int32 row = fromrow; row < torow; ++row) {
const GifRow &gifRow(_gifRows.at(row));
int32 left = st::savedGifsLeft, top = st::emojiPanHeader + row * (st::savedGifHeight + st::savedGifsSkip);
for (int32 col = 0, cols = gifRow.size(); col < cols; ++col) {
if (left >= tox) break;
for (int32 row = 0, rows = _contextRows.size(); row < rows; ++row) {
const ContextRow &contextRow(_contextRows.at(row));
if (top >= r.top() + r.height()) break;
if (top + contextRow.height > r.top()) {
int32 left = st::savedGifsLeft;
for (int32 col = 0, cols = contextRow.items.size(); col < cols; ++col) {
if (left >= tox) break;
int32 w = gifRow.at(col)->width();
if (left + w > fromx) {
p.translate(left, top);
gifRow.at(col)->paint(p, _previewShown, ms);
p.translate(-left, -top);
int32 w = contextRow.items.at(col)->width();
if (left + w > fromx) {
p.translate(left, top);
contextRow.items.at(col)->paint(p, r.translated(-left, -top), 0, &context);
p.translate(-left, -top);
}
left += w + st::savedGifsSkip;
}
left += w + st::savedGifsSkip;
}
top += contextRow.height;
}
}
@@ -1392,6 +1399,7 @@ void StickerPanInner::mousePressEvent(QMouseEvent *e) {
updateSelected();
_pressedSel = _selected;
textlnkDown(textlnkOver());
_previewTimer.start(QApplication::startDragTime());
}
@@ -1399,7 +1407,9 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
_previewTimer.stop();
int32 pressed = _pressedSel;
TextLinkPtr down(textlnkDown());
_pressedSel = -1;
textlnkDown(TextLinkPtr());
_lastMousePos = e->globalPos();
updateSelected();
@@ -1409,31 +1419,24 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
return;
}
if (_selected < 0 || _selected != pressed) return;
if (_showingGifs) {
if (_selected < 0 || _selected != pressed || textlnkOver() != down) return;
if (_showingContextItems) {
int32 row = _selected / MatrixRowShift, col = _selected % MatrixRowShift;
bool del = (col >= SavedGifsMaxPerRow);
if (del) col -= SavedGifsMaxPerRow;
if (row < _gifRows.size() && col < _gifRows.at(row).size()) {
DocumentData *doc = _gifRows.at(row).at(col)->document();
if (del) {
int32 index = cSavedGifs().indexOf(doc);
if (index >= 0) {
cRefSavedGifs().remove(index);
Local::writeSavedGifs();
if (App::main()) emit App::main()->savedGifsUpdated();
if (row < _contextRows.size() && col < _contextRows.at(row).items.size()) {
if (down) {
if (down->type() == qstr("SendContextItemLink") && e->button() == Qt::LeftButton) {
DocumentData *doc = _contextRows.at(row).items.at(col)->document();
if (!doc) return;
MTP::send(MTPmessages_SaveGif(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_bool(true)));
if (doc->loaded()) {
emit selected(doc);
} else if (doc->loading()) {
doc->cancel();
} else {
DocumentOpenLink::doOpen(doc, ActionOnLoadNone);
}
} else {
refreshSavedGifs();
}
} else {
if (doc->loaded()) {
emit selected(doc);
} else if (doc->loading()) {
doc->cancel();
} else {
DocumentOpenLink::doOpen(doc, ActionOnLoadNone);
down->onClick(e->button());
}
}
}
@@ -1505,14 +1508,13 @@ void StickerPanInner::enterFromChildEvent(QEvent *e) {
void StickerPanInner::clearSelection(bool fast) {
_lastMousePos = mapToGlobal(QPoint(-10, -10));
if (fast) {
if (_showingGifs) {
if (_showingContextItems) {
if (_selected >= 0) {
int32 srow = _selected / MatrixRowShift, scol = _selected % MatrixRowShift;
bool sdel = (scol >= SavedGifsMaxPerRow);
if (sdel) scol -= SavedGifsMaxPerRow;
if (srow < _gifRows.size() && scol < _gifRows.at(srow).size()) {
_gifRows.at(srow).at(scol)->notify_over(false);
if (sdel) _gifRows.at(srow).at(scol)->notify_deleteOver(false);
t_assert(srow >= 0 && srow < _contextRows.size() && scol >= 0 && scol < _contextRows.at(srow).items.size());
if (textlnkOver()) {
_contextRows.at(srow).items.at(scol)->linkOut(textlnkOver());
textlnkOver(TextLinkPtr());
}
setCursor(style::cur_default);
}
@@ -1548,10 +1550,18 @@ void StickerPanInner::clearSelection(bool fast) {
}
void StickerPanInner::hideFinish() {
clearSavedGifs();
clearContextRows();
for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
i.value()->document()->forget();
}
for (ContextLayouts::const_iterator i = _contextLayouts.cbegin(), e = _contextLayouts.cend(); i != e; ++i) {
if (i.value()->result()->doc) {
i.value()->result()->doc->forget();
}
if (i.value()->result()->photo) {
i.value()->result()->photo->forget();
}
}
}
void StickerPanInner::refreshStickers() {
@@ -1565,13 +1575,13 @@ void StickerPanInner::refreshStickers() {
appendSet(*i);
}
if (!_showingGifs) {
if (_showingContextItems) {
_settings.hide();
} else {
int32 h = countHeight();
if (h != height()) resize(width(), h);
_settings.setVisible(_sets.isEmpty());
} else {
_settings.hide();
}
@@ -1583,69 +1593,88 @@ void StickerPanInner::refreshStickers() {
void StickerPanInner::refreshSavedGifs() {
clearSelection(true);
clearSavedGifs();
if (_showingGifs) {
const SavedGifs &saved(cSavedGifs());
if (saved.isEmpty()) {
showStickerSet(RecentStickerSetId);
return;
} else {
_gifRows.reserve(saved.size());
GifRow row;
row.reserve(SavedGifsMaxPerRow);
int32 maxWidth = width() - st::savedGifsLeft, sumWidth = 0, widths[SavedGifsMaxPerRow] = { 0 };
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
DocumentData *doc = *i;
int32 w = doc->dimensions.width(), h = doc->dimensions.height();
if ((w <= 0 || h <= 0) && !doc->thumb->isNull()) {
w = doc->thumb->width();
h = doc->thumb->height();
if (_showingSavedGifs) {
clearContextRows();
if (_showingContextItems) {
const SavedGifs &saved(cSavedGifs());
if (saved.isEmpty()) {
showStickerSet(RecentStickerSetId);
return;
} else {
_contextRows.reserve(saved.size());
ContextRow row;
row.items.reserve(SavedGifsMaxPerRow);
int32 maxWidth = width() - st::savedGifsLeft, sumWidth = 0, widths[SavedGifsMaxPerRow] = { 0 };
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
DocumentData *doc = *i;
int32 w = doc->dimensions.width(), h = doc->dimensions.height();
if ((w <= 0 || h <= 0) && !doc->thumb->isNull()) {
w = doc->thumb->width();
h = doc->thumb->height();
}
if (w <= 0 || h <= 0) continue;
w = w * st::savedGifHeight / h;
widths[row.items.size()] = w;
w = qMax(w, int32(st::savedGifMinWidth));
sumWidth += w;
row.items.push_back(layoutPrepare(doc, (_contextRows.size() * MatrixRowShift) + row.items.size(), w));
if (row.items.size() >= SavedGifsMaxPerRow || sumWidth >= maxWidth - (row.items.size() - 1) * st::savedGifsSkip) {
_contextRows.push_back(layoutContextRow(row, widths, sumWidth));
row = ContextRow();
sumWidth = 0;
memset(widths, 0, sizeof(widths));
}
}
if (w <= 0 || h <= 0) continue;
w = w * st::savedGifHeight / h;
widths[row.size()] = w;
w = qMax(w, int32(st::savedGifMinWidth));
sumWidth += w;
row.push_back(layoutPrepare(doc, (_gifRows.size() * MatrixRowShift) + row.size(), w));
if (row.size() >= SavedGifsMaxPerRow || sumWidth >= maxWidth - (row.size() - 1) * st::savedGifsSkip) {
_gifRows.push_back(layoutGifRow(row, widths, sumWidth));
row.clear();
row.reserve(SavedGifsMaxPerRow);
sumWidth = 0;
memset(widths, 0, sizeof(widths));
if (!row.items.isEmpty()) {
_contextRows.push_back(layoutContextRow(row, 0, 0));
}
}
if (!row.isEmpty()) {
_gifRows.push_back(row);
}
deleteUnusedGifLayouts();
int32 h = countHeight();
if (h != height()) resize(width(), h);
update();
}
deleteUnusedLayouts();
int32 h = countHeight();
if (h != height()) resize(width(), h);
update();
}
emit refreshIcons();
updateSelected();
}
void StickerPanInner::clearSavedGifs() {
for (GifRows::const_iterator i = _gifRows.cbegin(), e = _gifRows.cend(); i != e; ++i) {
for (GifRow::const_iterator j = i->cbegin(), end = i->cend(); j != end; ++j) {
void StickerPanInner::refreshContextResults(const ContextResults &results) {
}
void StickerPanInner::contextBotChanged() {
refreshContextResults(ContextResults());
deleteUnusedContextLayouts();
}
void StickerPanInner::clearContextRows() {
for (ContextRows::const_iterator i = _contextRows.cbegin(), e = _contextRows.cend(); i != e; ++i) {
for (ContextItems::const_iterator j = i->items.cbegin(), end = i->items.cend(); j != end; ++j) {
(*j)->setPosition(-1, 0);
}
}
_gifRows.clear();
_contextRows.clear();
}
void StickerPanInner::deleteUnusedLayouts() {
if (_gifRows.isEmpty()) { // delete all
LayoutContextGif *StickerPanInner::layoutPrepare(DocumentData *doc, int32 position, int32 width) {
GifLayouts::const_iterator i = _gifLayouts.constFind(doc);
if (i == _gifLayouts.cend()) {
i = _gifLayouts.insert(doc, new LayoutContextGif(doc, true));
i.value()->initDimensions();
}
i.value()->setPosition(position, width);
return i.value();
}
void StickerPanInner::deleteUnusedGifLayouts() {
if (_contextRows.isEmpty()) { // delete all
for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
delete i.value();
}
@@ -1662,26 +1691,36 @@ void StickerPanInner::deleteUnusedLayouts() {
}
}
LayoutSavedGif *StickerPanInner::layoutPrepare(DocumentData *doc, int32 position, int32 width) {
GifLayouts::const_iterator i = _gifLayouts.constFind(doc);
if (i == _gifLayouts.cend()) {
i = _gifLayouts.insert(doc, new LayoutSavedGif(doc));
void StickerPanInner::deleteUnusedContextLayouts() {
if (_contextRows.isEmpty()) { // delete all
for (ContextLayouts::const_iterator i = _contextLayouts.cbegin(), e = _contextLayouts.cend(); i != e; ++i) {
delete i.value();
}
_contextLayouts.clear();
} else {
for (ContextLayouts::iterator i = _contextLayouts.begin(); i != _contextLayouts.cend();) {
if (i.value()->position() < 0) {
delete i.value();
i = _contextLayouts.erase(i);
} else {
++i;
}
}
}
i.value()->setPosition(position, width);
return i.value();
}
const StickerPanInner::GifRow &StickerPanInner::layoutGifRow(const GifRow &row, int32 *widths, int32 sumWidth) {
int32 count = row.size();
StickerPanInner::ContextRow &StickerPanInner::layoutContextRow(ContextRow &row, int32 *widths, int32 sumWidth) {
int32 count = row.items.size();
t_assert(count <= SavedGifsMaxPerRow);
row.height = 0;
int32 availw = width() - st::savedGifsLeft - st::savedGifsSkip * (count - 1);
if (sumWidth != availw) {
for (int32 i = 0; i < count; ++i) {
int32 w = widths[i] * availw / sumWidth;
int32 actualw = qMax(w, int32(st::savedGifMinWidth));
row.at(i)->setWidth(actualw);
for (int32 i = 0; i < count; ++i) {
int32 w = widths ? (widths[i] * availw / sumWidth) : row.items.at(i)->width();
int32 actualw = qMax(w, int32(st::savedGifMinWidth));
row.height = qMax(row.height, row.items.at(i)->resizeGetHeight(actualw));
if (widths) {
availw -= actualw;
sumWidth -= qMax(widths[i], int32(st::savedGifMinWidth));
}
@@ -1690,14 +1729,15 @@ const StickerPanInner::GifRow &StickerPanInner::layoutGifRow(const GifRow &row,
}
void StickerPanInner::preloadImages() {
if (_showingGifs) {
for (int32 row = 0, rows = _gifRows.size(); row < rows; ++row) {
for (int32 col = 0, cols = _gifRows.at(row).size(); col < cols; ++col) {
_gifRows.at(row).at(col)->preload();
if (_showingContextItems) {
for (int32 row = 0, rows = _contextRows.size(); row < rows; ++row) {
for (int32 col = 0, cols = _contextRows.at(row).items.size(); col < cols; ++col) {
_contextRows.at(row).items.at(col)->preload();
}
}
return;
}
uint64 ms = getms();
for (int32 i = 0, l = _sets.size(), k = 0; i < l; ++i) {
for (int32 j = 0, n = _sets.at(i).pack.size(); j < n; ++j) {
if (++k > StickerPanPerRow * (StickerPanPerRow + 1)) break;
@@ -1717,7 +1757,7 @@ void StickerPanInner::preloadImages() {
}
uint64 StickerPanInner::currentSet(int yOffset) const {
if (_showingGifs) return NoneStickerSetId;
if (_showingContextItems) return NoneStickerSetId;
int y, ytill = 0;
for (int i = 0, l = _sets.size(); i < l; ++i) {
@@ -1731,31 +1771,45 @@ uint64 StickerPanInner::currentSet(int yOffset) const {
return _sets.isEmpty() ? RecentStickerSetId : _sets.back().id;
}
void StickerPanInner::ui_repaintSavedGif(const LayoutSavedGif *layout) {
if (!_showingGifs) return;
void StickerPanInner::refreshContextRows(const ContextResults &results) {
int32 position = layout->position();
int32 row = position / MatrixRowShift, col = position % MatrixRowShift;
t_assert((row < _gifRows.size()) && (col < _gifRows.at(row).size()));
const GifRow &gifRow(_gifRows.at(row));
int32 left = st::savedGifsLeft, top = st::emojiPanHeader + row * (st::savedGifHeight + st::savedGifsSkip);
for (int32 i = 0; i < col; ++i) left += gifRow.at(i)->width() + st::savedGifsSkip;
rtlupdate(left, top, gifRow.at(col)->width(), st::savedGifHeight);
}
bool StickerPanInner::ui_isSavedGifVisible(const LayoutSavedGif *layout) {
void StickerPanInner::ui_repaintContextItem(const LayoutContextItem *layout) {
int32 position = layout->position();
int32 row = position / MatrixRowShift, col = position % MatrixRowShift;
t_assert((row < _gifRows.size()) && (col < _gifRows.at(row).size()));
if (!_showingContextItems || position < 0) return;
int32 top = st::emojiPanHeader + row * (st::savedGifHeight + st::savedGifsSkip);
return (top < _top + _maxHeight) && (top + st::savedGifHeight > _top);
int32 row = position / MatrixRowShift, col = position % MatrixRowShift;
t_assert((row < _contextRows.size()) && (col < _contextRows.at(row).items.size()));
const ContextItems &contextItems(_contextRows.at(row).items);
int32 left = st::savedGifsLeft, top = st::emojiPanHeader;
for (int32 i = 0; i < row; ++i) {
top += _contextRows.at(i).height;
}
for (int32 i = 0; i < col; ++i) left += contextItems.at(i)->width() + st::savedGifsSkip;
rtlupdate(left, top, contextItems.at(col)->width(), contextItems.at(col)->height());
}
bool StickerPanInner::ui_isGifBeingChosen() {
return _showingGifs;
bool StickerPanInner::ui_isContextItemVisible(const LayoutContextItem *layout) {
int32 position = layout->position();
if (!_showingContextItems || position < 0) return false;
int32 row = position / MatrixRowShift, col = position % MatrixRowShift;
t_assert((row < _contextRows.size()) && (col < _contextRows.at(row).items.size()));
const ContextItems &contextItems(_contextRows.at(row).items);
int32 top = st::emojiPanHeader;
for (int32 i = 0; i < row; ++i) {
top += _contextRows.at(i).height;
}
return (top < _top + _maxHeight) && (top + _contextRows.at(row).items.at(col)->height() > _top);
}
bool StickerPanInner::ui_isContextItemBeingChosen() {
return _showingContextItems;
}
void StickerPanInner::appendSet(uint64 setId) {
@@ -1772,8 +1826,10 @@ void StickerPanInner::appendSet(uint64 setId) {
}
void StickerPanInner::refreshRecent() {
if (_showingGifs) {
refreshSavedGifs();
if (_showingContextItems) {
if (_showingSavedGifs) {
refreshSavedGifs();
}
} else {
refreshRecentStickers();
}
@@ -1816,7 +1872,7 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
}
}
if (performResize && !_showingGifs) {
if (performResize && !_showingContextItems) {
int32 h = countHeight();
if (h != height()) {
resize(width(), h);
@@ -1860,7 +1916,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
}
panels.clear();
if (_showingGifs) {
if (_showingContextItems) {
panels.push_back(new EmojiPanel(parentWidget(), lang(lng_saved_gifs), NoneStickerSetId, true, 0));
panels.back()->show();
return;
@@ -1882,7 +1938,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
}
void StickerPanInner::refreshPanels(QVector<EmojiPanel*> &panels) {
if (_showingGifs) return;
if (_showingContextItems) return;
if (panels.size() != _sets.size()) return fillPanels(panels);
@@ -1901,58 +1957,55 @@ void StickerPanInner::updateSelected() {
int32 selIndex = -1;
QPoint p(mapFromGlobal(_lastMousePos));
if (_showingGifs) {
if (_showingContextItems) {
int sx = (rtl() ? width() - p.x() : p.x()) - st::savedGifsLeft, sy = p.y() - st::emojiPanHeader;
int32 row = sy / int32(st::savedGifHeight + st::savedGifsSkip), col = 0, sel = -1;
bool del = false;
if (sx >= 0 && row >= 0 && row < _gifRows.size() && sy < (row + 1) * st::savedGifHeight) {
const GifRow &gifRow(_gifRows.at(row));
for (int32 left = 0, cols = gifRow.size(); col < cols; ++col) {
int32 width = gifRow.at(col)->width();
if (sx >= left && sx < left + width) {
del = (sx >= left + width - st::stickerPanDelete.pxWidth()) && (sy < row * st::savedGifHeight + st::stickerPanDelete.pxHeight());
int32 row = -1, col = -1, sel = -1;
TextLinkPtr lnk;
HistoryCursorState cursor = HistoryDefaultCursorState;
if (sy >= 0) {
row = 0;
for (int32 rows = _contextRows.size(); row < rows; ++row) {
if (sy < _contextRows.at(row).height) {
break;
}
left += width + st::savedGifsSkip;
sy -= _contextRows.at(row).height;
}
if (col < gifRow.size()) {
sel = row * MatrixRowShift + col + (del ? SavedGifsMaxPerRow : 0);
} else {
row = col = -1;
}
} else {
row = col = -1;
}
if (_selected != sel) {
if (sx >= 0 && row >= 0 && row < _contextRows.size()) {
const ContextItems &contextItems(_contextRows.at(row).items);
col = 0;
for (int32 cols = contextItems.size(); col < cols; ++col) {
int32 width = contextItems.at(col)->width();
if (sx < width) {
break;
}
sx -= width + st::savedGifsSkip;
}
if (col < contextItems.size()) {
sel = row * MatrixRowShift + col;
contextItems.at(col)->getState(lnk, cursor, sx, sy);
}
}
if (_selected != sel || textlnkOver() != lnk) {
int32 srow = (_selected >= 0) ? (_selected / MatrixRowShift) : -1;
int32 scol = (_selected >= 0) ? (_selected % MatrixRowShift) : -1;
bool sdel = (scol >= SavedGifsMaxPerRow);
if (sdel) scol -= SavedGifsMaxPerRow;
if (srow != row || scol != col) {
if (srow >= 0 && srow < _gifRows.size()) {
if (scol >= 0 && scol < _gifRows.at(srow).size()) {
_gifRows.at(srow).at(scol)->notify_over(false);
if (sdel) _gifRows.at(srow).at(scol)->notify_deleteOver(false);
}
}
if (row >= 0 && row < _gifRows.size()) {
if (col >= 0 && col < _gifRows.at(row).size()) {
_gifRows.at(row).at(col)->notify_over(true);
if (del) _gifRows.at(row).at(col)->notify_deleteOver(true);
}
}
} else if (sdel != del) {
if (sdel) _gifRows.at(srow).at(scol)->notify_deleteOver(false);
if (del) _gifRows.at(row).at(col)->notify_deleteOver(true);
if (srow >= 0 && scol >= 0 && textlnkOver()) {
t_assert(srow >= 0 && srow < _contextRows.size() && scol >= 0 && scol < _contextRows.at(srow).items.size());
_contextRows.at(srow).items.at(scol)->linkOut(textlnkOver());
}
if ((_selected >= 0 && sel < 0) || (_selected < 0 && sel >= 0)) {
setCursor(sel >= 0 ? style::cur_pointer : style::cur_default);
if ((textlnkOver() && !lnk) || (!textlnkOver() && lnk)) {
setCursor(lnk ? style::cur_pointer : style::cur_default);
}
_selected = sel;
textlnkOver(lnk);
if (row >= 0 && col >= 0 && textlnkOver()) {
t_assert(row >= 0 && row < _contextRows.size() && col >= 0 && col < _contextRows.at(row).items.size());
_contextRows.at(row).items.at(col)->linkOver(textlnkOver());
}
if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) {
_pressedSel = _selected;
if (row >= 0 && col >= 0) {
Ui::showStickerPreview(_gifRows.at(row).at(col)->document());
if (row >= 0 && col >= 0 && _contextRows.at(row).items.at(col)->document()) {
Ui::showStickerPreview(_contextRows.at(row).items.at(col)->document());
}
}
}
@@ -2046,11 +2099,11 @@ void StickerPanInner::onSettings() {
void StickerPanInner::onPreview() {
if (_pressedSel < 0) return;
if (_showingGifs) {
if (_showingContextItems) {
int32 row = _pressedSel / MatrixRowShift, col = _pressedSel % MatrixRowShift;
if (col >= SavedGifsMaxPerRow) col -= SavedGifsMaxPerRow;
if (row < _gifRows.size() && col < _gifRows.at(row).size() && _gifRows.at(row).at(col)->document()->loaded()) {
Ui::showStickerPreview(_gifRows.at(row).at(col)->document());
if (row < _contextRows.size() && col < _contextRows.at(row).items.size() && _contextRows.at(row).items.at(col)->document() && _contextRows.at(row).items.at(col)->document()->loaded()) {
Ui::showStickerPreview(_contextRows.at(row).items.at(col)->document());
_previewShown = true;
}
} else if (_pressedSel < MatrixRowShift * _sets.size()) {
@@ -2084,12 +2137,12 @@ void StickerPanInner::showStickerSet(uint64 setId) {
clearSelection(true);
if (setId == NoneStickerSetId) {
if (_gifRows.isEmpty() && !cSavedGifs().isEmpty()) {
if (_contextRows.isEmpty() && !cSavedGifs().isEmpty()) {
refreshSavedGifs();
}
bool wasNotShowingGifs = !_showingGifs;
bool wasNotShowingGifs = !_showingContextItems;
if (wasNotShowingGifs) {
_showingGifs = true;
_showingContextItems = true;
cSetShowingSavedGifs(true);
emit saveConfigDelayed(SaveRecentEmojisTimeout);
}
@@ -2099,8 +2152,8 @@ void StickerPanInner::showStickerSet(uint64 setId) {
return;
}
if (_showingGifs) {
_showingGifs = false;
if (_showingContextItems) {
_showingContextItems = false;
cSetShowingSavedGifs(false);
emit saveConfigDelayed(SaveRecentEmojisTimeout);
@@ -2931,22 +2984,22 @@ void EmojiPan::stickersInstalled(uint64 setId) {
showStart();
}
void EmojiPan::ui_repaintSavedGif(const LayoutSavedGif *layout) {
void EmojiPan::ui_repaintContextItem(const LayoutContextItem *layout) {
if (_stickersShown && !isHidden()) {
s_inner.ui_repaintSavedGif(layout);
s_inner.ui_repaintContextItem(layout);
}
}
bool EmojiPan::ui_isSavedGifVisible(const LayoutSavedGif *layout) {
bool EmojiPan::ui_isContextItemVisible(const LayoutContextItem *layout) {
if (_stickersShown && !isHidden()) {
return s_inner.ui_isSavedGifVisible(layout);
return s_inner.ui_isContextItemVisible(layout);
}
return false;
}
bool EmojiPan::ui_isGifBeingChosen() {
bool EmojiPan::ui_isContextItemBeingChosen() {
if (_stickersShown && !isHidden()) {
return s_inner.ui_isGifBeingChosen();
return s_inner.ui_isContextItemBeingChosen();
}
return false;
}
@@ -3165,12 +3218,18 @@ void EmojiPan::onDelayedHide() {
_removingSetId = 0;
}
void EmojiPan::clearContextResults() {
void EmojiPan::contextBotChanged() {
if (!_contextBot) return;
if (_contextRequestId) MTP::cancel(_contextRequestId);
_contextRequestId = 0;
_contextQuery = _contextNextQuery = _contextNextOffset = QString();
_contextBot = 0;
for (ContextCache::const_iterator i = _contextCache.cbegin(), e = _contextCache.cend(); i != e; ++i) {
delete i.value();
}
_contextCache.clear();
s_inner.contextBotChanged();
}
void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
@@ -3185,54 +3244,56 @@ void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
uint64 queryId(d.vquery_id.v);
if (!adding) {
it = _contextCache.insert(_contextQuery, ContextCacheEntry());
it = _contextCache.insert(_contextQuery, new ContextCacheEntry());
}
it->nextOffset = v.isEmpty() ? QString() : qs(d.vnext_offset);
it.value()->nextOffset = v.isEmpty() ? QString() : qs(d.vnext_offset);
int32 count = v.size();
if (count) {
it->results.reserve(it->results.size() + count);
it.value()->results.reserve(it.value()->results.size() + count);
}
for (int32 i = 0; i < count; ++i) {
ContextResult result(queryId);
ContextResult *result = new ContextResult(queryId);
const MTPBotContextMessage *message = 0;
switch (v.at(i).type()) {
case mtpc_botContextMediaResultPhoto: {
const MTPDbotContextMediaResultPhoto &r(v.at(i).c_botContextMediaResultPhoto());
result.id = qs(r.vid);
result.type = qs(r.vtype);
result.photo = App::feedPhoto(r.vphoto);
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->photo = App::feedPhoto(r.vphoto);
message = &r.vsend_message;
} break;
case mtpc_botContextMediaResultDocument: {
const MTPDbotContextMediaResultDocument &r(v.at(i).c_botContextMediaResultDocument());
result.id = qs(r.vid);
result.type = qs(r.vtype);
result.doc = App::feedDocument(r.vdocument);
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->doc = App::feedDocument(r.vdocument);
message = &r.vsend_message;
} break;
case mtpc_botContextResult: {
const MTPDbotContextResult &r(v.at(i).c_botContextResult());
result.id = qs(r.vid);
result.type = qs(r.vtype);
result.title = qs(r.vtitle);
result.description = qs(r.vdescription);
result.url = qs(r.vurl);
result.thumb_url = qs(r.vthumb_url);
result.content_type = qs(r.vcontent_type);
result.content_url = qs(r.vcontent_url);
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->title = qs(r.vtitle);
result->description = qs(r.vdescription);
result->url = qs(r.vurl);
result->thumb_url = qs(r.vthumb_url);
result->content_type = qs(r.vcontent_type);
result->content_url = qs(r.vcontent_url);
message = &r.vsend_message;
} break;
}
bool badAttachment = (!result.photo || result.photo->access) && (!result.doc || result.doc->access);
bool canSend = (result.photo || result.doc || !result.message.isEmpty());
if (!result.type.isEmpty() && !badAttachment && !canSend) {
it->results.push_back(result);
bool badAttachment = (!result->photo || result->photo->access) && (!result->doc || result->doc->access);
bool canSend = (result->photo || result->doc || !result->message.isEmpty());
if (result->type.isEmpty() || badAttachment || !canSend) {
delete result;
} else {
it.value()->results.push_back(result);
}
}
} else if (adding) {
it->results.clear();
it->nextOffset = QString();
it.value()->clearResults();
it.value()->nextOffset = QString();
}
refreshContextRows(!adding);
}
@@ -3248,7 +3309,7 @@ void EmojiPan::showContextResults(UserData *bot, QString query) {
if (bot != _contextBot) {
if (!isHidden()) hideStart();
clearContextResults();
contextBotChanged();
_contextBot = bot;
force = true;
}
@@ -3273,19 +3334,22 @@ void EmojiPan::onContextRequest() {
QString nextOffset;
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
if (i != _contextCache.cend()) {
nextOffset = i->nextOffset;
nextOffset = i.value()->nextOffset;
if (nextOffset.isEmpty()) return;
}
_contextRequestId = MTP::send(MTPmessages_GetContextBotResults(_contextBot->inputUser, MTP_string(_contextQuery), MTP_string(nextOffset)), rpcDone(&EmojiPan::contextResultsDone), rpcFail(&EmojiPan::contextResultsFail));
}
void EmojiPan::refreshContextRows(bool toDown) {
void EmojiPan::refreshContextRows(bool newResults) {
bool clear = true;
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
if (i == _contextCache.cend()) {
clear = !i->results.isEmpty();
_contextNextOffset = i->nextOffset;
if (i != _contextCache.cend()) {
clear = !i.value()->results.isEmpty();
_contextNextOffset = i.value()->nextOffset;
}
s_inner.refreshContextRows(clear ? ContextResults() : i.value()->results);
if (newResults) s_scroll.scrollToY(0);
}
MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows)