2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 22:46:10 +00:00

photo and video overview rewritten on layouts

This commit is contained in:
John Preston
2015-12-22 15:49:42 +03:00
parent 62723f7576
commit d3896ff53b
8 changed files with 616 additions and 267 deletions

View File

@@ -143,15 +143,16 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
, _resizeSkip(0)
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
, _type(type)
, _reversed(_type != OverviewDocuments && _type != OverviewLinks)
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
, _history(App::history(_peer->id))
, _channel(peerToChannel(_peer->id))
, _selMode(false)
, _rowsLeft(0)
, _rowWidth(st::msgMinWidth)
, _rowHeight(0)
, _photosInRow(1)
, _photosToAdd(0)
, _selMode(false)
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
, _cancelSearch(this, st::btnCancelSearch)
, _cachedItemsToBeLoaded(LinksOverviewPerPage * 2)
@@ -292,7 +293,7 @@ int32 OverviewInner::migratedIndexSkip() const {
void OverviewInner::fixItemIndex(int32 &current, MsgId msgId) const {
if (!msgId) {
current = -1;
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
} else if (_type == OverviewAudioDocuments) {
History *history = itemMigrated(msgId) ? _migrated : _history;
int32 l = history->overview[_type].size(), indexskip = migratedIndexSkip();
int32 index = (current >= 0 && history == _history) ? (current - indexskip) : current;
@@ -306,7 +307,7 @@ void OverviewInner::fixItemIndex(int32 &current, MsgId msgId) const {
}
}
}
} else if (_type == OverviewDocuments) {
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
int32 l = _items.size();
if (current < 0 || current >= l || complexMsgId(_items.at(current)->getItem()) != msgId) {
current = -1;
@@ -501,7 +502,7 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
}
index += delta;
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
if (_type == OverviewAudioDocuments) {
int32 indexskip = migratedIndexSkip();
if (index < 0 || index >= indexskip + _history->overview[_type].size()) {
msgId = 0;
@@ -509,7 +510,7 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
} else {
msgId = (index >= indexskip) ? _history->overview[_type][index - indexskip] : (-_migrated->overview[_type][index]);
}
} else if (_type == OverviewDocuments) {
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
while (index >= 0 && index < _items.size() && !_items.at(index)->toLayoutMediaItem()) {
index += (delta > 0) ? 1 : -1;
}
@@ -536,9 +537,10 @@ void OverviewInner::redrawItem(MsgId itemId, int32 itemIndex) {
fixItemIndex(itemIndex, itemId);
if (itemIndex >= 0) {
if (_type == OverviewPhotos || _type == OverviewVideos) {
int32 shownAtIndex = _items.size() - itemIndex - 1;
float64 w = (float64(_width - st::overviewPhotoSkip) / _photosInRow);
int32 vsize = (_vsize + st::overviewPhotoSkip);
int32 row = (_photosToAdd + itemIndex) / _photosInRow, col = (_photosToAdd + itemIndex) % _photosInRow;
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
} else if (_type == OverviewAudioDocuments) {
update(_rowsLeft, _addToY + int32(itemIndex * _rowHeight), _rowWidth, _rowHeight);
@@ -916,9 +918,9 @@ void OverviewInner::addSelectionRange(int32 selFrom, int32 selTo, History *histo
if (selFrom < 0 || selTo < 0) return;
for (int32 i = selFrom; i <= selTo; ++i) {
MsgId msgid = 0;
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
if (_type == OverviewAudioDocuments) {
msgid = ((history == _history) ? 1 : -1) * history->overview[_type][i];
} else if (_type == OverviewDocuments) {
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
msgid = complexMsgId(_items.at(i)->getItem());
} else if (_type == OverviewLinks) {
msgid = _cachedItems[i].msgid;
@@ -948,7 +950,7 @@ void OverviewInner::applyDragSelection() {
_selected.clear();
}
int32 selfrom = _dragSelToIndex, selto = _dragSelFromIndex;
if (_migrated && (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments)) {
if (_migrated && (_type == OverviewAudioDocuments)) {
int32 indexskip = migratedIndexSkip();
if (selfrom < indexskip) {
if (selto < indexskip) {
@@ -978,7 +980,8 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
if (itemIndex < 0) return QPoint(0, 0);
if (_type == OverviewPhotos || _type == OverviewVideos) {
int32 row = (_photosToAdd + itemIndex) / _photosInRow, col = (_photosToAdd + itemIndex) % _photosInRow;
int32 shownAtIndex = _items.size() - itemIndex - 1;
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
float64 w = (_width - st::overviewPhotoSkip) / float64(_photosInRow);
p.setX(p.x() - int32(col * w) - st::overviewPhotoSkip);
p.setY(p.y() - _addToY - row * (_vsize + st::overviewPhotoSkip) - st::overviewPhotoSkip);
@@ -1003,7 +1006,15 @@ void OverviewInner::activate() {
}
void OverviewInner::clear() {
_cached.clear();
_selected.clear();
_dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1;
_dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0;
_lnkOverIndex = _lnkDownIndex = 0;
for (int32 i = 0, l = _items.size(); i != l; ++i) {
delete _items.at(i);
}
_items.clear();
_cachedItems.clear();
}
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
@@ -1046,7 +1057,7 @@ void OverviewInner::preloadMore() {
}
bool OverviewInner::preloadLocal() {
if (_type != OverviewLinks && _type != OverviewDocuments) return false;
if (_type != OverviewLinks && _type != OverviewDocuments && _type != OverviewPhotos && _type != OverviewVideos) return false;
if (_cachedItemsToBeLoaded >= migratedIndexSkip() + _history->overview[_type].size()) return false;
_cachedItemsToBeLoaded += LinksOverviewPerPage;
mediaOverviewUpdated();
@@ -1087,6 +1098,25 @@ QPixmap OverviewInner::genPix(VideoData *video, int32 size) {
return result;
}
uint32 OverviewInner::itemSelectedValue(int32 index) const {
int32 selfrom = -1, selto = -1;
if (_dragSelFromIndex >= 0 && _dragSelToIndex >= 0) {
selfrom = _dragSelToIndex;
selto = _dragSelFromIndex;
}
if (_items.at(index)->toLayoutMediaItem()) { // draw item
if (index >= _dragSelToIndex && index <= _dragSelFromIndex && _dragSelToIndex >= 0) {
return (_dragSelecting && _items.at(index)->msgId() > 0) ? FullSelection : 0;
} else if (!_selected.isEmpty()) {
SelectedItems::const_iterator j = _selected.constFind(complexMsgId(_items.at(index)->getItem()));
if (j != _selected.cend()) {
return j.value();
}
}
}
return 0;
}
void OverviewInner::paintEvent(QPaintEvent *e) {
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
@@ -1098,6 +1128,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
p.setClipRect(r);
}
uint64 ms = getms();
PaintContext context(ms, _selMode);
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
QPoint dogPos((_width - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
@@ -1120,111 +1151,21 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
bool hasSel = !_selected.isEmpty();
if (_type == OverviewPhotos || _type == OverviewVideos) {
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 count = migratedCount + overview.size();
int32 rowFrom = floorclamp(r.y() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
int32 rowTo = ceilclamp(r.y() + r.height() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
int32 count = _items.size(), rowsCount = (_photosToAdd + count) / _photosInRow + (((_photosToAdd + count) % _photosInRow) ? 1 : 0);
int32 rowFrom = floorclamp(r.y() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, rowsCount);
int32 rowTo = ceilclamp(r.y() + r.height() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, rowsCount);
float64 w = float64(_width - st::overviewPhotoSkip) / _photosInRow;
for (int32 row = rowFrom; row < rowTo; ++row) {
if (row * _photosInRow >= _photosToAdd + count) break;
for (int32 i = 0; i < _photosInRow; ++i) {
int32 index = row * _photosInRow + i - _photosToAdd;
if (index < 0) continue;
if (index >= count) break;
for (int32 col = 0; col < _photosInRow; ++col) {
int32 i = count - (row * _photosInRow + col - _photosToAdd) - 1;
if (i < 0) continue;
if (i >= count) break;
bool migratedindex = (index < migratedCount);
int32 bareindex = migratedindex ? index : (index - migratedCount);
HistoryItem *item = App::histItemById(migratedindex ? _migrated->channelId() : _channel, (migratedindex ? *migratedOverview : overview)[bareindex]);
HistoryMedia *m = item ? item->getMedia(true) : 0;
QPoint pos(int32(i * w + st::overviewPhotoSkip), _addToY + row * (_vsize + st::overviewPhotoSkip) + st::overviewPhotoSkip);
if (m) switch (m->type()) {
case MediaTypePhoto: {
PhotoData *photo = static_cast<HistoryPhoto*>(m)->photo();
bool quality = photo->full->loaded();
if (!quality) {
if (photo->thumb->loaded()) {
photo->medium->load(false, false);
quality = photo->medium->loaded();
} else {
photo->thumb->load();
}
}
CachedSizes::iterator it = _cached.find(photo);
if (it == _cached.cend()) {
CachedSize size;
size.medium = quality;
size.vsize = _vsize;
size.pix = genPix(photo, _vsize);
it = _cached.insert(photo, size);
} else if (it->medium != quality || it->vsize != _vsize) {
it->medium = quality;
it->vsize = _vsize;
it->pix = genPix(photo, _vsize);
}
p.drawPixmap(pos, it->pix);
if (!quality) {
uint64 dt = itemAnimations().animate(item, ms);
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
int32 x = pos.x() + (_vsize - st::overviewLoader.width()) / 2, y = pos.y() + (_vsize - st::overviewLoader.height()) / 2;
p.fillRect(x, y, st::overviewLoader.width(), st::overviewLoader.height(), st::photoLoaderBg->b);
x += (st::overviewLoader.width() - cnt * st::overviewLoaderPoint.width() - (cnt - 1) * st::overviewLoaderSkip) / 2;
y += (st::overviewLoader.height() - st::overviewLoaderPoint.height()) / 2;
QColor c(st::white->c);
QBrush b(c);
for (int32 i = 0; i < cnt; ++i) {
t -= delta;
while (t < 0) t += period;
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
b.setColor(c);
p.fillRect(x + i * (st::overviewLoaderPoint.width() + st::overviewLoaderSkip), y, st::overviewLoaderPoint.width(), st::overviewLoaderPoint.height(), b);
}
}
} break;
case MediaTypeVideo: {
VideoData *video = static_cast<HistoryVideo*>(m)->video();
CachedSizes::iterator it = _cached.find(video);
if (it == _cached.cend()) {
CachedSize size;
size.medium = 0;
size.vsize = _vsize;
size.pix = genPix(video, _vsize);
it = _cached.insert(video, size);
} else if (it->vsize != _vsize) {
it->vsize = _vsize;
it->pix = genPix(video, _vsize);
}
p.drawPixmap(pos, it->pix);
} break;
}
uint32 sel = 0;
if (index >= selfrom && index <= selto) {
sel = (_dragSelecting && item->id > 0) ? FullSelection : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(migratedindex ? -item->id : item->id);
if (i != selEnd) {
sel = i.value();
}
}
if (sel == FullSelection) {
p.fillRect(QRect(pos.x(), pos.y(), _vsize, _vsize), st::overviewPhotoSelectOverlay);
p.drawSprite(QPoint(pos.x() + _vsize - st::overviewPhotoCheck.pxWidth(), pos.y() + _vsize - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoChecked);
} else if (_selMode/* || (selfrom < count && selfrom <= selto && 0 <= selto)*/) {
p.drawSprite(QPoint(pos.x() + _vsize - st::overviewPhotoCheck.pxWidth(), pos.y() + _vsize - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoCheck);
}
if (m) {
p.translate(pos.x(), pos.y());
// m->drawOverview(p, _vsize, item, r.translated(-pos.x(), -pos.y()), sel == FullSelection, ms);
p.translate(-pos.x(), -pos.y());
}
QPoint pos(int32(col * w + st::overviewPhotoSkip), _addToY + row * (_vsize + st::overviewPhotoSkip) + st::overviewPhotoSkip);
p.translate(pos.x(), pos.y());
_items.at(i)->paint(p, r.translated(-pos.x(), -pos.y()), itemSelectedValue(i), &context);
p.translate(-pos.x(), -pos.y());
}
}
} else if (_type == OverviewAudioDocuments) {
@@ -1358,18 +1299,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
if (_addToY + curY >= r.y() + r.height()) break;
p.translate(0, curY - y);
uint32 sel = 0;
if (_items.at(i)->toLayoutMediaItem()) { // draw item
if (i >= selfrom && i <= selto) {
sel = (_dragSelecting && _items.at(i)->msgId() > 0) ? FullSelection : 0;
} else if (hasSel) {
SelectedItems::const_iterator j = _selected.constFind(complexMsgId(_items.at(i)->getItem()));
if (j != selEnd) {
sel = j.value();
}
}
}
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_addToY - curY), sel, ms);
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_addToY - curY), itemSelectedValue(i), &context);
y = curY;
}
}
@@ -1433,15 +1363,13 @@ void OverviewInner::onUpdateSelected() {
HistoryCursorState cursorState = HistoryDefaultCursorState;
if (_type == OverviewPhotos || _type == OverviewVideos) {
float64 w = (float64(_width - st::overviewPhotoSkip) / _photosInRow);
int32 inRow = int32((m.x() - (st::overviewPhotoSkip / 2)) / w), vsize = (_vsize + st::overviewPhotoSkip);
int32 col = int32((m.x() - (st::overviewPhotoSkip / 2)) / w), vsize = (_vsize + st::overviewPhotoSkip);
int32 row = int32((m.y() - _addToY - (st::overviewPhotoSkip / 2)) / vsize);
if (inRow < 0) inRow = 0;
if (col < 0) col = 0;
if (row < 0) row = 0;
bool upon = true;
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migratedCount = migratedIndexSkip();
int32 i = row * _photosInRow + inRow - _photosToAdd, count = migratedCount + overview.size();
int32 count = _items.size(), i = count - (row * _photosInRow + col - _photosToAdd) - 1;
if (i < 0) {
i = 0;
upon = false;
@@ -1451,18 +1379,11 @@ void OverviewInner::onUpdateSelected() {
upon = false;
}
if (i >= 0) {
MsgId msgid = (i >= migratedCount) ? overview[i - migratedCount] : (*migratedOverview)[i];
HistoryItem *histItem = App::histItemById((i >= migratedCount) ? _channel : _migrated->channelId(), msgid);
if (histItem) {
item = histItem;
if (LayoutMediaItem *media = _items.at(i)->toLayoutMediaItem()) {
item = media->getItem();
index = i;
if (upon && m.x() >= inRow * w + st::overviewPhotoSkip && m.x() < inRow * w + st::overviewPhotoSkip + _vsize) {
if (m.y() >= _addToY + row * vsize + st::overviewPhotoSkip && m.y() < _addToY + (row + 1) * vsize + st::overviewPhotoSkip) {
HistoryMedia *media = item->getMedia(true);
if (media) {
// media->getStateOverview(lnk, m.x() - inRow * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip, item, _vsize);
}
}
if (upon) {
media->getState(lnk, cursorState, m.x() - col * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip);
}
}
}
@@ -1618,11 +1539,32 @@ void OverviewInner::onUpdateSelected() {
bool lnkChanged = false;
if (lnk != textlnkOver()) {
lnkChanged = true;
redrawItem(App::hoveredLinkItem());
if (textlnkOver()) {
if (HistoryItem *item = App::hoveredLinkItem()) {
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
MsgId itemId = complexMsgId(item);
int32 itemIndex = oldMousedItemIndex;
fixItemIndex(itemIndex, itemId);
if (itemIndex >= 0) {
_items.at(itemIndex)->linkOut(textlnkOver());
redrawItem(itemId, itemIndex);
}
} else {
redrawItem(item);
}
}
}
textlnkOver(lnk);
App::hoveredLinkItem(lnk ? item : 0);
redrawItem(App::hoveredLinkItem());
QToolTip::hideText();
App::hoveredLinkItem(lnk ? item : 0);
if (textlnkOver()) {
if (item && index >= 0) {
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
_items.at(index)->linkOver(textlnkOver());
}
redrawItem(complexMsgId(item), index);
}
}
} else {
App::mousedItem(item);
}
@@ -1671,44 +1613,28 @@ void OverviewInner::onUpdateSelected() {
_selected[_dragItem] = 0;
updateDragSelection(0, -1, 0, -1, false);
} else if (canSelectMany) {
bool selectingDown = ((_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments || _type == OverviewLinks || _type == OverviewDocuments) ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && ((_type == OverviewPhotos || _type == OverviewVideos) ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
bool selectingDown = (_reversed ? (_mousedItemIndex < _dragItemIndex) : (_mousedItemIndex > _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && ((_type == OverviewPhotos || _type == OverviewVideos) ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
MsgId dragSelFrom = _dragItem, dragSelTo = _mousedItem;
int32 dragSelFromIndex = _dragItemIndex, dragSelToIndex = _mousedItemIndex;
if (!itemHasPoint(dragSelFrom, dragSelFromIndex, _dragStartPos.x(), _dragStartPos.y())) { // maybe exclude dragSelFrom
if (selectingDown) {
if (_type == OverviewPhotos || _type == OverviewVideos) {
if (_dragStartPos.x() >= _vsize || ((_mousedItem == dragSelFrom) && (m.x() < _dragStartPos.x() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
}
} else if (_type == OverviewAudioDocuments) {
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
} else {
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
}
} else if (_type == OverviewAudios) {
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, _reversed ? -1 : 1);
}
}
} else {
if (_type == OverviewPhotos || _type == OverviewVideos) {
if (_dragStartPos.x() < 0 || ((_mousedItem == dragSelFrom) && (m.x() >= _dragStartPos.x() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
} else if (_type == OverviewAudioDocuments) {
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
}
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
} else {
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
} else if (_type == OverviewAudios) {
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, _reversed ? 1 : -1);
}
}
}
@@ -1717,37 +1643,21 @@ void OverviewInner::onUpdateSelected() {
if (selectingDown) {
if (_type == OverviewPhotos || _type == OverviewVideos) {
if (m.x() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
}
} else if (_type == OverviewAudioDocuments) {
if (m.y() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
} else {
if (m.y() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
}
} else if (_type == OverviewAudios) {
if (m.y() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, _reversed ? 1 : -1);
}
}
} else {
if (_type == OverviewPhotos || _type == OverviewVideos) {
if (m.x() >= _vsize) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
} else if (_type == OverviewAudioDocuments) {
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
}
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
} else {
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
} else if (_type == OverviewAudios) {
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, _reversed ? -1 : 1);
}
}
}
@@ -1756,7 +1666,7 @@ void OverviewInner::onUpdateSelected() {
MsgId dragFirstAffected = dragSelFrom;
int32 dragFirstAffectedIndex = dragSelFromIndex;
while (dragFirstAffectedIndex >= 0 && itemMsgId(dragFirstAffected) <= 0) {
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments)) || (!selectingDown && (_type != OverviewPhotos && _type != OverviewVideos && _type != OverviewAudioDocuments))) ? -1 : 1);
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, selectingDown ? (_reversed ? -1 : 1) : (_reversed ? 1 : -1));
}
if (dragFirstAffectedIndex >= 0) {
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
@@ -2029,8 +1939,10 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
}
if ((_type == OverviewPhotos || _type == OverviewVideos) && _resizeIndex < 0) {
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
if (_resizeIndex < 0) {
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
}
}
resize(nwidth, height() > _minHeight ? height() : _minHeight);
showAll();
@@ -2059,17 +1971,9 @@ MediaOverviewType OverviewInner::type() const {
void OverviewInner::switchType(MediaOverviewType type) {
if (_type != type) {
_selected.clear();
_dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1;
_dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0;
_lnkOverIndex = _lnkDownIndex = 0;
for (int32 i = 0, l = _items.size(); i != l; ++i) {
delete _items.at(i);
}
_items.clear();
_cachedItems.clear();
_cached.clear();
clear();
_type = type;
_reversed = (_type != OverviewLinks && _type != OverviewDocuments);
if (_type == OverviewLinks || _type == OverviewDocuments) {
_search.show();
} else {
@@ -2348,17 +2252,71 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
int32 oldHeight = _height;
if (_type == OverviewDocuments) {
if (_type == OverviewPhotos || _type == OverviewVideos) {
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migrateCount = migratedIndexSkip();
int32 wasCount = _items.size(), fullCount = (migrateCount + o.size());
int32 tocheck = qMin(fullCount, _cachedItemsToBeLoaded);
_items.reserve(tocheck);
int32 index = 0;
bool allGood = true;
for (int32 i = fullCount, l = fullCount - tocheck; i > l;) {
--i;
MsgId msgid = ((i < migrateCount) ? -migratedOverview->at(i) : o.at(i - migrateCount));
if (allGood) {
if (_items.size() > index && complexMsgId(_items.at(index)->getItem()) == msgid) {
++index;
continue;
}
allGood = false;
}
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
HistoryMedia *media = item ? item->getMedia(true) : 0;
LayoutItem *layout = 0;
if (_type == OverviewPhotos) {
PhotoData *photo = (media && media->type() == MediaTypePhoto) ? static_cast<HistoryPhoto*>(media)->photo() : 0;
if (photo) layout = new LayoutOverviewPhoto(photo, item);
} else if (_type == OverviewVideos) {
VideoData *video = (media && media->type() == MediaTypeVideo) ? static_cast<HistoryVideo*>(media)->video() : 0;
if (video) layout = new LayoutOverviewVideo(video, item);
}
if (!layout) continue;
QDate date = item->date.date();
if (_items.size() > index) {
delete _items.at(index);
_items[index] = layout;
} else {
_items.push_back(layout);
}
layout->initDimensions();
layout->resizeGetHeight(_vsize);
++index;
}
for (int32 l = _items.size(); l > index;) {
delete _items.at(--l);
}
_items.resize(index);
if (!fromResize && _items.size() != wasCount) {
_height = qMax(recountHeight(), _minHeight);
if (height() != _height) {
resize(width(), _height);
}
}
dragActionUpdate(QCursor::pos());
update();
} else if (_type == OverviewDocuments) {
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migrateCount = migratedIndexSkip();
int32 l = _inSearch ? _searchResults.size() : (migrateCount + o.size()), tocheck = qMin(l, _cachedItemsToBeLoaded);
_items.reserve(2 * l); // day items
_items.reserve(2 * tocheck); // day items
int32 top = 0, in = 0, addtoheight = _addToY + st::linksSearchMargin.top();
bool allGood = true;
QDate prevDate;
for (int32 i = 0; i < tocheck; ++i) {
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount));
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -migratedOverview->at(l - i - 1) : o.at(l - i - 1 - migrateCount));
if (allGood) {
if (_items.size() > in && complexMsgId(_items.at(in)->getItem()) == msgid) {
prevDate = _items.at(in)->getItem()->date.date();
@@ -2391,7 +2349,8 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
}
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
HistoryMedia *media = item ? item->getMedia(true) : 0;
if (!media) continue;
DocumentData *document = media ? media->getDocument() : 0;
if (!document) continue;
QDate date = item->date.date();
if (!in || (in > 0 && date != prevDate)) {
@@ -2409,9 +2368,9 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
if (_items.size() > in) {
delete _items.at(in);
_items[in] = new LayoutOverviewDocument(media->getDocument(), item, top);
_items[in] = new LayoutOverviewDocument(document, item, top);
} else {
_items.push_back(new LayoutOverviewDocument(media->getDocument(), item, top));
_items.push_back(new LayoutOverviewDocument(document, item, top));
}
_items.at(in)->initDimensions();
top += _items.at(in)->resizeGetHeight(_rowWidth);
@@ -2435,13 +2394,13 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
int32 migrateCount = migratedIndexSkip();
int32 l = _inSearch ? _searchResults.size() : (migrateCount + o.size()), tocheck = qMin(l, _cachedItemsToBeLoaded);
_cachedItems.reserve(2 * l); // day items
_cachedItems.reserve(2 * tocheck); // day items
int32 y = 0, in = 0, addtoheight = _addToY + st::linksSearchMargin.top();
bool allGood = true;
QDate prevDate;
for (int32 i = 0; i < tocheck; ++i) {
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount));
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -migratedOverview->at(l - i - 1) : o.at(l - i - 1 - migrateCount));
if (allGood) {
if (_cachedItems.size() > in && _cachedItems.at(in).msgid == msgid) {
prevDate = _cachedItems.at(in).date;
@@ -2684,13 +2643,16 @@ void OverviewInner::redrawItem(const HistoryItem *msg) {
MsgId msgid = msg->id;
if (history->overviewHasMsgId(_type, msgid) && (history == _history || migrateindex > 0)) {
if (_type == OverviewPhotos || _type == OverviewVideos) {
int32 index = history->overview[_type].indexOf(msgid);
if (index >= 0) {
if (history == _history) index += migrateindex;
float64 w = (float64(width() - st::overviewPhotoSkip) / _photosInRow);
int32 vsize = (_vsize + st::overviewPhotoSkip);
int32 row = (_photosToAdd + index) / _photosInRow, col = (_photosToAdd + index) % _photosInRow;
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
if (history == _migrated) msgid = -msgid;
for (int32 i = 0, l = _items.size(); i != l; ++i) {
if (complexMsgId(_items.at(i)->getItem()) == msgid) {
int32 shownAtIndex = _items.size() - i - 1;
float64 w = (float64(width() - st::overviewPhotoSkip) / _photosInRow);
int32 vsize = (_vsize + st::overviewPhotoSkip);
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
break;
}
}
} else if (_type == OverviewAudioDocuments) {
int32 index = history->overview[_type].indexOf(msgid);
@@ -2726,12 +2688,10 @@ void OverviewInner::redrawItem(const HistoryItem *msg) {
}
}
void OverviewInner::showAll(bool recountHeights) {
int32 newHeight = height();
int32 OverviewInner::recountHeight() {
int32 result = _height;
if (_type == OverviewPhotos || _type == OverviewVideos) {
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
_vsize = (int32(width() - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
int32 count = _items.size();
int32 migratedFullCount = _migrated ? _migrated->overviewCount(_type) : 0;
int32 fullCount = migratedFullCount + _history->overviewCount(_type);
if (fullCount > 0 && migratedFullCount >= 0) {
@@ -2742,8 +2702,21 @@ void OverviewInner::showAll(bool recountHeights) {
_photosToAdd = 0;
}
int32 rows = ((_photosToAdd + count) / _photosInRow) + (((_photosToAdd + count) % _photosInRow) ? 1 : 0);
newHeight = _height = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
result = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
_addToY = (result < _minHeight) ? (_minHeight - result) : 0;
}
return result;
}
void OverviewInner::showAll(bool recountHeights) {
int32 newHeight = height();
if (_type == OverviewPhotos || _type == OverviewVideos) {
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
_vsize = (int32(width() - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
for (int32 i = 0, l = _items.size(); i < l; ++i) {
_items.at(i)->resizeGetHeight(_vsize);
}
newHeight = _height = recountHeight();
} else if (_type == OverviewAudioDocuments) {
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
newHeight = _height = count * _rowHeight + 2 * st::playlistPadding;
@@ -2834,6 +2807,7 @@ void OverviewWidget::onScroll() {
}
void OverviewWidget::resizeEvent(QResizeEvent *e) {
_noDropResizeIndex = true;
int32 st = _scroll.scrollTop();
_scroll.resize(size());
int32 newScrollTop = _inner.resizeToWidth(width(), st, height());
@@ -2841,10 +2815,9 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) {
newScrollTop += addToY;
}
if (newScrollTop != _scroll.scrollTop()) {
_noDropResizeIndex = true;
_scroll.scrollToY(newScrollTop);
_noDropResizeIndex = false;
}
_noDropResizeIndex = false;
_topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0);
@@ -3079,9 +3052,15 @@ void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) {
}
}
void OverviewWidget::ui_redrawHistoryItem(const HistoryItem *msg) {
if (peer() == msg->history()->peer || migratePeer() == msg->history()->peer) {
_inner.redrawItem(msg);
void OverviewWidget::ui_redrawHistoryItem(const HistoryItem *item) {
if (peer() == item->history()->peer || migratePeer() == item->history()->peer) {
_inner.redrawItem(item);
}
}
void OverviewWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
if (peer() == item->history()->peer || migratePeer() == item->history()->peer) {
_inner.onUpdateSelected();
}
}