Scroll to the item selected by keyboard.

This commit is contained in:
John Preston 2021-09-09 16:02:26 +03:00
parent 40c0a11705
commit 52718aa5db
3 changed files with 30 additions and 2 deletions

View file

@ -9,6 +9,7 @@
#include "ui/widgets/menu/menu_action.h"
#include "ui/widgets/menu/menu_item_base.h"
#include "ui/widgets/menu/menu_separator.h"
#include "ui/widgets/scroll_area.h"
#include <QtGui/QtEvents>
@ -212,6 +213,10 @@ rpl::producer<> Menu::resizesFromInner() const {
return _resizesFromInner.events();
}
rpl::producer<ScrollToRequest> Menu::scrollToRequests() const {
return _scrollToRequests.events();
}
void Menu::setShowSource(TriggeredSource source) {
const auto mouseSelection = (source == TriggeredSource::Mouse);
setSelected(
@ -314,6 +319,13 @@ void Menu::setSelected(int selected, bool isMouseSelection) {
const auto source = isMouseSelection
? TriggeredSource::Mouse
: TriggeredSource::Keyboard;
if (selected >= 0 && source == TriggeredSource::Keyboard) {
const auto widget = _actionWidgets[selected].get();
_scrollToRequests.fire({
widget->y(),
widget->y() + widget->height(),
});
}
if (const auto selectedItem = findSelectedAction()) {
if (selectedItem->index() == selected) {
return;
@ -321,7 +333,7 @@ void Menu::setSelected(int selected, bool isMouseSelection) {
selectedItem->setSelected(false, source);
}
if (selected >= 0) {
_actionWidgets[selected]->setSelected(true, source);
_actionWidgets[selected].get()->setSelected(true, source);
}
}

View file

@ -13,6 +13,10 @@
#include <QtWidgets/QMenu>
namespace Ui {
struct ScrollToRequest;
} // namespace Ui
namespace Ui::Menu {
class ItemBase;
@ -82,7 +86,8 @@ public:
}
void handleMouseRelease(QPoint globalPosition);
rpl::producer<> resizesFromInner() const;
[[nodiscard]] rpl::producer<> resizesFromInner() const;
[[nodiscard]] rpl::producer<ScrollToRequest> scrollToRequests() const;
protected:
void keyPressEvent(QKeyEvent *e) override;
@ -125,6 +130,7 @@ private:
QPointer<QAction> _childShownAction;
rpl::event_stream<> _resizesFromInner;
rpl::event_stream<ScrollToRequest> _scrollToRequests;
};

View file

@ -222,6 +222,16 @@ void PopupMenu::init() {
}
}, paddingWrap->lifetime());
_menu->scrollToRequests(
) | rpl::start_with_next([=](ScrollToRequest request) {
_scroll->scrollTo({
request.ymin ? (_st.scrollPadding.top() + request.ymin) : 0,
(request.ymax == _menu->height()
? paddingWrap->height()
: (_st.scrollPadding.top() + request.ymax)),
});
}, _menu->lifetime());
_menu->resizesFromInner(
) | rpl::start_with_next([=] {
handleMenuResize();