mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Add keyboard navigation to top peers.
This commit is contained in:
parent
a6c1def6fe
commit
e1c21b908c
5 changed files with 162 additions and 7 deletions
|
@ -1720,7 +1720,10 @@ void Widget::escape() {
|
|||
}
|
||||
|
||||
void Widget::submit() {
|
||||
if (_inner->chooseRow()) {
|
||||
if (_suggestions) {
|
||||
_suggestions->chooseRow();
|
||||
return;
|
||||
} else if (_inner->chooseRow()) {
|
||||
return;
|
||||
}
|
||||
const auto state = _inner->state();
|
||||
|
@ -3142,13 +3145,34 @@ void Widget::keyPressEvent(QKeyEvent *e) {
|
|||
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
||||
submit();
|
||||
} else if (e->key() == Qt::Key_Down) {
|
||||
_inner->selectSkip(1);
|
||||
if (_suggestions) {
|
||||
_suggestions->selectSkip(1);
|
||||
} else {
|
||||
_inner->selectSkip(1);
|
||||
}
|
||||
} else if (e->key() == Qt::Key_Up) {
|
||||
if (_suggestions) {
|
||||
_suggestions->selectSkip(-1);
|
||||
} else {
|
||||
_inner->selectSkip(-1);
|
||||
}
|
||||
_inner->selectSkip(-1);
|
||||
} else if (e->key() == Qt::Key_Left && _suggestions) {
|
||||
_suggestions->selectLeft();
|
||||
} else if (e->key() == Qt::Key_Right && _suggestions) {
|
||||
_suggestions->selectRight();
|
||||
} else if (e->key() == Qt::Key_PageDown) {
|
||||
_inner->selectSkipPage(_scroll->height(), 1);
|
||||
if (_suggestions) {
|
||||
_suggestions->selectSkipPage(_scroll->height(), 1);
|
||||
} else {
|
||||
_inner->selectSkipPage(_scroll->height(), 1);
|
||||
}
|
||||
} else if (e->key() == Qt::Key_PageUp) {
|
||||
_inner->selectSkipPage(_scroll->height(), -1);
|
||||
if (_suggestions) {
|
||||
_suggestions->selectSkipPage(_scroll->height(), -1);
|
||||
} else {
|
||||
_inner->selectSkipPage(_scroll->height(), -1);
|
||||
}
|
||||
} else if (!(e->modifiers() & ~Qt::ShiftModifier)
|
||||
&& e->key() != Qt::Key_Shift
|
||||
&& !_openedFolder
|
||||
|
|
|
@ -100,6 +100,43 @@ Suggestions::Suggestions(
|
|||
|
||||
Suggestions::~Suggestions() = default;
|
||||
|
||||
void Suggestions::selectSkip(int delta) {
|
||||
if (!delta) {
|
||||
return;
|
||||
} else if (delta > 0) {
|
||||
const auto hasRecent = false;
|
||||
if (hasRecent && (_topPeers->selectedByKeyboard() || delta > 1)) {
|
||||
_topPeers->deselectByKeyboard();
|
||||
} else {
|
||||
_topPeers->selectByKeyboard(0);
|
||||
}
|
||||
} else {
|
||||
if (_topPeers->selectedByKeyboard()) {
|
||||
_topPeers->deselectByKeyboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Suggestions::selectSkipPage(int height, int direction) {
|
||||
if (_topPeers->selectedByKeyboard()) {
|
||||
_topPeers->deselectByKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
void Suggestions::chooseRow() {
|
||||
if (_topPeers->chooseRow()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Suggestions::selectLeft() {
|
||||
_topPeers->selectLeft();
|
||||
}
|
||||
|
||||
void Suggestions::selectRight() {
|
||||
_topPeers->selectRight();
|
||||
}
|
||||
|
||||
void Suggestions::paintEvent(QPaintEvent *e) {
|
||||
QPainter(this).fillRect(e->rect(), st::windowBg);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,12 @@ public:
|
|||
rpl::producer<TopPeersList> topPeers);
|
||||
~Suggestions();
|
||||
|
||||
void selectSkip(int delta);
|
||||
void selectSkipPage(int height, int direction);
|
||||
void selectLeft();
|
||||
void selectRight();
|
||||
void chooseRow();
|
||||
|
||||
[[nodiscard]] rpl::producer<PeerId> topPeerChosen() const {
|
||||
return _topPeerChosen.events();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,11 @@ void TopPeersStrip::wheelEvent(QWheelEvent *e) {
|
|||
e->accept();
|
||||
}
|
||||
|
||||
void TopPeersStrip::leaveEventHook(QEvent *e) {
|
||||
setSelected(-1);
|
||||
_selectionByKeyboard = false;
|
||||
}
|
||||
|
||||
void TopPeersStrip::mousePressEvent(QMouseEvent *e) {
|
||||
if (e->button() != Qt::LeftButton) {
|
||||
return;
|
||||
|
@ -123,7 +128,11 @@ void TopPeersStrip::mousePressEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void TopPeersStrip::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_lastMousePosition == e->globalPos() && _selectionByKeyboard) {
|
||||
return;
|
||||
}
|
||||
_lastMousePosition = e->globalPos();
|
||||
_selectionByKeyboard = false;
|
||||
updateSelected();
|
||||
|
||||
if (!_dragging && _mouseDownPosition) {
|
||||
|
@ -259,6 +268,58 @@ void TopPeersStrip::removeLocally(uint64 id) {
|
|||
update();
|
||||
}
|
||||
|
||||
bool TopPeersStrip::selectedByKeyboard() const {
|
||||
return _selectionByKeyboard && _selected >= 0;
|
||||
}
|
||||
|
||||
void TopPeersStrip::selectByKeyboard(int delta) {
|
||||
if (_entries.empty()) {
|
||||
return;
|
||||
}
|
||||
_selectionByKeyboard = true;
|
||||
if (!delta) {
|
||||
if (_selected < 0) {
|
||||
setSelected(0);
|
||||
scrollToSelected();
|
||||
}
|
||||
return;
|
||||
}
|
||||
setSelected(std::clamp(_selected + delta, 0, int(_entries.size()) - 1));
|
||||
scrollToSelected();
|
||||
}
|
||||
|
||||
void TopPeersStrip::deselectByKeyboard() {
|
||||
if (_selectionByKeyboard) {
|
||||
_selectionByKeyboard = false;
|
||||
setSelected(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void TopPeersStrip::selectLeft() {
|
||||
if (_selected > 0) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(_selected - 1);
|
||||
scrollToSelected();
|
||||
}
|
||||
}
|
||||
|
||||
void TopPeersStrip::selectRight() {
|
||||
if (_selected + 1 < _entries.size()) {
|
||||
_selectionByKeyboard = true;
|
||||
setSelected(_selected + 1);
|
||||
scrollToSelected();
|
||||
}
|
||||
}
|
||||
|
||||
bool TopPeersStrip::chooseRow() {
|
||||
if (_selected >= 0) {
|
||||
Assert(_selected < _entries.size());
|
||||
_clicks.fire_copy(_entries[_selected].id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TopPeersStrip::apply(const TopPeersList &list) {
|
||||
auto now = std::vector<Entry>();
|
||||
|
||||
|
@ -542,9 +603,10 @@ void TopPeersStrip::updateSelected() {
|
|||
const auto x = p.x();
|
||||
const auto single = st.photoLeft * 2 + st.photo;
|
||||
const auto index = (_scrollLeft + x) / single;
|
||||
const auto selected = (index < 0 || index >= _entries.size())
|
||||
? -1
|
||||
: index;
|
||||
setSelected((index < 0 || index >= _entries.size()) ? -1 : index);
|
||||
}
|
||||
|
||||
void TopPeersStrip::setSelected(int selected) {
|
||||
if (_selected != selected) {
|
||||
const auto over = (selected >= 0);
|
||||
if (over != (_selected >= 0)) {
|
||||
|
@ -555,4 +617,19 @@ void TopPeersStrip::updateSelected() {
|
|||
}
|
||||
}
|
||||
|
||||
void TopPeersStrip::scrollToSelected() {
|
||||
if (_selected < 0) {
|
||||
return;
|
||||
}
|
||||
const auto &st = st::topPeers;
|
||||
const auto single = st.photoLeft * 2 + st.photo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
|
|
|
@ -52,6 +52,13 @@ public:
|
|||
|
||||
void removeLocally(uint64 id);
|
||||
|
||||
[[nodiscard]] bool selectedByKeyboard() const;
|
||||
void selectByKeyboard(int delta);
|
||||
void selectLeft();
|
||||
void selectRight();
|
||||
void deselectByKeyboard();
|
||||
bool chooseRow();
|
||||
|
||||
private:
|
||||
struct Entry;
|
||||
|
||||
|
@ -62,9 +69,12 @@ private:
|
|||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
void leaveEventHook(QEvent *e) override;
|
||||
|
||||
void updateScrollMax();
|
||||
void updateSelected();
|
||||
void setSelected(int selected);
|
||||
void scrollToSelected();
|
||||
void checkDragging();
|
||||
bool finishDragging();
|
||||
void subscribeUserpic(Entry &entry);
|
||||
|
@ -94,6 +104,7 @@ private:
|
|||
|
||||
int _selected = -1;
|
||||
int _pressed = -1;
|
||||
bool _selectionByKeyboard = false;
|
||||
|
||||
Ui::RoundRect _selection;
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
|
|
Loading…
Add table
Reference in a new issue