From 94fe669c6e26a9443601a7e746cb00f8c4753b2b Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 29 Sep 2015 16:24:39 +0300 Subject: [PATCH] dialogs optimizations, qt 5.5.0 xcode 7 build --- Telegram/Build.sh | 4 + Telegram/SourceFiles/dialogswidget.cpp | 509 ++++++++++-------- Telegram/SourceFiles/dialogswidget.h | 20 +- Telegram/SourceFiles/gui/scrollarea.cpp | 134 ++++- Telegram/SourceFiles/gui/scrollarea.h | 74 ++- Telegram/SourceFiles/history.cpp | 10 +- Telegram/SourceFiles/history.h | 8 +- Telegram/SourceFiles/historywidget.cpp | 135 +++-- Telegram/SourceFiles/historywidget.h | 8 +- Telegram/SourceFiles/mainwidget.cpp | 2 +- Telegram/SourceFiles/pspecific_mac.cpp | 6 +- Telegram/SourceFiles/title.cpp | 2 +- Telegram/SourceFiles/window.cpp | 5 +- .../qtbase/src/corelib/kernel/qobjectdefs.h | 509 ------------------ .../platforms/cocoa/qcocoabackingstore.h | 2 +- .../platforms/cocoa/qcocoabackingstore.mm | 7 +- 16 files changed, 571 insertions(+), 864 deletions(-) delete mode 100644 Telegram/_qt_5_5_0_patch/qtbase/src/corelib/kernel/qobjectdefs.h diff --git a/Telegram/Build.sh b/Telegram/Build.sh index 70b0cc86d..9e31e8f31 100755 --- a/Telegram/Build.sh +++ b/Telegram/Build.sh @@ -105,6 +105,10 @@ if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ]; then fi if [ "$BuildTarget" == "mac" ] || [ "$BuildTarget" == "mac32" ] || [ "$BuildTarget" == "macstore" ]; then + + touch ./SourceFiles/telegram.qrc or exit 1 + xcodebuild -project Telegram.xcodeproj -alltargets -configuration Release build or exit 1 + if [ ! -d "$ReleasePath/$BinaryName.app" ]; then echo "$BinaryName.app not found!" exit 1 diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index b9510f08c..1b613afd7 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -27,7 +27,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org #include "localstorage.h" -DialogsListWidget::DialogsListWidget(QWidget *parent, MainWidget *main) : QWidget(parent), +DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(parent), dialogs(DialogsSortByDate), contactsNoDialogs(DialogsSortByName), contacts(DialogsSortByName), @@ -54,43 +54,43 @@ _searchInPeer(0) { refresh(false); } -int32 DialogsListWidget::filteredOffset() const { +int32 DialogsInner::filteredOffset() const { return hashtagResults.size() * st::mentionHeight; } -int32 DialogsListWidget::peopleOffset() const { +int32 DialogsInner::peopleOffset() const { return filteredOffset() + (filterResults.size() * st::dlgHeight) + st::searchedBarHeight; } -int32 DialogsListWidget::searchedOffset() const { +int32 DialogsInner::searchedOffset() const { int32 result = peopleOffset() + (peopleResults.isEmpty() ? 0 : ((peopleResults.size() * st::dlgHeight) + st::searchedBarHeight)); if (_searchInPeer) result += st::dlgHeight; return result; } -void DialogsListWidget::paintEvent(QPaintEvent *e) { +void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) { if (!App::main()) return; - QRect r(e->rect()); - bool trivial = (rect() == r); - - Painter p(this); - if (!trivial) { - p.setClipRect(r); + QRect r(region.boundingRect()); + if (!paintingOther && !r.contains(rect())) { + p.setClipRect(rect().intersected(r)); } - + if (_state == DefaultState) { int32 otherStart = dialogs.list.count * st::dlgHeight; PeerData *active = App::main()->activePeer(), *selected = sel ? sel->history->peer : 0; if (otherStart) { - dialogs.list.paint(p, width(), r.top(), r.bottom(), active, selected); + dialogs.list.paint(p, fullWidth(), r.top(), r.top() + r.height(), active, selected, paintingOther); } if (contactsNoDialogs.list.count && false) { - contactsNoDialogs.list.paint(p, width(), r.top() - otherStart, r.bottom() - otherStart, active, selected); + contactsNoDialogs.list.paint(p, fullWidth(), r.top() - otherStart, r.top() + r.height() - otherStart, active, selected, paintingOther); } else if (!otherStart) { - p.setFont(st::noContactsFont->f); - p.setPen(st::noContactsColor->p); - p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center); + p.fillRect(r, st::white->b); + if (!paintingOther) { + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, fullWidth(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_chats : lng_contacts_loading), style::al_center); + } } } else if (_state == FilteredState || _state == SearchedState) { if (!hashtagResults.isEmpty()) { @@ -102,37 +102,39 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { } p.translate(0, from * st::mentionHeight); if (from < hashtagResults.size()) { - int32 to = (r.bottom() / int32(st::mentionHeight)) + 1, w = width(), htagwidth = w - st::dlgPaddingHor * 2; + int32 to = (r.bottom() / int32(st::mentionHeight)) + 1, w = fullWidth(), htagwidth = w - st::dlgPaddingHor * 2; if (to > hashtagResults.size()) to = hashtagResults.size(); p.setFont(st::mentionFont->f); p.setPen(st::black->p); for (; from < to; ++from) { bool selected = (from == hashtagSel); - if (selected) { - p.fillRect(0, 0, w, st::mentionHeight, st::mentionBgOver->b); - int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2; - p.drawPixmap(QPoint(w - st::notifyClose.icon.pxWidth() - skip, skip), App::sprite(), st::notifyClose.icon); - } + p.fillRect(0, 0, w, st::mentionHeight, (selected ? st::mentionBgOver : st::white)->b); + if (!paintingOther) { + if (selected) { + int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2; + p.drawPixmap(QPoint(w - st::notifyClose.icon.pxWidth() - skip, skip), App::sprite(), st::notifyClose.icon); - QString first = (_hashtagFilter.size() < 2) ? QString() : ('#' + hashtagResults.at(from).mid(0, _hashtagFilter.size() - 1)), second = (_hashtagFilter.size() < 2) ? ('#' + hashtagResults.at(from)) : hashtagResults.at(from).mid(_hashtagFilter.size() - 1); - int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second); - if (htagwidth < firstwidth + secondwidth) { - if (htagwidth < firstwidth + st::mentionFont->elidew) { - first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, htagwidth); - second = QString(); - } else { - second = st::mentionFont->m.elidedText(second, Qt::ElideRight, htagwidth - firstwidth); } - } + QString first = (_hashtagFilter.size() < 2) ? QString() : ('#' + hashtagResults.at(from).mid(0, _hashtagFilter.size() - 1)), second = (_hashtagFilter.size() < 2) ? ('#' + hashtagResults.at(from)) : hashtagResults.at(from).mid(_hashtagFilter.size() - 1); + int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second); + if (htagwidth < firstwidth + secondwidth) { + if (htagwidth < firstwidth + st::mentionFont->elidew) { + first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, htagwidth); + second = QString(); + } else { + second = st::mentionFont->m.elidedText(second, Qt::ElideRight, htagwidth - firstwidth); + } + } - p.setFont(st::mentionFont->f); - if (!first.isEmpty()) { - p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p); - p.drawText(st::dlgPaddingHor, st::mentionTop + st::mentionFont->ascent, first); - } - if (!second.isEmpty()) { - p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); - p.drawText(st::dlgPaddingHor + firstwidth, st::mentionTop + st::mentionFont->ascent, second); + p.setFont(st::mentionFont->f); + if (!first.isEmpty()) { + p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p); + p.drawText(st::dlgPaddingHor, st::mentionTop + st::mentionFont->ascent, first); + } + if (!second.isEmpty()) { + p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); + p.drawText(st::dlgPaddingHor + firstwidth, st::mentionTop + st::mentionFont->ascent, second); + } } p.translate(0, st::mentionHeight); } @@ -148,24 +150,26 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { } p.translate(0, from * st::dlgHeight); if (from < filterResults.size()) { - int32 to = (r.bottom() / int32(st::dlgHeight)) + 1, w = width(); + int32 to = (r.bottom() / int32(st::dlgHeight)) + 1, w = fullWidth(); if (to > filterResults.size()) to = filterResults.size(); for (; from < to; ++from) { bool active = (filterResults[from]->history->peer == App::main()->activePeer() && !App::main()->activeMsgId()); bool selected = (from == filteredSel); - filterResults[from]->paint(p, w, active, selected); + filterResults[from]->paint(p, w, active, selected, paintingOther); p.translate(0, st::dlgHeight); } } } if (!peopleResults.isEmpty()) { - p.fillRect(0, 0, width(), st::searchedBarHeight, st::searchedBarBG->b); - p.setFont(st::searchedBarFont->f); - p.setPen(st::searchedBarColor->p); - p.drawText(QRect(0, 0, width(), st::searchedBarHeight), lang(lng_search_global_results), style::al_center); + p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b); + if (!paintingOther) { + p.setFont(st::searchedBarFont->f); + p.setPen(st::searchedBarColor->p); + p.drawText(QRect(0, 0, fullWidth(), st::searchedBarHeight), lang(lng_search_global_results), style::al_center); + } p.translate(0, st::searchedBarHeight); - + int32 skip = peopleOffset(); int32 from = (r.top() - skip) / int32(st::dlgHeight); if (from < 0) { @@ -175,35 +179,39 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { } p.translate(0, from * st::dlgHeight); if (from < peopleResults.size()) { - int32 to = ((r.bottom() - skip) / int32(st::dlgHeight)) + 1, w = width(); + int32 to = ((r.bottom() - skip) / int32(st::dlgHeight)) + 1, w = fullWidth(); if (to > peopleResults.size()) to = peopleResults.size(); for (; from < to; ++from) { bool active = (peopleResults[from] == App::main()->activePeer() && !App::main()->activeMsgId()); bool selected = (from == peopleSel); - peopleResultPaint(peopleResults[from], p, w, active, selected); + peopleResultPaint(peopleResults[from], p, w, active, selected, paintingOther); p.translate(0, st::dlgHeight); } } } if (_searchInPeer) { - searchInPeerPaint(p, width()); + searchInPeerPaint(p, fullWidth(), paintingOther); p.translate(0, st::dlgHeight); if (_state == FilteredState && searchResults.isEmpty()) { - p.fillRect(0, 0, width(), st::searchedBarHeight, st::searchedBarBG->b); - p.setFont(st::searchedBarFont->f); - p.setPen(st::searchedBarColor->p); - p.drawText(QRect(0, 0, width(), st::searchedBarHeight), lang(lng_dlg_search_for_messages), style::al_center); + p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b); + if (!paintingOther) { + p.setFont(st::searchedBarFont->f); + p.setPen(st::searchedBarColor->p); + p.drawText(QRect(0, 0, fullWidth(), st::searchedBarHeight), lang(lng_dlg_search_for_messages), style::al_center); + } p.translate(0, st::searchedBarHeight); } } if (_state == SearchedState || !searchResults.isEmpty()) { QString text = lng_search_found_results(lt_count, searchResults.isEmpty() ? 0 : searchedCount); - p.fillRect(0, 0, width(), st::searchedBarHeight, st::searchedBarBG->b); - p.setFont(st::searchedBarFont->f); - p.setPen(st::searchedBarColor->p); - p.drawText(QRect(0, 0, width(), st::searchedBarHeight), text, style::al_center); + p.fillRect(0, 0, fullWidth(), st::searchedBarHeight, st::searchedBarBG->b); + if (!paintingOther) { + p.setFont(st::searchedBarFont->f); + p.setPen(st::searchedBarColor->p); + p.drawText(QRect(0, 0, fullWidth(), st::searchedBarHeight), text, style::al_center); + } p.translate(0, st::searchedBarHeight); int32 skip = searchedOffset(); @@ -215,12 +223,12 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { } p.translate(0, from * st::dlgHeight); if (from < searchResults.size()) { - int32 to = ((r.bottom() - skip) / int32(st::dlgHeight)) + 1, w = width(); + int32 to = ((r.bottom() - skip) / int32(st::dlgHeight)) + 1, w = fullWidth(); if (to > searchResults.size()) to = searchResults.size(); for (; from < to; ++from) { bool active = (searchResults[from]->_item->history()->peer == App::main()->activePeer() && searchResults[from]->_item->id == App::main()->activeMsgId()); bool selected = (from == searchedSel); - searchResults[from]->paint(p, w, active, selected); + searchResults[from]->paint(p, w, active, selected, paintingOther); p.translate(0, st::dlgHeight); } } @@ -228,9 +236,10 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { } } -void DialogsListWidget::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel) const { +void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const { QRect fullRect(0, 0, w, st::dlgHeight); p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b); + if (onlyBackground) return; History *history = App::history(peer->id); @@ -277,9 +286,10 @@ void DialogsListWidget::peopleResultPaint(PeerData *peer, Painter &p, int32 w, b peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } -void DialogsListWidget::searchInPeerPaint(Painter &p, int32 w) const { +void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const { QRect fullRect(0, 0, w, st::dlgHeight); p.fillRect(fullRect, st::dlgBG->b); + if (onlyBackground) return; p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, _searchInPeer->photo->pix(st::dlgPhotoSize)); @@ -305,17 +315,16 @@ void DialogsListWidget::searchInPeerPaint(Painter &p, int32 w) const { _searchInPeer->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } -void DialogsListWidget::activate() { +void DialogsInner::activate() { } -void DialogsListWidget::mouseMoveEvent(QMouseEvent *e) { +void DialogsInner::mouseMoveEvent(QMouseEvent *e) { lastMousePos = mapToGlobal(e->pos()); selByMouse = true; onUpdateSelected(true); - update(); } -void DialogsListWidget::onUpdateSelected(bool force) { +void DialogsInner::onUpdateSelected(bool force) { QPoint mouse(mapFromGlobal(lastMousePos)); if ((!force && !rect().contains(mouse)) || !selByMouse) return; @@ -331,65 +340,67 @@ void DialogsListWidget::onUpdateSelected(bool force) { contactSel = true; } if (newSel != sel) { + updateSelectedRow(); sel = newSel; + updateSelectedRow(); setCursor(sel ? style::cur_pointer : style::cur_default); - parentWidget()->update(); } } else if (_state == FilteredState || _state == SearchedState) { if (!hashtagResults.isEmpty()) { - int32 newHashtagSel = mouseY / int32(st::mentionHeight); + int32 skip = 0, newHashtagSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::mentionHeight)) : -1; if (newHashtagSel < 0 || newHashtagSel >= hashtagResults.size()) { newHashtagSel = -1; } if (newHashtagSel != hashtagSel) { + updateSelectedRow(); hashtagSel = newHashtagSel; + updateSelectedRow(); setCursor((hashtagSel >= 0) ? style::cur_pointer : style::cur_default); - parentWidget()->update(); } if (hashtagSel >= 0) { _overDelete = (mouse.x() >= w - st::mentionHeight); } - mouseY -= filteredOffset(); } if (!filterResults.isEmpty()) { - int32 newFilteredSel = (mouseY >= 0) ? (mouseY / int32(st::dlgHeight)) : -1; + int32 skip = filteredOffset(), newFilteredSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; if (newFilteredSel < 0 || newFilteredSel >= filterResults.size()) { newFilteredSel = -1; } if (newFilteredSel != filteredSel) { + updateSelectedRow(); filteredSel = newFilteredSel; + updateSelectedRow(); setCursor((filteredSel >= 0) ? style::cur_pointer : style::cur_default); - parentWidget()->update(); } } - mouseY -= peopleOffset() - filteredOffset(); if (!peopleResults.isEmpty()) { - int32 newPeopleSel = (mouseY >= 0) ? (mouseY / int32(st::dlgHeight)) : -1; + int32 skip = peopleOffset(), newPeopleSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; if (newPeopleSel < 0 || newPeopleSel >= peopleResults.size()) { newPeopleSel = -1; } if (newPeopleSel != peopleSel) { + updateSelectedRow(); peopleSel = newPeopleSel; + updateSelectedRow(); setCursor((peopleSel >= 0) ? style::cur_pointer : style::cur_default); - parentWidget()->update(); } } - mouseY -= searchedOffset() - peopleOffset(); if (_state == SearchedState && !searchResults.isEmpty()) { - int32 newSearchedSel = (mouseY >= 0) ? (mouseY / int32(st::dlgHeight)) : -1; + int32 skip = searchedOffset(), newSearchedSel = (mouseY >= skip) ? ((mouseY - skip) / int32(st::dlgHeight)) : -1; if (newSearchedSel < 0 || newSearchedSel >= searchResults.size()) { newSearchedSel = -1; } if (newSearchedSel != searchedSel) { + updateSelectedRow(); searchedSel = newSearchedSel; + updateSelectedRow(); setCursor((searchedSel >= 0) ? style::cur_pointer : style::cur_default); - parentWidget()->update(); } } } } -void DialogsListWidget::mousePressEvent(QMouseEvent *e) { +void DialogsInner::mousePressEvent(QMouseEvent *e) { lastMousePos = mapToGlobal(e->pos()); selByMouse = true; onUpdateSelected(true); @@ -398,12 +409,12 @@ void DialogsListWidget::mousePressEvent(QMouseEvent *e) { } } -void DialogsListWidget::resizeEvent(QResizeEvent *e) { +void DialogsInner::resizeEvent(QResizeEvent *e) { _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); _cancelSearchInPeer.move(width() - st::dlgPaddingHor - st::btnCancelSearch.width, (st::dlgHeight - st::btnCancelSearch.height) / 2); } -void DialogsListWidget::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) { +void DialogsInner::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) { if (_state == FilteredState || _state == SearchedState) { for (FilteredDialogs::iterator i = filterResults.begin(); i != filterResults.end();) { if (*i == oldRow) { // this row is shown in filtered and maybe is in contacts! @@ -423,7 +434,7 @@ void DialogsListWidget::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow } } -void DialogsListWidget::createDialog(History *history) { +void DialogsInner::createDialog(History *history) { bool creating = history->dialogs.isEmpty(); if (creating) { history->dialogs = dialogs.addToEnd(history); @@ -439,12 +450,12 @@ void DialogsListWidget::createDialog(History *history) { if (creating) { refresh(); - } else { - parentWidget()->update(); + } else if (_state == DefaultState && movedFrom != movedTo) { + update(0, qMin(movedFrom, movedTo) * st::dlgHeight, fullWidth(), qAbs(movedFrom - movedTo) * st::dlgHeight); } } -void DialogsListWidget::removePeer(PeerData *peer) { +void DialogsInner::removePeer(PeerData *peer) { if (sel && sel->history->peer == peer) { sel = 0; } @@ -466,7 +477,7 @@ void DialogsListWidget::removePeer(PeerData *peer) { refresh(); } -void DialogsListWidget::removeContact(UserData *user) { +void DialogsInner::removeContact(UserData *user) { if (sel && sel->history->peer == user) { sel = 0; } @@ -476,38 +487,36 @@ void DialogsListWidget::removeContact(UserData *user) { refresh(); } -void DialogsListWidget::dlgUpdated(DialogRow *row) { +void DialogsInner::dlgUpdated(DialogRow *row) { if (_state == DefaultState) { - update(0, row->pos * st::dlgHeight, width(), st::dlgHeight); + update(0, row->pos * st::dlgHeight, fullWidth(), st::dlgHeight); } else if (_state == FilteredState || _state == SearchedState) { - int32 cnt = 0; - for (FilteredDialogs::const_iterator i = filterResults.cbegin(), e = filterResults.cend(); i != e; ++i) { - if ((*i)->history == row->history) { - update(0, cnt * st::dlgHeight, width(), st::dlgHeight); + for (int32 i = 0, l = filterResults.size(); i < l; ++i) { + if (filterResults.at(i)->history == row->history) { + update(0, i * st::dlgHeight, fullWidth(), st::dlgHeight); break; } - ++cnt; } } } -void DialogsListWidget::dlgUpdated(History *history) { +void DialogsInner::dlgUpdated(History *history) { if (_state == DefaultState) { DialogRow *row = 0; DialogsList::RowByPeer::iterator i = dialogs.list.rowByPeer.find(history->peer->id); if (i != dialogs.list.rowByPeer.cend()) { - update(0, i.value()->pos * st::dlgHeight, width(), st::dlgHeight); + update(0, i.value()->pos * st::dlgHeight, fullWidth(), st::dlgHeight); } else { i = contactsNoDialogs.list.rowByPeer.end();// find(history->peer->id); if (i != contactsNoDialogs.list.rowByPeer.cend()) { - update(0, (dialogs.list.count + i.value()->pos) * st::dlgHeight, width(), st::dlgHeight); + update(0, (dialogs.list.count + i.value()->pos) * st::dlgHeight, fullWidth(), st::dlgHeight); } } } else if (_state == FilteredState || _state == SearchedState) { int32 cnt = 0, add = filteredOffset(); for (FilteredDialogs::const_iterator i = filterResults.cbegin(), e = filterResults.cend(); i != e; ++i) { if ((*i)->history == history) { - update(0, cnt * st::dlgHeight, width(), st::dlgHeight); + update(0, cnt * st::dlgHeight, fullWidth(), st::dlgHeight); break; } ++cnt; @@ -516,7 +525,7 @@ void DialogsListWidget::dlgUpdated(History *history) { int32 cnt = 0, add = peopleOffset(); for (PeopleResults::const_iterator i = peopleResults.cbegin(), e = peopleResults.cend(); i != e; ++i) { if ((*i) == history->peer) { - update(0, add + cnt * st::dlgHeight, width(), st::dlgHeight); + update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight); break; } ++cnt; @@ -526,7 +535,7 @@ void DialogsListWidget::dlgUpdated(History *history) { int32 cnt = 0, add = searchedOffset(); for (SearchResults::const_iterator i = searchResults.cbegin(), e = searchResults.cend(); i != e; ++i) { if ((*i)->_item->history() == history) { - update(0, add + cnt * st::dlgHeight, width(), st::dlgHeight); + update(0, add + cnt * st::dlgHeight, fullWidth(), st::dlgHeight); break; } ++cnt; @@ -535,24 +544,43 @@ void DialogsListWidget::dlgUpdated(History *history) { } } -void DialogsListWidget::enterEvent(QEvent *e) { +void DialogsInner::enterEvent(QEvent *e) { setMouseTracking(true); lastMousePos = QCursor::pos(); onUpdateSelected(true); } -void DialogsListWidget::leaveEvent(QEvent *e) { +void DialogsInner::updateSelectedRow() { + if (_state == DefaultState) { + if (sel) { + update(0, sel->pos * st::dlgHeight, fullWidth(), st::dlgHeight); + } + } else if (_state == FilteredState || _state == SearchedState) { + if (hashtagSel >= 0) { + update(0, hashtagSel * st::mentionHeight, fullWidth(), st::mentionHeight); + } else if (filteredSel >= 0) { + update(0, filteredOffset() + filteredSel * st::dlgHeight, fullWidth(), st::dlgHeight); + } else if (peopleSel >= 0) { + update(0, peopleOffset() + peopleSel * st::dlgHeight, fullWidth(), st::dlgHeight); + } else if (searchedSel >= 0) { + update(0, searchedOffset() + searchedSel * st::dlgHeight, fullWidth(), st::dlgHeight); + } + } + +} + +void DialogsInner::leaveEvent(QEvent *e) { setMouseTracking(false); selByMouse = false; if (sel || filteredSel >= 0 || hashtagSel >= 0 || searchedSel >= 0 || peopleSel >= 0) { + updateSelectedRow(); sel = 0; filteredSel = searchedSel = peopleSel = hashtagSel = -1; setCursor(style::cur_default); - parentWidget()->update(); } } -void DialogsListWidget::onParentGeometryChanged() { +void DialogsInner::onParentGeometryChanged() { lastMousePos = QCursor::pos(); if (rect().contains(mapFromGlobal(lastMousePos))) { setMouseTracking(true); @@ -560,18 +588,18 @@ void DialogsListWidget::onParentGeometryChanged() { } } -void DialogsListWidget::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) { +void DialogsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) { dialogs.peerNameChanged(peer, oldNames, oldChars); contactsNoDialogs.peerNameChanged(peer, oldNames, oldChars); contacts.peerNameChanged(peer, oldNames, oldChars); - parentWidget()->update(); + update(); } -void DialogsListWidget::onPeerPhotoChanged(PeerData *peer) { - parentWidget()->update(); +void DialogsInner::onPeerPhotoChanged(PeerData *peer) { + update(); } -void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) { +void DialogsInner::onFilterUpdate(QString newFilter, bool force) { newFilter = textSearchKey(newFilter); if (newFilter != filter || force) { QStringList f; @@ -679,7 +707,7 @@ void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) { } } -void DialogsListWidget::onHashtagFilterUpdate(QStringRef newFilter) { +void DialogsInner::onHashtagFilterUpdate(QStringRef newFilter) { if (newFilter.isEmpty() || newFilter.at(0) != '#' || _searchInPeer) { _hashtagFilter = QString(); if (!hashtagResults.isEmpty()) { @@ -708,11 +736,11 @@ void DialogsListWidget::onHashtagFilterUpdate(QStringRef newFilter) { setMouseSel(false, true); } -DialogsListWidget::~DialogsListWidget() { +DialogsInner::~DialogsInner() { clearSearchResults(); } -void DialogsListWidget::clearSearchResults(bool clearPeople) { +void DialogsInner::clearSearchResults(bool clearPeople) { if (clearPeople) peopleResults.clear(); if (!searchResults.isEmpty()) { for (SearchResults::const_iterator i = searchResults.cbegin(), e = searchResults.cend(); i != e; ++i) { @@ -723,7 +751,7 @@ void DialogsListWidget::clearSearchResults(bool clearPeople) { _lastSearchId = 0; } -void DialogsListWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { +void DialogsInner::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { for (int i = 0; i < searchResults.size(); ++i) { if (searchResults[i]->_item == oldItem) { searchResults[i]->_item = newItem; @@ -731,7 +759,7 @@ void DialogsListWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) } } -PeerData *DialogsListWidget::updateFromParentDrag(QPoint globalPos) { +PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) { lastMousePos = globalPos; selByMouse = true; onUpdateSelected(true); @@ -751,7 +779,7 @@ PeerData *DialogsListWidget::updateFromParentDrag(QPoint globalPos) { return 0; } -void DialogsListWidget::itemRemoved(HistoryItem *item) { +void DialogsInner::itemRemoved(HistoryItem *item) { int wasCount = searchResults.size(); for (int i = 0; i < searchResults.size();) { if (searchResults[i]->_item == item) { @@ -766,7 +794,7 @@ void DialogsListWidget::itemRemoved(HistoryItem *item) { } } -void DialogsListWidget::dialogsReceived(const QVector &added) { +void DialogsInner::dialogsReceived(const QVector &added) { for (QVector::const_iterator i = added.cbegin(), e = added.cend(); i != e; ++i) { History *history = 0; switch (i->type()) { @@ -813,7 +841,7 @@ void DialogsListWidget::dialogsReceived(const QVector &added) { refresh(); } -void DialogsListWidget::addSavedPeersAfter(const QDateTime &date) { +void DialogsInner::addSavedPeersAfter(const QDateTime &date) { SavedPeersByTime &saved(cRefSavedPeersByTime()); while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) { History *history = App::history(saved.last()->id); @@ -823,11 +851,11 @@ void DialogsListWidget::addSavedPeersAfter(const QDateTime &date) { } } -void DialogsListWidget::addAllSavedPeers() { +void DialogsInner::addAllSavedPeers() { addSavedPeersAfter(QDateTime()); } -void DialogsListWidget::searchReceived(const QVector &messages, bool fromStart, int32 fullCount) { +void DialogsInner::searchReceived(const QVector &messages, bool fromStart, int32 fullCount) { if (fromStart) { clearSearchResults(false); } @@ -843,7 +871,7 @@ void DialogsListWidget::searchReceived(const QVector &messages, bool refresh(); } -void DialogsListWidget::peopleReceived(const QString &query, const QVector &people) { +void DialogsInner::peopleReceived(const QString &query, const QVector &people) { peopleQuery = query.toLower().trimmed(); peopleResults.clear(); peopleResults.reserve(people.size()); @@ -857,7 +885,7 @@ void DialogsListWidget::peopleReceived(const QString &query, const QVector &contacts) { +void DialogsInner::contactsReceived(const QVector &contacts) { for (QVector::const_iterator i = contacts.cbegin(), e = contacts.cend(); i != e; ++i) { int32 uid = i->c_contact().vuser_id.v; addNewContact(uid); @@ -872,7 +900,7 @@ void DialogsListWidget::contactsReceived(const QVector &contacts) { refresh(); } -int32 DialogsListWidget::addNewContact(int32 uid, bool select) { // -2 - err, -1 - don't scroll, >= 0 - scroll +int32 DialogsInner::addNewContact(int32 uid, bool select) { // -2 - err, -1 - don't scroll, >= 0 - scroll PeerId peer = peerFromUser(uid); if (!App::peerLoaded(peer)) return -2; @@ -891,7 +919,7 @@ int32 DialogsListWidget::addNewContact(int32 uid, bool select) { // -2 - err, -1 return i.value()->pos * st::dlgHeight; } -void DialogsListWidget::refresh(bool toTop) { +void DialogsInner::refresh(bool toTop) { int32 h = 0; if (_state == DefaultState) { h = (dialogs.list.count/* + contactsNoDialogs.list.count*/) * st::dlgHeight; @@ -908,20 +936,20 @@ void DialogsListWidget::refresh(bool toTop) { } else { if (!_addContactLnk.isHidden()) _addContactLnk.hide(); if (_state == FilteredState) { - h = searchedOffset() + (searchResults.count() * st::dlgHeight) + ((searchResults.isEmpty() && !_searchInPeer) ? 0 : st::searchedBarHeight); + h = searchedOffset() + (searchResults.count() * st::dlgHeight) + ((searchResults.isEmpty() && !_searchInPeer) ? -st::searchedBarHeight : 0); } else if (_state == SearchedState) { - h = searchedOffset() + (searchResults.count() * st::dlgHeight) + st::searchedBarHeight; + h = searchedOffset() + (searchResults.count() * st::dlgHeight); } } - resize(width(), h); + setHeight(h ); if (toTop) { emit mustScrollTo(0, 0); loadPeerPhotos(0); } - parentWidget()->update(); + update(); } -void DialogsListWidget::setMouseSel(bool msel, bool toTop) { +void DialogsInner::setMouseSel(bool msel, bool toTop) { selByMouse = msel; if (!selByMouse && toTop) { if (_state == DefaultState) { @@ -934,7 +962,7 @@ void DialogsListWidget::setMouseSel(bool msel, bool toTop) { } } -void DialogsListWidget::setState(State newState) { +void DialogsInner::setState(State newState) { _state = newState; if (_state == DefaultState) { clearSearchResults(); @@ -949,15 +977,15 @@ void DialogsListWidget::setState(State newState) { refresh(true); } -DialogsListWidget::State DialogsListWidget::state() const { +DialogsInner::State DialogsInner::state() const { return _state; } -bool DialogsListWidget::hasFilteredResults() const { +bool DialogsInner::hasFilteredResults() const { return !filterResults.isEmpty() && hashtagResults.isEmpty(); } -void DialogsListWidget::searchInPeer(PeerData *peer) { +void DialogsInner::searchInPeer(PeerData *peer) { _searchInPeer = peer; if (_searchInPeer) { onHashtagFilterUpdate(QStringRef()); @@ -967,7 +995,7 @@ void DialogsListWidget::searchInPeer(PeerData *peer) { } } -void DialogsListWidget::clearFilter() { +void DialogsInner::clearFilter() { if (_state == FilteredState || _state == SearchedState) { if (_searchInPeer) { _state = FilteredState; @@ -984,7 +1012,7 @@ void DialogsListWidget::clearFilter() { } } -void DialogsListWidget::selectSkip(int32 direction) { +void DialogsInner::selectSkip(int32 direction) { if (_state == DefaultState) { if (!sel) { if (dialogs.list.count && direction > 0) { @@ -1053,10 +1081,10 @@ void DialogsListWidget::selectSkip(int32 direction) { emit mustScrollTo(searchedOffset() + searchedSel * st::dlgHeight + (searchedSel ? 0 : -st::searchedBarHeight), searchedOffset() + (searchedSel + 1) * st::dlgHeight); } } - parentWidget()->update(); + update(); } -void DialogsListWidget::scrollToPeer(const PeerId &peer, MsgId msgId) { +void DialogsInner::scrollToPeer(const PeerId &peer, MsgId msgId) { int32 fromY = -1; if (_state == DefaultState) { DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(peer); @@ -1091,7 +1119,7 @@ void DialogsListWidget::scrollToPeer(const PeerId &peer, MsgId msgId) { } } -void DialogsListWidget::selectSkipPage(int32 pixels, int32 direction) { +void DialogsInner::selectSkipPage(int32 pixels, int32 direction) { int32 toSkip = pixels / int32(st::dlgHeight); if (_state == DefaultState) { if (!sel) { @@ -1131,10 +1159,10 @@ void DialogsListWidget::selectSkipPage(int32 pixels, int32 direction) { } else { return selectSkip(direction * toSkip); } - parentWidget()->update(); + update(); } -void DialogsListWidget::loadPeerPhotos(int32 yFrom) { +void DialogsInner::loadPeerPhotos(int32 yFrom) { int32 yTo = yFrom + parentWidget()->height() * 5; MTP::clearLoaderPriorities(); if (_state == DefaultState) { @@ -1190,7 +1218,7 @@ void DialogsListWidget::loadPeerPhotos(int32 yFrom) { } } -bool DialogsListWidget::choosePeer() { +bool DialogsInner::choosePeer() { History *history = 0; MsgId msgId = ShowAtUnreadMsgId; if (_state == DefaultState) { @@ -1239,15 +1267,15 @@ bool DialogsListWidget::choosePeer() { if (chosen) { emit searchResultChosen(); } + updateSelectedRow(); sel = 0; filteredSel = peopleSel = searchedSel = hashtagSel = -1; - parentWidget()->update(); return true; } return false; } -void DialogsListWidget::saveRecentHashtags(const QString &text) { +void DialogsInner::saveRecentHashtags(const QString &text) { bool found = false; QRegularExpressionMatch m; RecentHashtagPack recent(cRecentSearchHashtags()); @@ -1275,7 +1303,7 @@ void DialogsListWidget::saveRecentHashtags(const QString &text) { } } -void DialogsListWidget::destroyData() { +void DialogsInner::destroyData() { sel = 0; contactSel = false; hashtagSel = -1; @@ -1290,7 +1318,7 @@ void DialogsListWidget::destroyData() { dialogs.clear(); } -void DialogsListWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { +void DialogsInner::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { if (_state == DefaultState) { DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id); if (i == dialogs.list.rowByPeer.constEnd()) { @@ -1374,7 +1402,7 @@ void DialogsListWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData outMsg = 0; } -void DialogsListWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { +void DialogsInner::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { if (_state == DefaultState) { DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id); if (i == dialogs.list.rowByPeer.constEnd()) { @@ -1448,27 +1476,27 @@ void DialogsListWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData outMsg = 0; } -DialogsIndexed &DialogsListWidget::contactsList() { +DialogsIndexed &DialogsInner::contactsList() { return contacts; } -DialogsIndexed &DialogsListWidget::dialogsList() { +DialogsIndexed &DialogsInner::dialogsList() { return dialogs; } -DialogsListWidget::FilteredDialogs &DialogsListWidget::filteredList() { +DialogsInner::FilteredDialogs &DialogsInner::filteredList() { return filterResults; } -DialogsListWidget::PeopleResults &DialogsListWidget::peopleList() { +DialogsInner::PeopleResults &DialogsInner::peopleList() { return peopleResults; } -DialogsListWidget::SearchResults &DialogsListWidget::searchList() { +DialogsInner::SearchResults &DialogsInner::searchList() { return searchResults; } -MsgId DialogsListWidget::lastSearchId() const { +MsgId DialogsInner::lastSearchId() const { return _lastSearchId; } @@ -1485,24 +1513,24 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent) , _newGroup(this, st::btnNewGroup) , _addContact(this, st::btnAddContact) , _cancelSearch(this, st::btnCancelSearch) -, scroll(this, st::dlgScroll) -, list(&scroll, parent) +, _scroll(this, st::dlgScroll) +, _inner(&_scroll, parent) , _searchInPeer(0) , _searchFull(false) , _peopleFull(false) { - scroll.setWidget(&list); - scroll.setFocusPolicy(Qt::NoFocus); - connect(&list, SIGNAL(mustScrollTo(int,int)), &scroll, SLOT(scrollToY(int,int))); - connect(&list, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); - connect(&list, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages())); - connect(&list, SIGNAL(searchResultChosen()), this, SLOT(onCancel())); - connect(&list, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString))); - connect(&list, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved())); - connect(&list, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer())); - connect(&scroll, SIGNAL(geometryChanged()), &list, SLOT(onParentGeometryChanged())); - connect(&scroll, SIGNAL(scrolled()), &list, SLOT(onUpdateSelected())); - connect(&scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); + _scroll.setWidget(&_inner); + _scroll.setFocusPolicy(Qt::NoFocus); + connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int))); + connect(&_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); + connect(&_inner, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages())); + connect(&_inner, SIGNAL(searchResultChosen()), this, SLOT(onCancel())); + connect(&_inner, SIGNAL(completeHashtag(QString)), this, SLOT(onCompleteHashtag(QString))); + connect(&_inner, SIGNAL(refreshHashtags()), this, SLOT(onFilterCursorMoved())); + connect(&_inner, SIGNAL(cancelSearchInPeer()), this, SLOT(onCancelSearchInPeer())); + connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged())); + connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected())); + connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); connect(&_filter, SIGNAL(cancelled()), this, SLOT(onCancel())); connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); connect(&_filter, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onFilterCursorMoved(int,int))); @@ -1519,7 +1547,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent) _searchTimer.setSingleShot(true); connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages())); - scroll.show(); + _scroll.show(); _filter.show(); _filter.move(st::dlgPaddingHor, st::dlgFilterPadding); _filter.setFocusPolicy(Qt::StrongFocus); @@ -1534,31 +1562,31 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent) void DialogsWidget::activate() { _filter.setFocus(); - list.activate(); + _inner.activate(); } void DialogsWidget::createDialog(History *history) { - list.createDialog(history); + _inner.createDialog(history); } void DialogsWidget::dlgUpdated(DialogRow *row) { - list.dlgUpdated(row); + _inner.dlgUpdated(row); } void DialogsWidget::dlgUpdated(History *row) { - list.dlgUpdated(row); + _inner.dlgUpdated(row); } void DialogsWidget::dialogsToUp() { if (_filter.getLastText().trimmed().isEmpty()) { - scroll.scrollToY(0); + _scroll.scrollToY(0); } } void DialogsWidget::animShow(const QPixmap &bgAnimCache) { _bgAnimCache = bgAnimCache; _animCache = myGrab(this, rect()); - scroll.hide(); + _scroll.hide(); _filter.hide(); _cancelSearch.hide(); _newGroup.hide(); @@ -1580,7 +1608,7 @@ bool DialogsWidget::animStep(float64 ms) { a_coord.finish(); a_alpha.finish(); _bgAnimCache = _animCache = QPixmap(); - scroll.show(); + _scroll.show(); _filter.show(); onFilterUpdate(true); activate(); @@ -1601,11 +1629,11 @@ void DialogsWidget::onCancel() { } void DialogsWidget::itemRemoved(HistoryItem *item) { - list.itemRemoved(item); + _inner.itemRemoved(item); } void DialogsWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { - list.itemReplaced(oldItem, newItem); + _inner.itemReplaced(oldItem, newItem); } void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { @@ -1673,7 +1701,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque _dialogsCount = count; if (dlgList) { unreadCountsReceived(*dlgList); - list.dialogsReceived(*dlgList); + _inner.dialogsReceived(*dlgList); onListScroll(); if (dlgList->size()) { @@ -1693,7 +1721,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque //_channelDialogsCount = count; if (dlgList) { unreadCountsReceived(*dlgList); - list.dialogsReceived(*dlgList); + _inner.dialogsReceived(*dlgList); onListScroll(); // if (dlgList->size()) { @@ -1782,14 +1810,14 @@ void DialogsWidget::onNeedSearchMessages() { } void DialogsWidget::onChooseByDrag() { - list.choosePeer(); + _inner.choosePeer(); } void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) { if ((_filter.getLastText() != query) || (inPeer && inPeer != _searchInPeer)) { if (inPeer) { _searchInPeer = inPeer; - list.searchInPeer(inPeer); + _inner.searchInPeer(inPeer); } _filter.setText(query); _filter.updatePlaceholder(); @@ -1797,7 +1825,7 @@ void DialogsWidget::searchMessages(const QString &query, PeerData *inPeer) { _searchTimer.stop(); onSearchMessages(); - list.saveRecentHashtags(query); + _inner.saveRecentHashtags(query); } } @@ -1814,7 +1842,7 @@ void DialogsWidget::onSearchMore(MsgId minMsgId) { void DialogsWidget::loadDialogs() { if (_dialogsRequest) return; if (_dialogsCount >= 0 && _dialogsOffset >= _dialogsCount) { - list.addAllSavedPeers(); + _inner.addAllSavedPeers(); cSetDialogsReceived(true); return; } @@ -1831,7 +1859,7 @@ void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &contacts) { if (contacts.type() == mtpc_contacts_contacts) { const MTPDcontacts_contacts &d(contacts.c_contacts_contacts()); App::feedUsers(d.vusers); - list.contactsReceived(d.vcontacts.c_vector().v); + _inner.contactsReceived(d.vcontacts.c_vector().v); } if (App::main()) App::main()->contactsReceived(); } @@ -1843,7 +1871,7 @@ bool DialogsWidget::contactsFailed(const RPCError &error) { } void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req) { - if (fromStart && (list.state() == DialogsListWidget::FilteredState || list.state() == DialogsListWidget::SearchedState)) { + if (fromStart && (_inner.state() == DialogsInner::FilteredState || _inner.state() == DialogsInner::SearchedState)) { SearchQueries::iterator i = _searchQueries.find(req); if (i != _searchQueries.cend()) { _searchCache[i.value()] = result; @@ -1858,7 +1886,7 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r App::feedUsers(d.vusers); App::feedChats(d.vchats); const QVector &msgs(d.vmessages.c_vector().v); - list.searchReceived(msgs, fromStart, msgs.size()); + _inner.searchReceived(msgs, fromStart, msgs.size()); if (msgs.isEmpty()) { _searchFull = true; } @@ -1869,7 +1897,7 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r App::feedUsers(d.vusers); App::feedChats(d.vchats); const QVector &msgs(d.vmessages.c_vector().v); - list.searchReceived(msgs, fromStart, d.vcount.v); + _inner.searchReceived(msgs, fromStart, d.vcount.v); if (msgs.isEmpty()) { _searchFull = true; } @@ -1889,7 +1917,7 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r App::feedUsers(d.vusers); App::feedChats(d.vchats); const QVector &msgs(d.vmessages.c_vector().v); - list.searchReceived(msgs, fromStart, d.vcount.v); + _inner.searchReceived(msgs, fromStart, d.vcount.v); if (msgs.isEmpty()) { _searchFull = true; } @@ -1903,7 +1931,7 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r void DialogsWidget::peopleReceived(const MTPcontacts_Found &result, mtpRequestId req) { QString q = _peopleQuery; - if (list.state() == DialogsListWidget::FilteredState || list.state() == DialogsListWidget::SearchedState) { + if (_inner.state() == DialogsInner::FilteredState || _inner.state() == DialogsInner::SearchedState) { PeopleQueries::iterator i = _peopleQueries.find(req); if (i != _peopleQueries.cend()) { q = i.value(); @@ -1917,7 +1945,7 @@ void DialogsWidget::peopleReceived(const MTPcontacts_Found &result, mtpRequestId case mtpc_contacts_found: { App::feedUsers(result.c_contacts_found().vusers); App::feedChats(result.c_contacts_found().vchats); - list.peopleReceived(q, result.c_contacts_found().vresults.c_vector().v); + _inner.peopleReceived(q, result.c_contacts_found().vresults.c_vector().v); } break; } @@ -1950,10 +1978,10 @@ bool DialogsWidget::addNewContact(int32 uid, bool show) { _filter.setText(QString()); _filter.updatePlaceholder(); onFilterUpdate(); - int32 to = list.addNewContact(uid, true); + int32 to = _inner.addNewContact(uid, true); if (to < -1 || !show) return false; - list.refresh(); - if (to >= 0) scroll.scrollToY(to); + _inner.refresh(); + if (to >= 0) _scroll.scrollToY(to); return true; } @@ -1968,7 +1996,7 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) { if (_dragForward) { e->setDropAction(Qt::CopyAction); e->accept(); - updateDragInScroll(scroll.geometry().contains(e->pos())); + updateDragInScroll(_scroll.geometry().contains(e->pos())); } else if (App::main() && App::main()->getDragState(e->mimeData()) != DragStateNone) { e->setDropAction(Qt::CopyAction); e->accept(); @@ -1977,13 +2005,13 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) { } void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) { - if (scroll.geometry().contains(e->pos())) { + if (_scroll.geometry().contains(e->pos())) { if (_dragForward) { updateDragInScroll(true); } else { _chooseByDragTimer.start(ChoosePeerByDragTimeout); } - PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos())); + PeerData *p = _inner.updateFromParentDrag(mapToGlobal(e->pos())); if (p) { e->setDropAction(Qt::CopyAction); } else { @@ -1991,7 +2019,7 @@ void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) { } } else { if (_dragForward) updateDragInScroll(false); - list.leaveEvent(0); + _inner.leaveEvent(0); e->setDropAction(Qt::IgnoreAction); } e->accept(); @@ -2003,7 +2031,7 @@ void DialogsWidget::dragLeaveEvent(QDragLeaveEvent *e) { } else { _chooseByDragTimer.stop(); } - list.leaveEvent(0); + _inner.leaveEvent(0); e->accept(); } @@ -2020,8 +2048,8 @@ void DialogsWidget::updateDragInScroll(bool inScroll) { void DialogsWidget::dropEvent(QDropEvent *e) { _chooseByDragTimer.stop(); - if (scroll.geometry().contains(e->pos())) { - PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos())); + if (_scroll.geometry().contains(e->pos())) { + PeerData *p = _inner.updateFromParentDrag(mapToGlobal(e->pos())); if (p) { e->acceptProposedAction(); App::main()->onFilesOrForwardDrop(p->id, e->mimeData()); @@ -2032,12 +2060,12 @@ void DialogsWidget::dropEvent(QDropEvent *e) { void DialogsWidget::onListScroll() { // if (!App::self()) return; - list.loadPeerPhotos(scroll.scrollTop()); - if (list.state() == DialogsListWidget::SearchedState) { - if (scroll.scrollTop() > (list.searchList().size() + list.filteredList().size() + list.peopleList().size()) * st::dlgHeight - PreloadHeightsCount * scroll.height()) { - onSearchMore(list.lastSearchId()); + _inner.loadPeerPhotos(_scroll.scrollTop()); + if (_inner.state() == DialogsInner::SearchedState) { + if (_scroll.scrollTop() > (_inner.searchList().size() + _inner.filteredList().size() + _inner.peopleList().size()) * st::dlgHeight - PreloadHeightsCount * _scroll.height()) { + onSearchMore(_inner.lastSearchId()); } - } else if (scroll.scrollTop() > list.dialogsList().list.count * st::dlgHeight - PreloadHeightsCount * scroll.height()) { + } else if (_scroll.scrollTop() > _inner.dialogsList().list.count * st::dlgHeight - PreloadHeightsCount * _scroll.height()) { loadDialogs(); } } @@ -2046,7 +2074,7 @@ void DialogsWidget::onFilterUpdate(bool force) { if (animating() && !force) return; QString filterText = _filter.getLastText(); - list.onFilterUpdate(filterText); + _inner.onFilterUpdate(filterText); if (filterText.isEmpty()) { _searchCache.clear(); _searchQueries.clear(); @@ -2067,9 +2095,9 @@ void DialogsWidget::onFilterUpdate(bool force) { void DialogsWidget::searchInPeer(PeerData *peer) { onCancelSearch(); _searchInPeer = peer; - list.searchInPeer(peer); + _inner.searchInPeer(peer); onFilterUpdate(true); - list.onFilterUpdate(_filter.getLastText(), true); + _inner.onFilterUpdate(_filter.getLastText(), true); } void DialogsWidget::onFilterCursorMoved(int from, int to) { @@ -2085,7 +2113,7 @@ void DialogsWidget::onFilterCursorMoved(int from, int to) { } if (!t.at(start).isLetterOrNumber() && t.at(start) != '_') break; } - list.onHashtagFilterUpdate(r); + _inner.onHashtagFilterUpdate(r); } void DialogsWidget::onCompleteHashtag(QString tag) { @@ -2121,14 +2149,13 @@ void DialogsWidget::resizeEvent(QResizeEvent *e) { _newGroup.move(w - _newGroup.width() - st::dlgPaddingHor, _filter.y()); _addContact.move(w - _addContact.width() - st::dlgPaddingHor, _filter.y()); _cancelSearch.move(w - _cancelSearch.width() - st::dlgPaddingHor, _filter.y()); - scroll.move(0, _filter.height() + 2 * st::dlgFilterPadding); + _scroll.move(0, _filter.height() + 2 * st::dlgFilterPadding); int32 addToY = App::main() ? App::main()->contentScrollAddToY() : 0; - int32 newScrollY = scroll.scrollTop() + addToY; - scroll.resize(w, height() - _filter.y() - _filter.height() - st::dlgFilterPadding - st::dlgPaddingVer); - list.resize(w, list.height()); + int32 newScrollY = _scroll.scrollTop() + addToY; + _scroll.resize(w, height() - _filter.y() - _filter.height() - st::dlgFilterPadding - st::dlgPaddingVer); if (addToY) { - scroll.scrollToY(newScrollY); + _scroll.scrollToY(newScrollY); } else { onListScroll(); } @@ -2138,26 +2165,26 @@ void DialogsWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { e->ignore(); } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { - if (!list.choosePeer()) { - if (list.state() == DialogsListWidget::DefaultState || list.state() == DialogsListWidget::SearchedState || (list.state() == DialogsListWidget::FilteredState && list.hasFilteredResults())) { - list.selectSkip(1); - list.choosePeer(); + if (!_inner.choosePeer()) { + if (_inner.state() == DialogsInner::DefaultState || _inner.state() == DialogsInner::SearchedState || (_inner.state() == DialogsInner::FilteredState && _inner.hasFilteredResults())) { + _inner.selectSkip(1); + _inner.choosePeer(); } else { onSearchMessages(); } } } else if (e->key() == Qt::Key_Down) { - list.setMouseSel(false); - list.selectSkip(1); + _inner.setMouseSel(false); + _inner.selectSkip(1); } else if (e->key() == Qt::Key_Up) { - list.setMouseSel(false); - list.selectSkip(-1); + _inner.setMouseSel(false); + _inner.selectSkip(-1); } else if (e->key() == Qt::Key_PageDown) { - list.setMouseSel(false); - list.selectSkipPage(scroll.height(), 1); + _inner.setMouseSel(false); + _inner.selectSkipPage(_scroll.height(), 1); } else if (e->key() == Qt::Key_PageUp) { - list.setMouseSel(false); - list.selectSkipPage(scroll.height(), -1); + _inner.setMouseSel(false); + _inner.selectSkipPage(_scroll.height(), -1); } else { e->ignore(); } @@ -2176,6 +2203,14 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { p.drawPixmap(a_coord.current(), 0, _animCache); return; } + QRect above(0, 0, width() - (cWideMode() ? st::dlgShadow : 0), _scroll.y()); + if (above.intersects(r)) { + p.fillRect(above.intersected(r), st::white->b); + } + QRect below(0, _scroll.y() + qMin(_scroll.height(), _inner.height()), width() - (cWideMode() ? st::dlgShadow : 0), height()); + if (below.intersects(r)) { + p.fillRect(below.intersected(r), st::white->b); + } if (cWideMode() && _drawShadow) { QRect sh(width() - st::dlgShadow, 0, st::dlgShadow, height()); if (r.intersects(sh)) { @@ -2185,41 +2220,41 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { } void DialogsWidget::destroyData() { - list.destroyData(); + _inner.destroyData(); } void DialogsWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { - return list.peerBefore(inPeer, inMsg, outPeer, outMsg); + return _inner.peerBefore(inPeer, inMsg, outPeer, outMsg); } void DialogsWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const { - return list.peerAfter(inPeer, inMsg, outPeer, outMsg); + return _inner.peerAfter(inPeer, inMsg, outPeer, outMsg); } void DialogsWidget::scrollToPeer(const PeerId &peer, MsgId msgId) { - list.scrollToPeer(peer, msgId); + _inner.scrollToPeer(peer, msgId); } void DialogsWidget::removePeer(PeerData *peer) { _filter.setText(QString()); _filter.updatePlaceholder(); onFilterUpdate(); - list.removePeer(peer); + _inner.removePeer(peer); } void DialogsWidget::removeContact(UserData *user) { _filter.setText(QString()); _filter.updatePlaceholder(); onFilterUpdate(); - list.removeContact(user); + _inner.removeContact(user); } DialogsIndexed &DialogsWidget::contactsList() { - return list.contactsList(); + return _inner.contactsList(); } DialogsIndexed &DialogsWidget::dialogsList() { - return list.dialogsList(); + return _inner.dialogsList(); } void DialogsWidget::onAddContact() { @@ -2241,10 +2276,10 @@ bool DialogsWidget::onCancelSearch() { App::main()->showPeerHistory(_searchInPeer->id, ShowAtUnreadMsgId); } _searchInPeer = 0; - list.searchInPeer(0); + _inner.searchInPeer(0); clearing = true; } - list.clearFilter(); + _inner.clearFilter(); _filter.clear(); _filter.updatePlaceholder(); onFilterUpdate(); @@ -2261,9 +2296,9 @@ void DialogsWidget::onCancelSearchInPeer() { App::main()->showPeerHistory(_searchInPeer->id, ShowAtUnreadMsgId); } _searchInPeer = 0; - list.searchInPeer(0); + _inner.searchInPeer(0); } - list.clearFilter(); + _inner.clearFilter(); _filter.clear(); _filter.updatePlaceholder(); onFilterUpdate(); @@ -2273,9 +2308,9 @@ void DialogsWidget::onCancelSearchInPeer() { } void DialogsWidget::onDialogMoved(int movedFrom, int movedTo) { - int32 st = scroll.scrollTop(); + int32 st = _scroll.scrollTop(); if (st > movedTo && st < movedFrom) { - scroll.scrollToY(st + st::dlgHeight); + _scroll.scrollToY(st + st::dlgHeight); } } diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 7ceb5b00e..5f55958af 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -19,12 +19,12 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org class MainWidget; -class DialogsListWidget : public QWidget { +class DialogsInner : public SplittedWidget { Q_OBJECT public: - DialogsListWidget(QWidget *parent, MainWidget *main); + DialogsInner(QWidget *parent, MainWidget *main); void dialogsReceived(const QVector &dialogs); void addSavedPeersAfter(const QDateTime &date); @@ -42,15 +42,14 @@ public: int32 peopleOffset() const; int32 searchedOffset() const; - void paintEvent(QPaintEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); void resizeEvent(QResizeEvent *e); void enterEvent(QEvent *e); void leaveEvent(QEvent *e); - void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel) const; - void searchInPeerPaint(Painter &p, int32 w) const; + void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const; + void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const; void selectSkip(int32 direction); void selectSkipPage(int32 pixels, int32 direction); @@ -106,7 +105,7 @@ public: PeerData *updateFromParentDrag(QPoint globalPos); - ~DialogsListWidget(); + ~DialogsInner(); public slots: @@ -126,9 +125,14 @@ signals: void completeHashtag(QString tag); void refreshHashtags(); +protected: + + void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther); + private: void clearSearchResults(bool clearPeople = true); + void updateSelectedRow(); DialogsIndexed dialogs; DialogsIndexed contactsNoDialogs; @@ -265,8 +269,8 @@ private: FlatInput _filter; IconedButton _newGroup, _addContact, _cancelSearch; - ScrollArea scroll; - DialogsListWidget list; + ScrollArea _scroll; + DialogsInner _inner; QPixmap _animCache, _bgAnimCache; anim::ivalue a_coord, a_bgCoord; diff --git a/Telegram/SourceFiles/gui/scrollarea.cpp b/Telegram/SourceFiles/gui/scrollarea.cpp index cc721bf81..cfa8a071b 100644 --- a/Telegram/SourceFiles/gui/scrollarea.cpp +++ b/Telegram/SourceFiles/gui/scrollarea.cpp @@ -35,8 +35,7 @@ void ScrollShadow::changeVisibility(bool shown) { setVisible(shown); } -ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent), - _area(parent), _st(st), _vertical(vert), +ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent), _st(st), _vertical(vert), _over(false), _overbar(false), _moving(false), _topSh(false), _bottomSh(false), _connected(vert ? parent->verticalScrollBar() : parent->horizontalScrollBar()), _scrollMax(_connected->maximum()), _hideIn(-1), @@ -54,11 +53,11 @@ ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) } void ScrollBar::recountSize() { - setGeometry(_vertical ? QRect(rtl() ? 0 : (_area->width() - _st->width), _st->deltat, _st->width, _area->height() - _st->deltat - _st->deltab) : QRect(_st->deltat, _area->height() - _st->width, _area->width() - _st->deltat - _st->deltab, _st->width)); + setGeometry(_vertical ? QRect(rtl() ? 0 : (area()->width() - _st->width), _st->deltat, _st->width, area()->height() - _st->deltat - _st->deltab) : QRect(_st->deltat, area()->height() - _st->width, area()->width() - _st->deltat - _st->deltab, _st->width)); } void ScrollBar::onValueChanged() { - _area->onScrolled(); + area()->onScrolled(); updateBar(); } @@ -67,11 +66,11 @@ void ScrollBar::updateBar(bool force) { if (_connected->maximum() != _scrollMax) { int32 oldMax = _scrollMax, newMax = _connected->maximum(); _scrollMax = newMax; - _area->rangeChanged(oldMax, newMax, _vertical); + area()->rangeChanged(oldMax, newMax, _vertical); } if (_vertical) { - int sh = _area->scrollHeight(), rh = height(), h = sh ? int32((rh * int64(_area->height())) / sh) : 0; - if (h >= rh || !_area->scrollTopMax() || rh < _st->minHeight) { + int sh = area()->scrollHeight(), rh = height(), h = sh ? int32((rh * int64(area()->height())) / sh) : 0; + if (h >= rh || !area()->scrollTopMax() || rh < _st->minHeight) { if (!isHidden()) hide(); bool newTopSh = (_st->topsh < 0), newBottomSh = (_st->bottomsh < 0); if (newTopSh != _topSh || force) emit topShadowVisibility(_topSh = newTopSh); @@ -80,29 +79,29 @@ void ScrollBar::updateBar(bool force) { } if (h <= _st->minHeight) h = _st->minHeight; - int stm = _area->scrollTopMax(), y = stm ? int32(((rh - h) * int64(_area->scrollTop())) / stm) : 0; + int stm = area()->scrollTopMax(), y = stm ? int32(((rh - h) * int64(area()->scrollTop())) / stm) : 0; if (y > rh - h) y = rh - h; newBar = QRect(_st->deltax, y, width() - 2 * _st->deltax, h); } else { - int sw = _area->scrollWidth(), rw = width(), w = sw ? int32((rw * int64(_area->width())) / sw) : 0; - if (w >= rw || !_area->scrollLeftMax() || rw < _st->minHeight) { + int sw = area()->scrollWidth(), rw = width(), w = sw ? int32((rw * int64(area()->width())) / sw) : 0; + if (w >= rw || !area()->scrollLeftMax() || rw < _st->minHeight) { if (!isHidden()) hide(); return; } if (w <= _st->minHeight) w = _st->minHeight; - int slm = _area->scrollLeftMax(), x = slm ? int32(((rw - w) * int64(_area->scrollLeft())) / slm) : 0; + int slm = area()->scrollLeftMax(), x = slm ? int32(((rw - w) * int64(area()->scrollLeft())) / slm) : 0; if (x > rw - w) x = rw - w; newBar = QRect(x, _st->deltax, w, height() - 2 * _st->deltax); } if (newBar != _bar) { _bar = newBar; - update();// parentWidget()->update(geometry()); + update(); } if (_vertical) { - bool newTopSh = (_st->topsh < 0) || (_area->scrollTop() > _st->topsh), newBottomSh = (_st->bottomsh < 0) || (_area->scrollTop() < _area->scrollTopMax() - _st->bottomsh); + bool newTopSh = (_st->topsh < 0) || (area()->scrollTop() > _st->topsh), newBottomSh = (_st->bottomsh < 0) || (area()->scrollTop() < area()->scrollTopMax() - _st->bottomsh); if (newTopSh != _topSh || force) emit topShadowVisibility(_topSh = newTopSh); if (newBottomSh != _bottomSh || force) emit bottomShadowVisibility(_bottomSh = newBottomSh); } @@ -116,6 +115,10 @@ void ScrollBar::onHideTimer() { anim::start(this); } +ScrollArea *ScrollBar::area() { + return static_cast(parentWidget()); +} + void ScrollBar::paintEvent(QPaintEvent *e) { if (!_bar.width() && !_bar.height()) { hide(); @@ -200,10 +203,10 @@ void ScrollBar::mouseMoveEvent(QMouseEvent *e) { } } if (_moving) { - int delta = 0, barDelta = _vertical ? (_area->height() - _bar.height()) : (_area->width() - _bar.width()); + int delta = 0, barDelta = _vertical ? (area()->height() - _bar.height()) : (area()->width() - _bar.width()); if (barDelta > 0) { QPoint d = (e->globalPos() - _dragStart); - delta = int32((_vertical ? (d.y() * int64(_area->scrollTopMax())) : (d.x() * int64(_area->scrollLeftMax()))) / barDelta); + delta = int32((_vertical ? (d.y() * int64(area()->scrollTopMax())) : (d.x() * int64(area()->scrollLeftMax()))) / barDelta); } _connected->setValue(_startFrom + delta); } @@ -220,7 +223,7 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) { int32 val = _vertical ? e->pos().y() : e->pos().x(), div = _vertical ? height() : width(); val = (val <= _st->deltat) ? 0 : (val - _st->deltat); div = (div <= _st->deltat + _st->deltab) ? 1 : (div - _st->deltat - _st->deltab); - _startFrom = _vertical ? int32((val * int64(_area->scrollTopMax())) / div) : ((val * int64(_area->scrollLeftMax())) / div); + _startFrom = _vertical ? int32((val * int64(area()->scrollTopMax())) / div) : ((val * int64(area()->scrollLeftMax())) / div); _connected->setValue(_startFrom); if (!_overbar) { _overbar = true; @@ -229,7 +232,7 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) { anim::start(this); } } - emit _area->scrollStarted(); + emit area()->scrollStarted(); } void ScrollBar::mouseReleaseEvent(QMouseEvent *e) { @@ -252,7 +255,7 @@ void ScrollBar::mouseReleaseEvent(QMouseEvent *e) { } } if (a) anim::start(this); - emit _area->scrollFinished(); + emit area()->scrollFinished(); } if (!_over) { setMouseTracking(false); @@ -263,12 +266,53 @@ void ScrollBar::resizeEvent(QResizeEvent *e) { updateBar(); } +void SplittedWidget::paintEvent(QPaintEvent *e) { + Painter p(this); + if (rtl()) { + p.translate(-otherWidth(), 0); + paintRegion(p, e->region().translated(otherWidth(), 0), false); + } else { + paintRegion(p, e->region(), false); + } +} + +void SplittedWidget::update(const QRect &r) { + if (rtl()) { + TWidget::update(r.translated(-otherWidth(), 0).intersected(rect())); + emit updateOther(r); + } else { + TWidget::update(r.intersected(rect())); + emit updateOther(r.translated(-width(), 0)); + } +} + +void SplittedWidget::update(const QRegion &r) { + if (rtl()) { + TWidget::update(r.translated(-otherWidth(), 0).intersected(rect())); + emit updateOther(r); + } else { + TWidget::update(r.intersected(rect())); + emit updateOther(r.translated(-width(), 0)); + } +} + +void SplittedWidgetOther::paintEvent(QPaintEvent *e) { + Painter p(this); + SplittedWidget *s = static_cast(static_cast(parentWidget())->widget()); + if (rtl()) { + s->paintRegion(p, e->region(), true); + } else { + p.translate(-s->width(), 0); + s->paintRegion(p, e->region().translated(s->width(), 0), true); + } +} + ScrollArea::ScrollArea(QWidget *parent, const style::flatScroll &st, bool handleTouch) : QScrollArea(parent), _disabled(false), _st(st), hor(this, false, &_st), vert(this, true, &_st), topSh(this, &_st), bottomSh(this, &_st), _touchEnabled(handleTouch), _touchScroll(false), _touchPress(false), _touchRightButton(false), _touchScrollState(TouchScrollManual), _touchPrevPosValid(false), _touchWaitingAcceleration(false), -_touchSpeedTime(0), _touchAccelerationTime(0), _touchTime(0), _widgetAcceptsTouch(false) { +_touchSpeedTime(0), _touchAccelerationTime(0), _touchTime(0), _widgetAcceptsTouch(false), _other(0) { setLayoutDirection(cLangDir()); connect(&vert, SIGNAL(topShadowVisibility(bool)), &topSh, SLOT(changeVisibility(bool))); @@ -581,6 +625,12 @@ void ScrollArea::resizeEvent(QResizeEvent *e) { vert.recountSize(); topSh.setGeometry(QRect(0, 0, width(), qAbs(_st.topsh))); bottomSh.setGeometry(QRect(0, height() - qAbs(_st.bottomsh), width(), qAbs(_st.bottomsh))); + if (SplittedWidget *w = qobject_cast(widget())) { + w->resize(width() - w->otherWidth(), w->height()); + if (!rtl()) { + _other->move(w->width(), w->y()); + } + } emit geometryChanged(); } @@ -644,10 +694,22 @@ void ScrollArea::scrollToY(int toTop, int toBottom) { } void ScrollArea::setWidget(QWidget *w) { + SplittedWidget *splitted = qobject_cast(w); if (widget() && _touchEnabled) { widget()->removeEventFilter(this); if (!_widgetAcceptsTouch) widget()->setAttribute(Qt::WA_AcceptTouchEvents, false); } + if (_other && !splitted) { + delete _other; + _other = 0; + disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll())); + } else if (!_other && splitted) { + _other = new SplittedWidgetOther(this); + _other->setAttribute(Qt::WA_OpaquePaintEvent); + connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll())); + hor.raise(); + vert.raise(); + } QScrollArea::setWidget(w); if (w) { w->setAutoFillBackground(false); @@ -656,9 +718,43 @@ void ScrollArea::setWidget(QWidget *w) { _widgetAcceptsTouch = w->testAttribute(Qt::WA_AcceptTouchEvents); w->setAttribute(Qt::WA_AcceptTouchEvents); } + if (splitted) { + splitted->setOtherWidth(vert.width()); + w->resize(width() - splitted->otherWidth(), w->height()); + connect(splitted, SIGNAL(resizeOther()), this, SLOT(onResizeOther())); + connect(splitted, SIGNAL(updateOther(const QRect&)), this, SLOT(onUpdateOther(const QRect&))); + connect(splitted, SIGNAL(updateOther(const QRegion&)), this, SLOT(onUpdateOther(const QRegion&))); + onResizeOther(); + splitted->update(); + } } } +QWidget *ScrollArea::takeWidget() { + if (_other) { + delete _other; + _other = 0; + disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScroll())); + } + return QScrollArea::takeWidget(); +} + +void ScrollArea::onResizeOther() { + _other->resize(_other->width(), widget()->height()); +} + +void ScrollArea::onUpdateOther(const QRect &r) { + _other->update(r.intersected(_other->rect())); +} + +void ScrollArea::onUpdateOther(const QRegion &r) { + _other->update(r.intersected(_other->rect())); +} + +void ScrollArea::onVerticalScroll() { + _other->move(_other->x(), widget()->y()); +} + void ScrollArea::rangeChanged(int oldMax, int newMax, bool vertical) { } diff --git a/Telegram/SourceFiles/gui/scrollarea.h b/Telegram/SourceFiles/gui/scrollarea.h index 208055057..9d1999b27 100644 --- a/Telegram/SourceFiles/gui/scrollarea.h +++ b/Telegram/SourceFiles/gui/scrollarea.h @@ -81,7 +81,7 @@ signals: private: - ScrollArea *_area; + ScrollArea *area(); const style::flatScroll *_st; bool _vertical; @@ -100,6 +100,62 @@ private: QRect _bar; }; +class SplittedWidget : public TWidget { + Q_OBJECT + +public: + + SplittedWidget(QWidget *parent) : TWidget(parent), _otherWidth(0) { + setAttribute(Qt::WA_OpaquePaintEvent); + } + void paintEvent(QPaintEvent *e); // paintEvent done through paintRegion + void setHeight(int32 newHeight) { + resize(width(), newHeight); + emit resizeOther(); + } + void update(int x, int y, int w, int h) { + update(QRect(x, y, w, h)); + } + void update(const QRect&); + void update(const QRegion&); + +public slots: + + void update() { + update(0, 0, fullWidth(), height()); + } + +signals: + + void resizeOther(); + void updateOther(const QRect&); + void updateOther(const QRegion&); + +protected: + + int32 otherWidth() const { + return _otherWidth; + } + int32 fullWidth() const { + return width() + otherWidth(); + } + virtual void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) = 0; + +private: + + int32 _otherWidth; + void setOtherWidth(int32 otherWidth) { + _otherWidth = otherWidth; + } + void resize(int32 w, int32 h) { + TWidget::resize(w, h); + } + friend class ScrollArea; + friend class SplittedWidgetOther; + +}; + +class SplittedWidgetOther; class ScrollArea : public QScrollArea { Q_OBJECT @@ -127,6 +183,7 @@ public: int scrollTop() const; void setWidget(QWidget *widget); + QWidget *takeWidget(); void rangeChanged(int oldMax, int newMax, bool vertical); @@ -145,6 +202,11 @@ public slots: void onTouchTimer(); void onTouchScrollTimer(); + void onResizeOther(); + void onUpdateOther(const QRect&); + void onUpdateOther(const QRegion&); + void onVerticalScroll(); + signals: void scrolled(); @@ -192,4 +254,14 @@ private: bool _widgetAcceptsTouch; + friend class SplittedWidgetOther; + SplittedWidgetOther *_other; + +}; + +class SplittedWidgetOther : public TWidget { +public: + SplittedWidgetOther(ScrollArea *parent) : TWidget(parent) { + } + void paintEvent(QPaintEvent *e); }; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 96e9dd138..ab6c4b065 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -149,10 +149,11 @@ void stopGif() { animated.stop(); } -void DialogRow::paint(Painter &p, int32 w, bool act, bool sel) const { +void DialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const { QRect fullRect(0, 0, w, st::dlgHeight); p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b); - + if (onlyBackground) return; + p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize)); int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; @@ -240,10 +241,11 @@ void DialogRow::paint(Painter &p, int32 w, bool act, bool sel) const { history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } -void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel) const { +void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const { QRect fullRect(0, 0, w, st::dlgHeight); p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b); - + if (onlyBackground) return; + History *history = _item->history(); p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize)); diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index cca5e9eea..3a103340b 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -77,7 +77,7 @@ struct DialogRow { DialogRow(History *history = 0, DialogRow *prev = 0, DialogRow *next = 0, int32 pos = 0) : prev(prev), next(next), history(history), pos(pos), attached(0) { } - void paint(Painter &p, int32 w, bool act, bool sel) const; + void paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const; DialogRow *prev, *next; History *history; @@ -89,7 +89,7 @@ struct FakeDialogRow { FakeDialogRow(HistoryItem *item) : _item(item), _cacheFor(0), _cache(st::dlgRichMinWidth) { } - void paint(Painter &p, int32 w, bool act, bool sel) const; + void paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const; HistoryItem *_item; mutable const HistoryItem *_cacheFor; @@ -447,13 +447,13 @@ struct DialogsList { } } - void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel) const { + void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground) const { adjustCurrent(hFrom, st::dlgHeight); DialogRow *drawFrom = current; p.translate(0, drawFrom->pos * st::dlgHeight); while (drawFrom != end && drawFrom->pos * st::dlgHeight < hTo) { - drawFrom->paint(p, w, (drawFrom->history->peer == act), (drawFrom->history->peer == sel)); + drawFrom->paint(p, w, (drawFrom->history->peer == act), (drawFrom->history->peer == sel), onlyBackground); drawFrom = drawFrom->next; p.translate(0, st::dlgHeight); } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 01d424df0..7b2543148 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -34,7 +34,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org // flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html -HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : QWidget(0) +HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : QWidget(0) , hist(history) , ySkip(0) , botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : 0) @@ -82,20 +82,20 @@ HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, Histo setMouseTracking(true); } -void HistoryList::messagesReceived(const QVector &messages, const QVector *collapsed) { +void HistoryInner::messagesReceived(const QVector &messages, const QVector *collapsed) { hist->addOlderSlice(messages, collapsed); } -void HistoryList::messagesReceivedDown(const QVector &messages, const QVector *collapsed) { +void HistoryInner::messagesReceivedDown(const QVector &messages, const QVector *collapsed) { hist->addNewerSlice(messages, collapsed); } -void HistoryList::updateMsg(const HistoryItem *msg) { +void HistoryInner::updateMsg(const HistoryItem *msg) { if (!msg || msg->detached() || !hist || hist != msg->history()) return; update(0, ySkip + msg->block()->y + msg->y, width(), msg->height()); } -void HistoryList::paintEvent(QPaintEvent *e) { +void HistoryInner::paintEvent(QPaintEvent *e) { if (!App::main()) return; QRect r(e->rect()); @@ -174,7 +174,7 @@ void HistoryList::paintEvent(QPaintEvent *e) { } } -bool HistoryList::event(QEvent *e) { +bool HistoryInner::event(QEvent *e) { if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchUpdate || e->type() == QEvent::TouchEnd || e->type() == QEvent::TouchCancel) { QTouchEvent *ev = static_cast(e); if (ev->device()->type() == QTouchDevice::TouchScreen) { @@ -185,7 +185,7 @@ bool HistoryList::event(QEvent *e) { return QWidget::event(e); } -void HistoryList::onTouchScrollTimer() { +void HistoryInner::onTouchScrollTimer() { uint64 nowTime = getms(); if (_touchScrollState == TouchScrollAcceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) { _touchScrollState = TouchScrollManual; @@ -206,7 +206,7 @@ void HistoryList::onTouchScrollTimer() { } } -void HistoryList::touchUpdateSpeed() { +void HistoryInner::touchUpdateSpeed() { const uint64 nowTime = getms(); if (_touchPrevPosValid) { const int elapsed = nowTime - _touchSpeedTime; @@ -245,19 +245,19 @@ void HistoryList::touchUpdateSpeed() { _touchPrevPos = _touchPos; } -void HistoryList::touchResetSpeed() { +void HistoryInner::touchResetSpeed() { _touchSpeed = QPoint(); _touchPrevPosValid = false; } -void HistoryList::touchDeaccelerate(int32 elapsed) { +void HistoryInner::touchDeaccelerate(int32 elapsed) { int32 x = _touchSpeed.x(); int32 y = _touchSpeed.y(); _touchSpeed.setX((x == 0) ? x : (x > 0) ? qMax(0, x - elapsed) : qMin(0, x + elapsed)); _touchSpeed.setY((y == 0) ? y : (y > 0) ? qMax(0, y - elapsed) : qMin(0, y + elapsed)); } -void HistoryList::touchEvent(QTouchEvent *e) { +void HistoryInner::touchEvent(QTouchEvent *e) { const Qt::TouchPointStates &states(e->touchPointStates()); if (e->type() == QEvent::TouchCancel) { // cancel if (!_touchInProgress) return; @@ -353,31 +353,31 @@ void HistoryList::touchEvent(QTouchEvent *e) { } } -void HistoryList::mouseMoveEvent(QMouseEvent *e) { +void HistoryInner::mouseMoveEvent(QMouseEvent *e) { if (!(e->buttons() & (Qt::LeftButton | Qt::MiddleButton)) && (textlnkDown() || _dragAction != NoDrag)) { mouseReleaseEvent(e); } dragActionUpdate(e->globalPos()); } -void HistoryList::dragActionUpdate(const QPoint &screenPos) { +void HistoryInner::dragActionUpdate(const QPoint &screenPos) { _dragPos = screenPos; onUpdateSelected(); } -void HistoryList::touchScrollUpdated(const QPoint &screenPos) { +void HistoryInner::touchScrollUpdated(const QPoint &screenPos) { _touchPos = screenPos; historyWidget->touchScroll(_touchPos - _touchPrevPos); touchUpdateSpeed(); } -QPoint HistoryList::mapMouseToItem(QPoint p, HistoryItem *item) { +QPoint HistoryInner::mapMouseToItem(QPoint p, HistoryItem *item) { if (!item || item->detached()) return QPoint(0, 0); p.setY(p.y() - (height() - hist->height - st::historyPadding) - item->block()->y - item->y); return p; } -void HistoryList::mousePressEvent(QMouseEvent *e) { +void HistoryInner::mousePressEvent(QMouseEvent *e) { if (_menu) { e->accept(); return; // ignore mouse press, that was hiding context menu @@ -385,7 +385,7 @@ void HistoryList::mousePressEvent(QMouseEvent *e) { dragActionStart(e->globalPos(), e->button()); } -void HistoryList::dragActionStart(const QPoint &screenPos, Qt::MouseButton button) { +void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton button) { dragActionUpdate(screenPos); if (button != Qt::LeftButton) return; @@ -492,7 +492,7 @@ void HistoryList::dragActionStart(const QPoint &screenPos, Qt::MouseButton butto } } -void HistoryList::dragActionCancel() { +void HistoryInner::dragActionCancel() { _dragItem = 0; _dragAction = NoDrag; _dragStartPos = QPoint(0, 0); @@ -501,7 +501,7 @@ void HistoryList::dragActionCancel() { historyWidget->noSelectingScroll(); } -void HistoryList::onDragExec() { +void HistoryInner::onDragExec() { if (_dragAction != Dragging) return; bool uponSelected = false; @@ -589,7 +589,7 @@ void HistoryList::onDragExec() { } } -void HistoryList::itemRemoved(HistoryItem *item) { +void HistoryInner::itemRemoved(HistoryItem *item) { SelectedItems::iterator i = _selected.find(item); if (i != _selected.cend()) { _selected.erase(i); @@ -609,7 +609,7 @@ void HistoryList::itemRemoved(HistoryItem *item) { updateDragSelection(_dragSelFrom, _dragSelTo, _dragSelecting, true); } -void HistoryList::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { +void HistoryInner::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { if (_dragItem == oldItem) _dragItem = newItem; SelectedItems::iterator i = _selected.find(oldItem); @@ -623,7 +623,7 @@ void HistoryList::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { if (_dragSelTo == oldItem) _dragSelTo = newItem; } -void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton button) { +void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton button) { TextLinkPtr needClick; dragActionUpdate(screenPos); @@ -712,14 +712,14 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt historyWidget->updateTopBarSelection(); } -void HistoryList::mouseReleaseEvent(QMouseEvent *e) { +void HistoryInner::mouseReleaseEvent(QMouseEvent *e) { dragActionFinish(e->globalPos(), e->button()); if (!rect().contains(e->pos())) { leaveEvent(e); } } -void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) { +void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) { if (!hist) return; if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) { @@ -748,7 +748,7 @@ void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) { } } -void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { +void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (_menu) { _menu->deleteLater(); _menu = 0; @@ -929,34 +929,34 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } -void HistoryList::onMenuDestroy(QObject *obj) { +void HistoryInner::onMenuDestroy(QObject *obj) { if (_menu == obj) { _menu = 0; } } -void HistoryList::copySelectedText() { +void HistoryInner::copySelectedText() { QString sel = getSelectedText(); if (!sel.isEmpty()) { QApplication::clipboard()->setText(sel); } } -void HistoryList::openContextUrl() { +void HistoryInner::openContextUrl() { HistoryItem *was = App::hoveredLinkItem(); App::hoveredLinkItem(App::contextItem()); _contextMenuLnk->onClick(Qt::LeftButton); App::hoveredLinkItem(was); } -void HistoryList::copyContextUrl() { +void HistoryInner::copyContextUrl() { QString enc = _contextMenuLnk->encoded(); if (!enc.isEmpty()) { QApplication::clipboard()->setText(enc); } } -void HistoryList::saveContextImage() { +void HistoryInner::saveContextImage() { PhotoLink *lnk = dynamic_cast(_contextMenuLnk.data()); if (!lnk) return; @@ -971,7 +971,7 @@ void HistoryList::saveContextImage() { } } -void HistoryList::copyContextImage() { +void HistoryInner::copyContextImage() { PhotoLink *lnk = dynamic_cast(_contextMenuLnk.data()); if (!lnk) return; @@ -981,7 +981,7 @@ void HistoryList::copyContextImage() { QApplication::clipboard()->setPixmap(photo->full->pix()); } -void HistoryList::cancelContextDownload() { +void HistoryInner::cancelContextDownload() { VideoLink *lnkVideo = dynamic_cast(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); @@ -989,7 +989,7 @@ void HistoryList::cancelContextDownload() { if (loader) loader->cancel(); } -void HistoryList::showContextInFolder() { +void HistoryInner::showContextInFolder() { VideoLink *lnkVideo = dynamic_cast(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); @@ -997,7 +997,7 @@ void HistoryList::showContextInFolder() { if (!already.isEmpty()) psShowInFolder(already); } -void HistoryList::openContextFile() { +void HistoryInner::openContextFile() { VideoLink *lnkVideo = dynamic_cast(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); @@ -1006,7 +1006,7 @@ void HistoryList::openContextFile() { if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton); } -void HistoryList::saveContextFile() { +void HistoryInner::saveContextFile() { VideoLink *lnkVideo = dynamic_cast(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_contextMenuLnk.data()); @@ -1015,7 +1015,7 @@ void HistoryList::saveContextFile() { if (lnkDocument) DocumentSaveLink::doSave(lnkDocument->document(), true); } -void HistoryList::copyContextText() { +void HistoryInner::copyContextText() { HistoryItem *item = App::contextItem(); if (item && item->type() != HistoryItemMsg) { item = 0; @@ -1029,11 +1029,11 @@ void HistoryList::copyContextText() { } } -void HistoryList::resizeEvent(QResizeEvent *e) { +void HistoryInner::resizeEvent(QResizeEvent *e) { onUpdateSelected(); } -QString HistoryList::getSelectedText() const { +QString HistoryInner::getSelectedText() const { SelectedItems sel = _selected; if (_dragAction == Selecting && _dragSelFrom && _dragSelTo) { @@ -1070,7 +1070,7 @@ QString HistoryList::getSelectedText() const { return result; } -void HistoryList::keyPressEvent(QKeyEvent *e) { +void HistoryInner::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { historyWidget->onListEscapePressed(); } else if (e == QKeySequence::Copy && !_selected.isEmpty()) { @@ -1086,7 +1086,7 @@ void HistoryList::keyPressEvent(QKeyEvent *e) { } } -int32 HistoryList::recountHeight(HistoryItem *resizedItem) { +int32 HistoryInner::recountHeight(HistoryItem *resizedItem) { int32 st = hist->lastScrollTop; int32 ph = scrollArea->height(), minadd = 0; @@ -1127,7 +1127,7 @@ int32 HistoryList::recountHeight(HistoryItem *resizedItem) { return st + (newYSkip - wasYSkip); } -void HistoryList::updateBotInfo(bool recount) { +void HistoryInner::updateBotInfo(bool recount) { int32 newh = 0; if (botInfo && !botInfo->description.isEmpty()) { if (botInfo->text.isEmpty()) { @@ -1164,16 +1164,16 @@ void HistoryList::updateBotInfo(bool recount) { } } -bool HistoryList::wasSelectedText() const { +bool HistoryInner::wasSelectedText() const { return _wasSelectedText; } -void HistoryList::setFirstLoading(bool loading) { +void HistoryInner::setFirstLoading(bool loading) { _firstLoading = loading; update(); } -HistoryItem *HistoryList::atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const { +HistoryItem *HistoryInner::atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const { if (hist->isEmpty()) return 0; adjustCurrent(top); @@ -1205,7 +1205,7 @@ HistoryItem *HistoryList::atTopImportantMsg(int32 top, int32 height, int32 &bott return 0; } -void HistoryList::updateSize() { +void HistoryInner::updateSize() { int32 ph = scrollArea->height(), minadd = 0; int32 newYSkip = ph - (hist->height + st::historyPadding); if (botInfo && !botInfo->text.isEmpty()) { @@ -1234,11 +1234,11 @@ void HistoryList::updateSize() { } } -void HistoryList::enterEvent(QEvent *e) { +void HistoryInner::enterEvent(QEvent *e) { return QWidget::enterEvent(e); } -void HistoryList::leaveEvent(QEvent *e) { +void HistoryInner::leaveEvent(QEvent *e) { if (textlnkOver()) { updateMsg(App::hoveredItem()); updateMsg(App::hoveredLinkItem()); @@ -1253,12 +1253,12 @@ void HistoryList::leaveEvent(QEvent *e) { return QWidget::leaveEvent(e); } -HistoryList::~HistoryList() { +HistoryInner::~HistoryInner() { delete _menu; _dragAction = NoDrag; } -void HistoryList::adjustCurrent(int32 y) const { +void HistoryInner::adjustCurrent(int32 y) const { if (hist->isEmpty()) return; if (currentBlock >= hist->blocks.size()) { currentBlock = hist->blocks.size() - 1; @@ -1286,7 +1286,7 @@ void HistoryList::adjustCurrent(int32 y) const { } } -HistoryItem *HistoryList::prevItem(HistoryItem *item) { +HistoryItem *HistoryInner::prevItem(HistoryItem *item) { if (!item) return 0; HistoryBlock *block = item->block(); int32 blockIndex = hist->blocks.indexOf(block), itemIndex = block->items.indexOf(item); @@ -1300,7 +1300,7 @@ HistoryItem *HistoryList::prevItem(HistoryItem *item) { return 0; } -HistoryItem *HistoryList::nextItem(HistoryItem *item) { +HistoryItem *HistoryInner::nextItem(HistoryItem *item) { if (!item) return 0; HistoryBlock *block = item->block(); int32 blockIndex = hist->blocks.indexOf(block), itemIndex = block->items.indexOf(item); @@ -1314,18 +1314,18 @@ HistoryItem *HistoryList::nextItem(HistoryItem *item) { return 0; } -bool HistoryList::canCopySelected() const { +bool HistoryInner::canCopySelected() const { return !_selected.isEmpty(); } -bool HistoryList::canDeleteSelected() const { +bool HistoryInner::canDeleteSelected() const { if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return false; int32 selectedForForward, selectedForDelete; getSelectionState(selectedForForward, selectedForDelete); return (selectedForForward == selectedForDelete); } -void HistoryList::getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const { +void HistoryInner::getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const { selectedForForward = selectedForDelete = 0; for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { if (i.key()->type() == HistoryItemMsg && i.value() == FullItemSel) { @@ -1340,7 +1340,7 @@ void HistoryList::getSelectionState(int32 &selectedForForward, int32 &selectedFo } } -void HistoryList::clearSelectedItems(bool onlyTextSelection) { +void HistoryInner::clearSelectedItems(bool onlyTextSelection) { if (!_selected.isEmpty() && (!onlyTextSelection || _selected.cbegin().value() != FullItemSel)) { _selected.clear(); historyWidget->updateTopBarSelection(); @@ -1348,7 +1348,7 @@ void HistoryList::clearSelectedItems(bool onlyTextSelection) { } } -void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { +void HistoryInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return; for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { @@ -1359,7 +1359,7 @@ void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { } } -void HistoryList::selectItem(HistoryItem *item) { +void HistoryInner::selectItem(HistoryItem *item) { if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) { _selected.clear(); } else if (_selected.size() == MaxSelectedItems && _selected.constFind(item) == _selected.cend()) { @@ -1370,12 +1370,12 @@ void HistoryList::selectItem(HistoryItem *item) { historyWidget->update(); } -void HistoryList::onTouchSelect() { +void HistoryInner::onTouchSelect() { _touchSelect = true; dragActionStart(_touchPos); } -void HistoryList::onUpdateSelected() { +void HistoryInner::onUpdateSelected() { if (!hist) return; QPoint mousePos(mapFromGlobal(_dragPos)); @@ -1539,7 +1539,7 @@ void HistoryList::onUpdateSelected() { } } -void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) { +void HistoryInner::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force) { if (_dragSelFrom != dragSelFrom || _dragSelTo != dragSelTo || _dragSelecting != dragSelecting) { _dragSelFrom = dragSelFrom; _dragSelTo = dragSelTo; @@ -1558,11 +1558,11 @@ void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dra update(); } -void HistoryList::applyDragSelection() { +void HistoryInner::applyDragSelection() { applyDragSelection(&_selected); } -void HistoryList::applyDragSelection(SelectedItems *toItems) const { +void HistoryInner::applyDragSelection(SelectedItems *toItems) const { if (!toItems->isEmpty() && toItems->cbegin().value() != FullItemSel) { toItems->clear(); } @@ -1606,7 +1606,7 @@ void HistoryList::applyDragSelection(SelectedItems *toItems) const { } } -void HistoryList::showLinkTip() { +void HistoryInner::showLinkTip() { TextLinkPtr lnk = textlnkOver(); int32 dd = QApplication::startDragDistance(); QPoint dp(mapFromGlobal(_dragPos)); @@ -1620,7 +1620,7 @@ void HistoryList::showLinkTip() { } } -void HistoryList::onParentGeometryChanged() { +void HistoryInner::onParentGeometryChanged() { bool needToUpdate = (_dragAction != NoDrag || _touchScroll || rect().contains(mapFromGlobal(QCursor::pos()))); if (needToUpdate) { dragActionUpdate(QCursor::pos()); @@ -2913,6 +2913,8 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) { if (_history->unreadBar) { _history->unreadBar->destroy(); } + + App::main()->dlgUpdated(_history); _history = 0; } @@ -2933,9 +2935,6 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) { _showAtMsgId = showAtMsgId; _histInited = false; - if (_history) { - App::main()->dlgUpdated(_history); - } _peer = peerId ? App::peer(peerId) : 0; _channel = _peer ? peerToChannel(_peer->id) : NoChannel; @@ -2979,7 +2978,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) { _history->lastWidth = 0; } - _list = new HistoryList(this, &_scroll, _history); + _list = new HistoryInner(this, &_scroll, _history); _list->hide(); _scroll.hide(); _scroll.setWidget(_list); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 66ef491e3..db38cec39 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -30,12 +30,12 @@ enum DragState { }; class HistoryWidget; -class HistoryList : public QWidget { +class HistoryInner : public QWidget { Q_OBJECT public: - HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, History *history); + HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history); void messagesReceived(const QVector &messages, const QVector *collapsed); void messagesReceivedDown(const QVector &messages, const QVector *collapsed); @@ -86,7 +86,7 @@ public: HistoryItem *atTopImportantMsg(int32 top, int32 height, int32 &bottomUnderScrollTop) const; - ~HistoryList(); + ~HistoryInner(); public slots: @@ -715,7 +715,7 @@ private: MsgId _activeAnimMsgId; ScrollArea _scroll; - HistoryList *_list; + HistoryInner *_list; History *_history; bool _histInited; // initial updateListSize() called diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 3be54d658..5ec1a612a 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -2661,7 +2661,7 @@ void MainWidget::onActiveChannelUpdateFull() { void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) { if (!msg) return; history.msgUpdated(peer, msg); - if (!msg->history()->dialogs.isEmpty()) dialogs.dlgUpdated(msg->history()->dialogs[0]); + if (!msg->history()->dialogs.isEmpty() && msg->history()->lastMsg == msg) dialogs.dlgUpdated(msg->history()->dialogs[0]); if (overview) overview->msgUpdated(peer, msg); } diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 9586da73a..0c7a40eb4 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -357,7 +357,7 @@ void PsMainWindow::psFirstShow() { namespace { void _sendKeySequence(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier) { QWidget *focused = QApplication::focusWidget(); - if (qobject_cast(focused) || qobject_cast(focused) || qobject_cast(focused)) { + if (qobject_cast(focused) || qobject_cast(focused) || qobject_cast(focused)) { QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifiers)); QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifiers)); } @@ -429,7 +429,7 @@ void PsMainWindow::psMacUpdateMenu() { canUndo = edit->isUndoAvailable(); canRedo = edit->isRedoAvailable(); canPaste = !App::app()->clipboard()->text().isEmpty(); - } else if (HistoryList *list = qobject_cast(focused)) { + } else if (HistoryInner *list = qobject_cast(focused)) { canCopy = list->canCopySelected(); canDelete = list->canDeleteSelected(); } @@ -509,7 +509,7 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) { QEvent::Type t = evt->type(); if (t == QEvent::FocusIn || t == QEvent::FocusOut) { - if (qobject_cast(obj) || qobject_cast(obj) || qobject_cast(obj)) { + if (qobject_cast(obj) || qobject_cast(obj) || qobject_cast(obj)) { psMacUpdateMenu(); } } diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index bea4b9b56..1249c32e8 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -94,7 +94,7 @@ TitleWidget::TitleWidget(Window *window) void TitleWidget::paintEvent(QPaintEvent *e) { QPainter p(this); - + LOG(("TITLE")); p.fillRect(QRect(0, 0, width(), st::titleHeight), st::titleBG->b); if (!_cancel.isHidden()) { p.setPen(st::titleTextButton.color->p); diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 3ef20b7f6..56e6cb0ad 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -368,7 +368,7 @@ _connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shoul setObjectName(qsl("MainWindow")); } resize(st::wndDefWidth, st::wndDefHeight); - setWindowOpacity(1); + setLocale(QLocale(QLocale::English, QLocale::UnitedStates)); centralwidget = new QWidget(this); centralwidget->setObjectName(qsl("centralwidget")); @@ -388,6 +388,9 @@ _connecting(0), _clearManager(0), dragging(false), _inactivePress(false), _shoul connect(this, SIGNAL(imageLoaded()), this, SLOT(update())); connect(this, SIGNAL(imageLoaded()), this, SLOT(notifyUpdateAllPhotos())); + + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_OpaquePaintEvent); } void Window::inactivePress(bool inactive) { diff --git a/Telegram/_qt_5_5_0_patch/qtbase/src/corelib/kernel/qobjectdefs.h b/Telegram/_qt_5_5_0_patch/qtbase/src/corelib/kernel/qobjectdefs.h deleted file mode 100644 index 9bee4732c..000000000 --- a/Telegram/_qt_5_5_0_patch/qtbase/src/corelib/kernel/qobjectdefs.h +++ /dev/null @@ -1,509 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QOBJECTDEFS_H -#define QOBJECTDEFS_H - -#if defined(__OBJC__) && !defined(__cplusplus) -# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)" -#endif - -#include - -#include - -QT_BEGIN_NAMESPACE - - -class QByteArray; -struct QArrayData; -typedef QArrayData QByteArrayData; - -class QString; - -#ifndef Q_MOC_OUTPUT_REVISION -#define Q_MOC_OUTPUT_REVISION 67 -#endif - -// The following macros are our "extensions" to C++ -// They are used, strictly speaking, only by the moc. - -#ifndef Q_MOC_RUN -#ifndef QT_NO_META_MACROS -# if defined(QT_NO_KEYWORDS) -# define QT_NO_EMIT -# else -# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS -# define slots -# define signals public -# endif -# endif -# define Q_SLOTS -# define Q_SIGNALS public -# define Q_PRIVATE_SLOT(d, signature) -# define Q_EMIT -#ifndef QT_NO_EMIT -# define emit -#endif -#define Q_CLASSINFO(name, value) -#define Q_PLUGIN_METADATA(x) -#define Q_INTERFACES(x) -#define Q_PROPERTY(text) -#define Q_PRIVATE_PROPERTY(d, text) -#define Q_REVISION(v) -#define Q_OVERRIDE(text) -#define Q_ENUMS(x) -#define Q_FLAGS(x) -#define Q_ENUM(ENUM) \ - friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \ - friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) Q_DECL_NOEXCEPT { return #ENUM; } -#define Q_FLAG(ENUM) Q_ENUM(ENUM) -#define Q_SCRIPTABLE -#define Q_INVOKABLE -#define Q_SIGNAL -#define Q_SLOT -#endif // QT_NO_META_MACROS - -#ifndef QT_NO_TRANSLATION -// full set of tr functions -# define QT_TR_FUNCTIONS \ - static inline QString tr(const char *s, const char *c = Q_NULLPTR, int n = -1) \ - { return staticMetaObject.tr(s, c, n); } \ - QT_DEPRECATED static inline QString trUtf8(const char *s, const char *c = Q_NULLPTR, int n = -1) \ - { return staticMetaObject.tr(s, c, n); } -#else -// inherit the ones from QObject -# define QT_TR_FUNCTIONS -#endif - -#if defined(QT_NO_QOBJECT_CHECK) -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT_CHECK -#else - -/* This is a compile time check that ensures that any class cast with qobject_cast - actually contains a Q_OBJECT macro. Note: qobject_cast will fail if a QObject - subclass doesn't contain Q_OBJECT. - - In qt_check_for_QOBJECT_macro, we call a dummy templated function with two - parameters, the first being "this" and the other the target of the qobject - cast. If the types are not identical, we know that a Q_OBJECT macro is missing. - - If you get a compiler error here, make sure that the class you are casting - to contains a Q_OBJECT macro. -*/ - -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT_CHECK \ - template inline void qt_check_for_QOBJECT_macro(const ThisObject &_q_argument) const \ - { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i + 1; } - -template -inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; } - -template -inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} -#endif // QT_NO_QOBJECT_CHECK - -#if defined(Q_CC_INTEL) -// Cannot redefine the visibility of a method in an exported class -# define Q_DECL_HIDDEN_STATIC_METACALL -#else -# define Q_DECL_HIDDEN_STATIC_METACALL Q_DECL_HIDDEN -#endif - -#if defined(Q_CC_CLANG) && (Q_CC_CLANG >= 306) && 0 -# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") -#else -# define Q_OBJECT_NO_OVERRIDE_WARNING -#endif - -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT \ -public: \ - Q_OBJECT_CHECK \ - QT_WARNING_PUSH \ - Q_OBJECT_NO_OVERRIDE_WARNING \ - static const QMetaObject staticMetaObject; \ - virtual const QMetaObject *metaObject() const; \ - virtual void *qt_metacast(const char *); \ - virtual int qt_metacall(QMetaObject::Call, int, void **); \ - QT_WARNING_POP \ - QT_TR_FUNCTIONS \ -private: \ - Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \ - struct QPrivateSignal {}; - -/* qmake ignore Q_OBJECT */ -#define Q_OBJECT_FAKE Q_OBJECT - -#ifndef QT_NO_META_MACROS -/* qmake ignore Q_GADGET */ -#define Q_GADGET \ -public: \ - static const QMetaObject staticMetaObject; \ - void qt_check_for_QGADGET_macro(); \ - typedef void QtGadgetHelper; \ -private: \ - Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); -#endif // QT_NO_META_MACROS - -#else // Q_MOC_RUN -#define slots slots -#define signals signals -#define Q_SLOTS Q_SLOTS -#define Q_SIGNALS Q_SIGNALS -#define Q_CLASSINFO(name, value) Q_CLASSINFO(name, value) -#define Q_INTERFACES(x) Q_INTERFACES(x) -#define Q_PROPERTY(text) Q_PROPERTY(text) -#define Q_PRIVATE_PROPERTY(d, text) Q_PRIVATE_PROPERTY(d, text) -#define Q_REVISION(v) Q_REVISION(v) -#define Q_OVERRIDE(text) Q_OVERRIDE(text) -#define Q_ENUMS(x) Q_ENUMS(x) -#define Q_FLAGS(x) Q_FLAGS(x) -#define Q_ENUM(x) Q_ENUM(x) -#define Q_FLAGS(x) Q_FLAGS(x) - /* qmake ignore Q_OBJECT */ -#define Q_OBJECT Q_OBJECT - /* qmake ignore Q_OBJECT */ -#define Q_OBJECT_FAKE Q_OBJECT_FAKE - /* qmake ignore Q_GADGET */ -#define Q_GADGET Q_GADGET -#define Q_SCRIPTABLE Q_SCRIPTABLE -#define Q_INVOKABLE Q_INVOKABLE -#define Q_SIGNAL Q_SIGNAL -#define Q_SLOT Q_SLOT -#endif //Q_MOC_RUN - -#ifndef QT_NO_META_MACROS -// macro for onaming members -#ifdef METHOD -#undef METHOD -#endif -#ifdef SLOT -#undef SLOT -#endif -#ifdef SIGNAL -#undef SIGNAL -#endif -#endif // QT_NO_META_MACROS - -Q_CORE_EXPORT const char *qFlagLocation(const char *method); - -#ifndef QT_NO_META_MACROS -#ifndef QT_NO_DEBUG -# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__) -# ifndef QT_NO_KEYWORDS -# define METHOD(a) qFlagLocation("0"#a QLOCATION) -# endif -# define SLOT(a) qFlagLocation("1"#a QLOCATION) -# define SIGNAL(a) qFlagLocation("2"#a QLOCATION) -#else -# ifndef QT_NO_KEYWORDS -# define METHOD(a) "0"#a -# endif -# define SLOT(a) "1"#a -# define SIGNAL(a) "2"#a -#endif - -#define QMETHOD_CODE 0 // member type codes -#define QSLOT_CODE 1 -#define QSIGNAL_CODE 2 -#endif // QT_NO_META_MACROS - -#define Q_ARG(type, data) QArgument(#type, data) -#define Q_RETURN_ARG(type, data) QReturnArgument(#type, data) - -class QObject; -class QMetaMethod; -class QMetaEnum; -class QMetaProperty; -class QMetaClassInfo; - - -class Q_CORE_EXPORT QGenericArgument -{ -public: - inline QGenericArgument(const char *aName = 0, const void *aData = 0) - : _data(aData), _name(aName) {} - inline void *data() const { return const_cast(_data); } - inline const char *name() const { return _name; } - -private: - const void *_data; - const char *_name; -}; - -class Q_CORE_EXPORT QGenericReturnArgument: public QGenericArgument -{ -public: - inline QGenericReturnArgument(const char *aName = 0, void *aData = 0) - : QGenericArgument(aName, aData) - {} -}; - -template -class QArgument: public QGenericArgument -{ -public: - inline QArgument(const char *aName, const T &aData) - : QGenericArgument(aName, static_cast(&aData)) - {} -}; -template -class QArgument: public QGenericArgument -{ -public: - inline QArgument(const char *aName, T &aData) - : QGenericArgument(aName, static_cast(&aData)) - {} -}; - - -template -class QReturnArgument: public QGenericReturnArgument -{ -public: - inline QReturnArgument(const char *aName, T &aData) - : QGenericReturnArgument(aName, static_cast(&aData)) - {} -}; - -struct Q_CORE_EXPORT QMetaObject -{ - class Connection; - const char *className() const; - const QMetaObject *superClass() const; - - QObject *cast(QObject *obj) const; - const QObject *cast(const QObject *obj) const; - -#ifndef QT_NO_TRANSLATION - QString tr(const char *s, const char *c, int n = -1) const; -#endif // QT_NO_TRANSLATION - - int methodOffset() const; - int enumeratorOffset() const; - int propertyOffset() const; - int classInfoOffset() const; - - int constructorCount() const; - int methodCount() const; - int enumeratorCount() const; - int propertyCount() const; - int classInfoCount() const; - - int indexOfConstructor(const char *constructor) const; - int indexOfMethod(const char *method) const; - int indexOfSignal(const char *signal) const; - int indexOfSlot(const char *slot) const; - int indexOfEnumerator(const char *name) const; - int indexOfProperty(const char *name) const; - int indexOfClassInfo(const char *name) const; - - QMetaMethod constructor(int index) const; - QMetaMethod method(int index) const; - QMetaEnum enumerator(int index) const; - QMetaProperty property(int index) const; - QMetaClassInfo classInfo(int index) const; - QMetaProperty userProperty() const; - - static bool checkConnectArgs(const char *signal, const char *method); - static bool checkConnectArgs(const QMetaMethod &signal, - const QMetaMethod &method); - static QByteArray normalizedSignature(const char *method); - static QByteArray normalizedType(const char *type); - - // internal index-based connect - static Connection connect(const QObject *sender, int signal_index, - const QObject *receiver, int method_index, - int type = 0, int *types = 0); - // internal index-based disconnect - static bool disconnect(const QObject *sender, int signal_index, - const QObject *receiver, int method_index); - static bool disconnectOne(const QObject *sender, int signal_index, - const QObject *receiver, int method_index); - // internal slot-name based connect - static void connectSlotsByName(QObject *o); - - // internal index-based signal activation - static void activate(QObject *sender, int signal_index, void **argv); - static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv); - static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv); - - static bool invokeMethod(QObject *obj, const char *member, - Qt::ConnectionType, - QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()); - - static inline bool invokeMethod(QObject *obj, const char *member, - QGenericReturnArgument ret, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3, - val4, val5, val6, val7, val8, val9); - } - - static inline bool invokeMethod(QObject *obj, const char *member, - Qt::ConnectionType type, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2, - val3, val4, val5, val6, val7, val8, val9); - } - - static inline bool invokeMethod(QObject *obj, const char *member, - QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) - { - return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0, - val1, val2, val3, val4, val5, val6, val7, val8, val9); - } - - QObject *newInstance(QGenericArgument val0 = QGenericArgument(0), - QGenericArgument val1 = QGenericArgument(), - QGenericArgument val2 = QGenericArgument(), - QGenericArgument val3 = QGenericArgument(), - QGenericArgument val4 = QGenericArgument(), - QGenericArgument val5 = QGenericArgument(), - QGenericArgument val6 = QGenericArgument(), - QGenericArgument val7 = QGenericArgument(), - QGenericArgument val8 = QGenericArgument(), - QGenericArgument val9 = QGenericArgument()) const; - - enum Call { - InvokeMetaMethod, - ReadProperty, - WriteProperty, - ResetProperty, - QueryPropertyDesignable, - QueryPropertyScriptable, - QueryPropertyStored, - QueryPropertyEditable, - QueryPropertyUser, - CreateInstance, - IndexOfMethod, - RegisterPropertyMetaType, - RegisterMethodArgumentMetaType - }; - - int static_metacall(Call, int, void **) const; - static int metacall(QObject *, Call, int, void **); - - struct { // private data - const QMetaObject *superdata; - const QByteArrayData *stringdata; - const uint *data; - typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); - StaticMetacallFunction static_metacall; - const QMetaObject * const *relatedMetaObjects; - void *extradata; //reserved for future use - } d; -}; - -class Q_CORE_EXPORT QMetaObject::Connection { - void *d_ptr; //QObjectPrivate::Connection* - explicit Connection(void *data) : d_ptr(data) { } - friend class QObject; - friend class QObjectPrivate; - friend struct QMetaObject; -public: - ~Connection(); - Connection(); - Connection(const Connection &other); - Connection &operator=(const Connection &other); -#ifdef Q_QDOC - operator bool() const; -#else - typedef void *Connection::*RestrictedBool; - operator RestrictedBool() const { return d_ptr ? &Connection::d_ptr : 0; } -#endif - -#ifdef Q_COMPILER_RVALUE_REFS - inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; } - inline Connection &operator=(Connection &&other) - { qSwap(d_ptr, other.d_ptr); return *this; } -#endif -}; - -inline const QMetaObject *QMetaObject::superClass() const -{ return d.superdata; } - -namespace QtPrivate { - /* Trait that tells is a the Object has a Q_OBJECT macro */ - template struct HasQ_OBJECT_Macro { - template - static char test(int (T::*)(QMetaObject::Call, int, void **)); - static int test(int (Object::*)(QMetaObject::Call, int, void **)); - enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) }; - }; -} - -QT_END_NAMESPACE - -#endif // QOBJECTDEFS_H diff --git a/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h b/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h index dab59c86f..1014a2104 100644 --- a/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -62,7 +62,7 @@ public: private: QImage m_qImage; QSize m_requestedSize; - bool m_imageWasEqual; + bool m_qImageNeedsClear, m_imageWasEqual; }; QT_END_NAMESPACE diff --git a/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 3a153de05..cab243e43 100644 --- a/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/Telegram/_qt_5_5_0_patch/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE QCocoaBackingStore::QCocoaBackingStore(QWindow *window) - : QPlatformBackingStore(window), m_imageWasEqual(false) + : QPlatformBackingStore(window), m_qImageNeedsClear(false), m_imageWasEqual(false) { } @@ -57,9 +57,10 @@ QPaintDevice *QCocoaBackingStore::paintDevice() if (m_qImage.size() != effectiveBufferSize) { QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_qImageNeedsClear = window()->requestedFormat().hasAlpha() || cocoaWindow->m_drawContentBorderGradient; m_qImage = QImage(effectiveBufferSize, format); m_qImage.setDevicePixelRatio(windowDevicePixelRatio); - if (format == QImage::Format_ARGB32_Premultiplied) + if (m_qImageNeedsClear) m_qImage.fill(Qt::transparent); } return &m_qImage; @@ -98,7 +99,7 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) void QCocoaBackingStore::beginPaint(const QRegion ®ion) { - if (m_qImage.hasAlphaChannel()) { + if (m_qImageNeedsClear && m_qImage.hasAlphaChannel()) { QPainter p(&m_qImage); p.setCompositionMode(QPainter::CompositionMode_Source); const QVector rects = region.rects();