diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 7aa48aaa38..dca4a065ba 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -2125,6 +2125,16 @@ bool PeerListContent::submitted() { return false; } +PeerListRowId PeerListContent::updateFromParentDrag(QPoint globalPosition) { + selectByMouse(globalPosition); + const auto row = getRow(_selected.index); + return row ? row->id() : 0; +} + +void PeerListContent::dragLeft() { + clearSelection(); +} + void PeerListContent::visibleTopBottomUpdated( int visibleTop, int visibleBottom) { diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 335001e02c..4349fd8c60 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -625,6 +625,9 @@ public: void searchQueryChanged(QString query); bool submitted(); + PeerListRowId updateFromParentDrag(QPoint globalPosition); + void dragLeft(); + // Interface for the controller. void appendRow(std::unique_ptr row); void appendSearchRow(std::unique_ptr row); diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index a777cddca7..da180d1202 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -2543,15 +2543,18 @@ void Widget::dragMoveEvent(QDragMoveEvent *e) { } else { _chooseByDragTimer.callOnce(ChoosePeerByDragTimeout); } - if (_inner->updateFromParentDrag(mapToGlobal(e->pos()))) { - e->setDropAction(Qt::CopyAction); - } else { - e->setDropAction(Qt::IgnoreAction); - } + const auto global = mapToGlobal(e->pos()); + const auto thread = _suggestions + ? _suggestions->updateFromParentDrag(global) + : _inner->updateFromParentDrag(global); + e->setDropAction(thread ? Qt::CopyAction : Qt::IgnoreAction); } else { if (_dragForward) { updateDragInScroll(false); } + if (_suggestions) { + _suggestions->dragLeft(); + } _inner->dragLeft(); e->setDropAction(Qt::IgnoreAction); } @@ -2564,6 +2567,9 @@ void Widget::dragLeaveEvent(QDragLeaveEvent *e) { } else { _chooseByDragTimer.cancel(); } + if (_suggestions) { + _suggestions->dragLeft(); + } _inner->dragLeft(); e->accept(); } @@ -2582,8 +2588,11 @@ void Widget::updateDragInScroll(bool inScroll) { void Widget::dropEvent(QDropEvent *e) { _chooseByDragTimer.cancel(); if (_scroll->geometry().contains(e->pos())) { - const auto point = mapToGlobal(e->pos()); - if (const auto thread = _inner->updateFromParentDrag(point)) { + const auto globalPosition = mapToGlobal(e->pos()); + const auto thread = _suggestions + ? _suggestions->updateFromParentDrag(globalPosition) + : _inner->updateFromParentDrag(globalPosition); + if (thread) { e->setDropAction(Qt::CopyAction); e->accept(); controller()->content()->filesOrForwardDrop( diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 50362e657a..37be201fa9 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -1121,6 +1121,39 @@ void Suggestions::chooseRow() { } } +Data::Thread *Suggestions::updateFromParentDrag(QPoint globalPosition) { + return (_tab.current() == Tab::Chats) + ? updateFromChatsDrag(globalPosition) + : updateFromChannelsDrag(globalPosition); +} + +Data::Thread *Suggestions::updateFromChatsDrag(QPoint globalPosition) { + if (const auto top = _topPeers->updateFromParentDrag(globalPosition)) { + return _controller->session().data().history(PeerId(top)); + } + return fromListId(_recentUpdateFromParentDrag(globalPosition)); +} + +Data::Thread *Suggestions::updateFromChannelsDrag(QPoint globalPosition) { + if (const auto id = _myChannelsUpdateFromParentDrag(globalPosition)) { + return fromListId(id); + } + return fromListId(_recommendationsUpdateFromParentDrag(globalPosition)); +} + +Data::Thread *Suggestions::fromListId(uint64 peerListRowId) { + return peerListRowId + ? _controller->session().data().history(PeerId(peerListRowId)).get() + : nullptr; +} + +void Suggestions::dragLeft() { + _topPeers->dragLeft(); + _recentDragLeft(); + _myChannelsDragLeft(); + _recommendationsDragLeft(); +} + void Suggestions::show(anim::type animated, Fn finish) { RpWidget::show(); @@ -1304,6 +1337,12 @@ object_ptr> Suggestions::setupRecentPeers( } return JumpResult::NotApplied; }; + _recentUpdateFromParentDrag = [=](QPoint globalPosition) { + return raw->updateFromParentDrag(globalPosition); + }; + _recentDragLeft = [=] { + raw->dragLeft(); + }; raw->scrollToRequests( ) | rpl::start_with_next([this](Ui::ScrollToRequest request) { const auto add = _topPeersWrap->toggled() ? _topPeers->height() : 0; @@ -1438,6 +1477,12 @@ object_ptr> Suggestions::setupMyChannels() { } return JumpResult::NotApplied; }; + _myChannelsUpdateFromParentDrag = [=](QPoint globalPosition) { + return raw->updateFromParentDrag(globalPosition); + }; + _myChannelsDragLeft = [=] { + raw->dragLeft(); + }; raw->scrollToRequests( ) | rpl::start_with_next([this](Ui::ScrollToRequest request) { _channelsScroll->scrollToY(request.ymin, request.ymax); @@ -1499,6 +1544,12 @@ object_ptr> Suggestions::setupRecommendations() { } return JumpResult::NotApplied; }; + _recommendationsUpdateFromParentDrag = [=](QPoint globalPosition) { + return raw->updateFromParentDrag(globalPosition); + }; + _recommendationsDragLeft = [=] { + raw->dragLeft(); + }; raw->scrollToRequests( ) | rpl::start_with_next([this](Ui::ScrollToRequest request) { const auto add = _myChannels->toggled() ? _myChannels->height() : 0; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h index 49b74fa740..947bf2fa9d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h @@ -12,6 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/animations.h" #include "ui/rp_widget.h" +namespace Data { +class Thread; +} // namespace Data + namespace Main { class Session; } // namespace Main @@ -46,6 +50,9 @@ public: void selectJump(Qt::Key direction, int pageSize = 0); void chooseRow(); + [[nodiscard]] Data::Thread *updateFromParentDrag(QPoint globalPosition); + void dragLeft(); + void show(anim::type animated, Fn finish); void hide(anim::type animated, Fn finish); [[nodiscard]] float64 shownOpacity() const; @@ -90,6 +97,11 @@ private: void selectJumpChats(Qt::Key direction, int pageSize); void selectJumpChannels(Qt::Key direction, int pageSize); + [[nodiscard]] Data::Thread *updateFromChatsDrag(QPoint globalPosition); + [[nodiscard]] Data::Thread *updateFromChannelsDrag( + QPoint globalPosition); + [[nodiscard]] Data::Thread *fromListId(uint64 peerListRowId); + [[nodiscard]] object_ptr> setupRecentPeers( RecentPeersList recentPeers); [[nodiscard]] object_ptr> setupEmptyRecent(); @@ -121,6 +133,8 @@ private: rpl::variable _recentCount; Fn _recentPeersChoose; Fn _recentSelectJump; + Fn _recentUpdateFromParentDrag; + Fn _recentDragLeft; const not_null*> _recentPeers; const not_null*> _emptyRecent; @@ -130,11 +144,15 @@ private: rpl::variable _myChannelsCount; Fn _myChannelsChoose; Fn _myChannelsSelectJump; + Fn _myChannelsUpdateFromParentDrag; + Fn _myChannelsDragLeft; const not_null*> _myChannels; rpl::variable _recommendationsCount; Fn _recommendationsChoose; Fn _recommendationsSelectJump; + Fn _recommendationsUpdateFromParentDrag; + Fn _recommendationsDragLeft; const not_null*> _recommendations; const not_null*> _emptyChannels; diff --git a/Telegram/SourceFiles/dialogs/ui/top_peers_strip.cpp b/Telegram/SourceFiles/dialogs/ui/top_peers_strip.cpp index f793da346c..40e758ad2a 100644 --- a/Telegram/SourceFiles/dialogs/ui/top_peers_strip.cpp +++ b/Telegram/SourceFiles/dialogs/ui/top_peers_strip.cpp @@ -248,7 +248,7 @@ void TopPeersStrip::stripWheelEvent(QWheelEvent *e) { void TopPeersStrip::stripLeaveEvent(QEvent *e) { if (!_selectionByKeyboard) { - setSelected(-1); + clearSelection(); } if (!_dragging) { _lastMousePosition = std::nullopt; @@ -299,9 +299,7 @@ void TopPeersStrip::stripMouseMoveEvent(QMouseEvent *e) { && (_lastMousePosition == e->globalPos())) { return; } - _lastMousePosition = e->globalPos(); - _selectionByKeyboard = false; - updateSelected(); + selectByMouse(e->globalPos()); if (!_dragging && _mouseDownPosition) { if ((*_lastMousePosition - *_mouseDownPosition).manhattanLength() @@ -315,6 +313,12 @@ void TopPeersStrip::stripMouseMoveEvent(QMouseEvent *e) { checkDragging(); } +void TopPeersStrip::selectByMouse(QPoint globalPosition) { + _lastMousePosition = globalPosition; + _selectionByKeyboard = false; + updateSelected(); +} + void TopPeersStrip::checkDragging() { if (_dragging && !_expandAnimation.animating()) { const auto sign = (style::RightToLeft() ? -1 : 1); @@ -551,6 +555,20 @@ bool TopPeersStrip::chooseRow() { return false; } +uint64 TopPeersStrip::updateFromParentDrag(QPoint globalPosition) { + if (!rect().contains(mapFromGlobal(globalPosition))) { + dragLeft(); + return 0; + } + selectByMouse(globalPosition); + + return (_selected >= 0) ? _entries[_selected].id : 0; +} + +void TopPeersStrip::dragLeft() { + clearSelection(); +} + void TopPeersStrip::apply(const TopPeersList &list) { if (_hiddenLocally) { return; @@ -908,6 +926,10 @@ void TopPeersStrip::setSelected(int selected) { } } +void TopPeersStrip::clearSelection() { + setSelected(-1); +} + void TopPeersStrip::scrollToSelected() { if (_selected < 0) { return; diff --git a/Telegram/SourceFiles/dialogs/ui/top_peers_strip.h b/Telegram/SourceFiles/dialogs/ui/top_peers_strip.h index 9894235c69..23db15d1f2 100644 --- a/Telegram/SourceFiles/dialogs/ui/top_peers_strip.h +++ b/Telegram/SourceFiles/dialogs/ui/top_peers_strip.h @@ -62,6 +62,9 @@ public: void deselectByKeyboard(); bool chooseRow(); + uint64 updateFromParentDrag(QPoint globalPosition); + void dragLeft(); + [[nodiscard]] auto verticalScrollEvents() const -> rpl::producer>; @@ -92,6 +95,8 @@ private: void subscribeUserpic(Entry &entry); void unsubscribeUserpics(bool all = false); void paintUserpic(Painter &p, int x, int y, int index, bool selected); + void clearSelection(); + void selectByMouse(QPoint globalPosition); [[nodiscard]] QRect outer() const; [[nodiscard]] QRect innerRounded() const;