mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Fix keyboard navigation in top peers.
This commit is contained in:
parent
e066cf1589
commit
7111c92ae7
3 changed files with 113 additions and 31 deletions
|
@ -962,6 +962,11 @@ void Suggestions::setupChats() {
|
|||
});
|
||||
}, _topPeers->lifetime());
|
||||
|
||||
_topPeers->scrollToRequests(
|
||||
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
_chatsScroll->scrollToY(request.ymin, request.ymax);
|
||||
}, _topPeers->lifetime());
|
||||
|
||||
_chatsScroll->setVisible(_tab.current() == Tab::Chats);
|
||||
}
|
||||
|
||||
|
@ -1015,19 +1020,19 @@ void Suggestions::selectJumpChats(Qt::Key direction, int pageSize) {
|
|||
} else if (direction == Qt::Key_Up) {
|
||||
if (_recentSelectJump(direction, pageSize)
|
||||
== JumpResult::AppliedAndOut) {
|
||||
_topPeers->selectByKeyboard({});
|
||||
_chatsScroll->scrollTo(0);
|
||||
} else {
|
||||
_topPeers->deselectByKeyboard();
|
||||
_topPeers->selectByKeyboard(direction);
|
||||
} else if (_topPeers->selectedByKeyboard()) {
|
||||
_topPeers->selectByKeyboard(direction);
|
||||
}
|
||||
} else if (direction == Qt::Key_Down) {
|
||||
if (_topPeers->selectedByKeyboard()) {
|
||||
if (_recentCount.current() > 0) {
|
||||
if (!_topPeersWrap->toggled() || recentHasSelection()) {
|
||||
_recentSelectJump(direction, pageSize);
|
||||
} else if (_topPeers->selectedByKeyboard()) {
|
||||
if (!_topPeers->selectByKeyboard(direction)
|
||||
&& _recentCount.current() > 0) {
|
||||
_topPeers->deselectByKeyboard();
|
||||
_recentSelectJump(direction, pageSize);
|
||||
}
|
||||
} else if (!_topPeersWrap->toggled() || recentHasSelection()) {
|
||||
_recentSelectJump(direction, pageSize);
|
||||
} else {
|
||||
_topPeers->selectByKeyboard({});
|
||||
_chatsScroll->scrollTo(0);
|
||||
|
@ -1035,7 +1040,6 @@ void Suggestions::selectJumpChats(Qt::Key direction, int pageSize) {
|
|||
} else if (direction == Qt::Key_Left || direction == Qt::Key_Right) {
|
||||
if (!recentHasSelection()) {
|
||||
_topPeers->selectByKeyboard(direction);
|
||||
_chatsScroll->scrollTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/dynamic_image.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/unread_badge_paint.h"
|
||||
|
@ -242,8 +243,12 @@ void TopPeersStrip::stripWheelEvent(QWheelEvent *e) {
|
|||
}
|
||||
|
||||
void TopPeersStrip::stripLeaveEvent(QEvent *e) {
|
||||
setSelected(-1);
|
||||
_selectionByKeyboard = false;
|
||||
if (!_selectionByKeyboard) {
|
||||
setSelected(-1);
|
||||
}
|
||||
if (!_dragging) {
|
||||
_lastMousePosition = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void TopPeersStrip::stripMousePressEvent(QMouseEvent *e) {
|
||||
|
@ -251,6 +256,7 @@ void TopPeersStrip::stripMousePressEvent(QMouseEvent *e) {
|
|||
return;
|
||||
}
|
||||
_lastMousePosition = e->globalPos();
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
|
||||
_mouseDownPosition = _lastMousePosition;
|
||||
|
@ -280,7 +286,13 @@ void TopPeersStrip::stripMousePressEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void TopPeersStrip::stripMouseMoveEvent(QMouseEvent *e) {
|
||||
if (_lastMousePosition == e->globalPos() && _selectionByKeyboard) {
|
||||
if (!_lastMousePosition) {
|
||||
_lastMousePosition = e->globalPos();
|
||||
if (_selectionByKeyboard) {
|
||||
return;
|
||||
}
|
||||
} else if (_selectionByKeyboard
|
||||
&& (_lastMousePosition == e->globalPos())) {
|
||||
return;
|
||||
}
|
||||
_lastMousePosition = e->globalPos();
|
||||
|
@ -288,7 +300,7 @@ void TopPeersStrip::stripMouseMoveEvent(QMouseEvent *e) {
|
|||
updateSelected();
|
||||
|
||||
if (!_dragging && _mouseDownPosition) {
|
||||
if ((_lastMousePosition - *_mouseDownPosition).manhattanLength()
|
||||
if ((*_lastMousePosition - *_mouseDownPosition).manhattanLength()
|
||||
>= QApplication::startDragDistance()) {
|
||||
if (!_expandAnimation.animating()) {
|
||||
_dragging = true;
|
||||
|
@ -303,7 +315,7 @@ void TopPeersStrip::checkDragging() {
|
|||
if (_dragging && !_expandAnimation.animating()) {
|
||||
const auto sign = (style::RightToLeft() ? -1 : 1);
|
||||
const auto newLeft = std::clamp(
|
||||
(sign * (_mouseDownPosition->x() - _lastMousePosition.x())
|
||||
(sign * (_mouseDownPosition->x() - _lastMousePosition->x())
|
||||
+ _startDraggingLeft),
|
||||
0,
|
||||
_scrollLeftMax);
|
||||
|
@ -367,6 +379,7 @@ void TopPeersStrip::stripMouseReleaseEvent(QMouseEvent *e) {
|
|||
if (finishDragging()) {
|
||||
return;
|
||||
}
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
if (_selected >= 0 && _selected == pressed) {
|
||||
Assert(_selected < _entries.size());
|
||||
|
@ -412,6 +425,11 @@ auto TopPeersStrip::showMenuRequests() const
|
|||
return _showMenuRequests.events();
|
||||
}
|
||||
|
||||
auto TopPeersStrip::scrollToRequests() const
|
||||
-> rpl::producer<Ui::ScrollToRequest> {
|
||||
return _scrollToRequests.events();
|
||||
}
|
||||
|
||||
void TopPeersStrip::removeLocally(uint64 id) {
|
||||
if (!id) {
|
||||
unsubscribeUserpics(true);
|
||||
|
@ -446,34 +464,76 @@ bool TopPeersStrip::selectedByKeyboard() const {
|
|||
return _selectionByKeyboard && _selected >= 0;
|
||||
}
|
||||
|
||||
void TopPeersStrip::selectByKeyboard(Qt::Key direction) {
|
||||
bool TopPeersStrip::selectByKeyboard(Qt::Key direction) {
|
||||
if (_entries.empty()) {
|
||||
return;
|
||||
}
|
||||
if (direction == Qt::Key()) {
|
||||
return false;
|
||||
} else if (direction == Qt::Key()) {
|
||||
_selectionByKeyboard = true;
|
||||
if (_selected < 0) {
|
||||
setSelected(0);
|
||||
scrollToSelected();
|
||||
return true;
|
||||
}
|
||||
} else if (direction == Qt::Key_Left) {
|
||||
if (_selected > 0) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(_selected - 1);
|
||||
scrollToSelected();
|
||||
return true;
|
||||
}
|
||||
} else if (direction == Qt::Key_Right) {
|
||||
if (_selected + 1 < _entries.size()) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(_selected + 1);
|
||||
scrollToSelected();
|
||||
return true;
|
||||
}
|
||||
} else if (direction == Qt::Key_Up) {
|
||||
const auto layout = currentLayout();
|
||||
if (_selected < 0) {
|
||||
_selectionByKeyboard = true;
|
||||
const auto rows = _expanded.current()
|
||||
? ((int(_entries.size()) + layout.inrow - 1) / layout.inrow)
|
||||
: 1;
|
||||
setSelected((rows - 1) * layout.inrow);
|
||||
scrollToSelected();
|
||||
return true;
|
||||
} else if (!_expanded.current()) {
|
||||
deselectByKeyboard();
|
||||
} else if (_selected >= 0) {
|
||||
const auto row = _selected / layout.inrow;
|
||||
if (row > 0) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(_selected - layout.inrow);
|
||||
scrollToSelected();
|
||||
return true;
|
||||
} else {
|
||||
deselectByKeyboard();
|
||||
}
|
||||
}
|
||||
} else if (direction == Qt::Key_Down) {
|
||||
if (_selected >= 0 && _expanded.current()) {
|
||||
const auto layout = currentLayout();
|
||||
const auto row = _selected / layout.inrow;
|
||||
const auto rows = (int(_entries.size()) + layout.inrow - 1)
|
||||
/ layout.inrow;
|
||||
if (row + 1 < rows) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(std::min(
|
||||
_selected + layout.inrow,
|
||||
int(_entries.size()) - 1));
|
||||
scrollToSelected();
|
||||
return true;
|
||||
} else {
|
||||
deselectByKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TopPeersStrip::deselectByKeyboard() {
|
||||
if (_selectionByKeyboard) {
|
||||
_selectionByKeyboard = false;
|
||||
setSelected(-1);
|
||||
}
|
||||
}
|
||||
|
@ -760,6 +820,7 @@ void TopPeersStrip::stripContextMenuEvent(QContextMenuEvent *e) {
|
|||
|
||||
if (e->reason() == QContextMenuEvent::Mouse) {
|
||||
_lastMousePosition = e->globalPos();
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
}
|
||||
if (_selected < 0 || _entries.empty()) {
|
||||
|
@ -781,6 +842,7 @@ void TopPeersStrip::stripContextMenuEvent(QContextMenuEvent *e) {
|
|||
const auto globalPosition = QCursor::pos();
|
||||
if (rect().contains(mapFromGlobal(globalPosition))) {
|
||||
_lastMousePosition = globalPosition;
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
}
|
||||
};
|
||||
|
@ -798,6 +860,7 @@ bool TopPeersStrip::finishDragging() {
|
|||
}
|
||||
checkDragging();
|
||||
_dragging = false;
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
return true;
|
||||
}
|
||||
|
@ -818,10 +881,10 @@ TopPeersStrip::Layout TopPeersStrip::currentLayout() const {
|
|||
}
|
||||
|
||||
void TopPeersStrip::updateSelected() {
|
||||
if (_pressed >= 0) {
|
||||
if (_pressed >= 0 || !_lastMousePosition || _selectionByKeyboard) {
|
||||
return;
|
||||
}
|
||||
const auto p = _strip.mapFromGlobal(_lastMousePosition);
|
||||
const auto p = _strip.mapFromGlobal(*_lastMousePosition);
|
||||
const auto expanded = _expanded.current();
|
||||
const auto row = expanded ? (p.y() / st::topPeers.height) : 0;
|
||||
const auto layout = currentLayout();
|
||||
|
@ -844,14 +907,24 @@ void TopPeersStrip::setSelected(int selected) {
|
|||
void TopPeersStrip::scrollToSelected() {
|
||||
if (_selected < 0) {
|
||||
return;
|
||||
}
|
||||
const auto single = outer().width();
|
||||
const auto left = _selected * single;
|
||||
const auto right = left + single;
|
||||
if (_scrollLeft > left) {
|
||||
_scrollLeft = std::clamp(left, 0, _scrollLeftMax);
|
||||
} else if (_scrollLeft + width() < right) {
|
||||
_scrollLeft = std::clamp(right - width(), 0, _scrollLeftMax);
|
||||
} else if (_expanded.current()) {
|
||||
const auto layout = currentLayout();
|
||||
const auto row = _selected / layout.inrow;
|
||||
const auto header = _header.height();
|
||||
const auto top = header + row * st::topPeers.height;
|
||||
const auto bottom = top + st::topPeers.height;
|
||||
_scrollToRequests.fire({ top - (row ? 0 : header), bottom});
|
||||
} else {
|
||||
const auto single = outer().width();
|
||||
const auto left = _selected * single;
|
||||
const auto right = left + single;
|
||||
if (_scrollLeft > left) {
|
||||
_scrollLeft = std::clamp(left, 0, _scrollLeftMax);
|
||||
} else if (_scrollLeft + width() < right) {
|
||||
_scrollLeft = std::clamp(right - width(), 0, _scrollLeftMax);
|
||||
}
|
||||
const auto height = _header.height() + st::topPeers.height;
|
||||
_scrollToRequests.fire({ 0, height });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Ui {
|
||||
class DynamicImage;
|
||||
class LinkButton;
|
||||
struct ScrollToRequest;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Dialogs {
|
||||
|
@ -51,11 +52,13 @@ public:
|
|||
[[nodiscard]] rpl::producer<uint64> clicks() const;
|
||||
[[nodiscard]] auto showMenuRequests() const
|
||||
-> rpl::producer<ShowTopPeerMenuRequest>;
|
||||
[[nodiscard]] auto scrollToRequests() const
|
||||
-> rpl::producer<Ui::ScrollToRequest>;
|
||||
|
||||
void removeLocally(uint64 id = 0);
|
||||
|
||||
[[nodiscard]] bool selectedByKeyboard() const;
|
||||
void selectByKeyboard(Qt::Key direction);
|
||||
bool selectByKeyboard(Qt::Key direction);
|
||||
void deselectByKeyboard();
|
||||
bool chooseRow();
|
||||
|
||||
|
@ -106,7 +109,7 @@ private:
|
|||
rpl::event_stream<ShowTopPeerMenuRequest> _showMenuRequests;
|
||||
rpl::event_stream<not_null<QWheelEvent*>> _verticalScrollEvents;
|
||||
|
||||
QPoint _lastMousePosition;
|
||||
std::optional<QPoint> _lastMousePosition;
|
||||
std::optional<QPoint> _mouseDownPosition;
|
||||
int _startDraggingLeft = 0;
|
||||
int _scrollLeft = 0;
|
||||
|
@ -122,6 +125,8 @@ private:
|
|||
Ui::Animations::Simple _expandAnimation;
|
||||
rpl::variable<bool> _expanded = false;
|
||||
|
||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||
|
||||
Ui::RoundRect _selection;
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
base::has_weak_ptr _menuGuard;
|
||||
|
|
Loading…
Add table
Reference in a new issue