Force PopupMenu item selection when submenu is shown.
This commit is contained in:
parent
6651d9f9b6
commit
f4cf3094c2
5 changed files with 50 additions and 27 deletions
|
|
@ -107,6 +107,11 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
|
||||||
widget->selects(
|
widget->selects(
|
||||||
) | rpl::start_with_next([=](const CallbackData &data) {
|
) | rpl::start_with_next([=](const CallbackData &data) {
|
||||||
if (!data.selected) {
|
if (!data.selected) {
|
||||||
|
if (!findSelectedAction()
|
||||||
|
&& data.index < _actionWidgets.size()
|
||||||
|
&& _childShownAction == data.action) {
|
||||||
|
_actionWidgets[data.index]->setSelected(true);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto i = 0; i < _actionWidgets.size(); i++) {
|
for (auto i = 0; i < _actionWidgets.size(); i++) {
|
||||||
|
|
@ -282,7 +287,7 @@ void Menu::clearMouseSelection() {
|
||||||
const auto mouseSelection = selected
|
const auto mouseSelection = selected
|
||||||
? (selected->lastTriggeredSource() == TriggeredSource::Mouse)
|
? (selected->lastTriggeredSource() == TriggeredSource::Mouse)
|
||||||
: false;
|
: false;
|
||||||
if (mouseSelection && !_childShown) {
|
if (mouseSelection && !_childShownAction) {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ public:
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
|
|
||||||
void setChildShown(bool shown) {
|
void setChildShownAction(QAction *action) {
|
||||||
_childShown = shown;
|
_childShownAction = action;
|
||||||
}
|
}
|
||||||
void setShowSource(TriggeredSource source);
|
void setShowSource(TriggeredSource source);
|
||||||
void setForceWidth(int forceWidth);
|
void setForceWidth(int forceWidth);
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
_triggeredCallback = std::move(callback);
|
_triggeredCallback = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ItemBase *findSelectedAction() const;
|
||||||
|
|
||||||
void setKeyPressDelegate(Fn<bool(int key)> delegate) {
|
void setKeyPressDelegate(Fn<bool(int key)> delegate) {
|
||||||
_keyPressDelegate = std::move(delegate);
|
_keyPressDelegate = std::move(delegate);
|
||||||
}
|
}
|
||||||
|
|
@ -102,8 +104,6 @@ private:
|
||||||
|
|
||||||
void itemPressed(TriggeredSource source);
|
void itemPressed(TriggeredSource source);
|
||||||
|
|
||||||
ItemBase *findSelectedAction() const;
|
|
||||||
|
|
||||||
void resizeFromInner(int w, int h);
|
void resizeFromInner(int w, int h);
|
||||||
|
|
||||||
const style::Menu &_st;
|
const style::Menu &_st;
|
||||||
|
|
@ -121,7 +121,7 @@ private:
|
||||||
|
|
||||||
int _forceWidth = 0;
|
int _forceWidth = 0;
|
||||||
|
|
||||||
bool _childShown = false;
|
QPointer<QAction> _childShownAction;
|
||||||
|
|
||||||
rpl::event_stream<> _resizesFromInner;
|
rpl::event_stream<> _resizesFromInner;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,12 +189,6 @@ void Action::handleKeyPress(not_null<QKeyEvent*> e) {
|
||||||
setClicked(TriggeredSource::Keyboard);
|
setClicked(TriggeredSource::Keyboard);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (key == (style::RightToLeft() ? Qt::Key_Left : Qt::Key_Right)) {
|
|
||||||
if (hasSubmenu()) {
|
|
||||||
setClicked(TriggeredSource::Keyboard);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Ui::Menu
|
} // namespace Ui::Menu
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
#include "ui/platform/ui_platform_utility.h"
|
#include "ui/platform/ui_platform_utility.h"
|
||||||
|
#include "ui/widgets/menu//menu_item_base.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/delayed_activation.h"
|
#include "ui/delayed_activation.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
|
|
@ -98,7 +99,22 @@ not_null<PopupMenu*> PopupMenu::ensureSubmenu(not_null<QAction*> action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::removeSubmenu(not_null<QAction*> action) {
|
void PopupMenu::removeSubmenu(not_null<QAction*> action) {
|
||||||
_submenus.remove(action);
|
const auto menu = _submenus.take(action);
|
||||||
|
if (menu && menu->get() == _activeSubmenu) {
|
||||||
|
base::take(_activeSubmenu)->hideMenu(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupMenu::checkSubmenuShow() {
|
||||||
|
if (_activeSubmenu) {
|
||||||
|
return;
|
||||||
|
} else if (const auto item = _menu->findSelectedAction()) {
|
||||||
|
if (item->lastTriggeredSource() == Menu::TriggeredSource::Mouse) {
|
||||||
|
if (_submenus.contains(item->action())) {
|
||||||
|
item->setClicked(Menu::TriggeredSource::Mouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::handleCompositingUpdate() {
|
void PopupMenu::handleCompositingUpdate() {
|
||||||
|
|
@ -211,24 +227,24 @@ void PopupMenu::handleTriggered(const Menu::CallbackData &data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PopupMenu::popupSubmenuFromAction(const Menu::CallbackData &data) {
|
bool PopupMenu::popupSubmenuFromAction(const Menu::CallbackData &data) {
|
||||||
|
if (!data.action) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (const auto i = _submenus.find(data.action); i != end(_submenus)) {
|
if (const auto i = _submenus.find(data.action); i != end(_submenus)) {
|
||||||
const auto submenu = i->second.get();
|
const auto submenu = i->second.get();
|
||||||
if (_activeSubmenu == submenu) {
|
if (_activeSubmenu != submenu) {
|
||||||
// There is a strange problem on macOS
|
popupSubmenu(data.action, submenu, data.actionTop, data.source);
|
||||||
// when a submenu closes arbitrarily
|
|
||||||
// if we try to move the cursor to it.
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
submenu->hideMenu(true);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
popupSubmenu(submenu, data.actionTop, data.source);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::popupSubmenu(not_null<PopupMenu*> submenu, int actionTop, TriggeredSource source) {
|
void PopupMenu::popupSubmenu(
|
||||||
|
not_null<QAction*> action,
|
||||||
|
not_null<PopupMenu*> submenu,
|
||||||
|
int actionTop,
|
||||||
|
TriggeredSource source) {
|
||||||
if (auto currentSubmenu = base::take(_activeSubmenu)) {
|
if (auto currentSubmenu = base::take(_activeSubmenu)) {
|
||||||
currentSubmenu->hideMenu(true);
|
currentSubmenu->hideMenu(true);
|
||||||
}
|
}
|
||||||
|
|
@ -236,10 +252,7 @@ void PopupMenu::popupSubmenu(not_null<PopupMenu*> submenu, int actionTop, Trigge
|
||||||
QPoint p(_inner.x() + (style::RightToLeft() ? _padding.right() : _inner.width() - _padding.left()), _inner.y() + actionTop);
|
QPoint p(_inner.x() + (style::RightToLeft() ? _padding.right() : _inner.width() - _padding.left()), _inner.y() + actionTop);
|
||||||
_activeSubmenu = submenu;
|
_activeSubmenu = submenu;
|
||||||
_activeSubmenu->showMenu(geometry().topLeft() + p, this, source);
|
_activeSubmenu->showMenu(geometry().topLeft() + p, this, source);
|
||||||
|
_menu->setChildShownAction(action);
|
||||||
_menu->setChildShown(true);
|
|
||||||
} else {
|
|
||||||
_menu->setChildShown(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,6 +274,12 @@ bool PopupMenu::handleKeyPress(int key) {
|
||||||
hideMenu(true);
|
hideMenu(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (key == (style::RightToLeft() ? Qt::Key_Left : Qt::Key_Right)) {
|
||||||
|
if (const auto item = _menu->findSelectedAction()) {
|
||||||
|
if (_submenus.contains(item->action())) {
|
||||||
|
item->setClicked(Menu::TriggeredSource::Keyboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -337,6 +356,9 @@ void PopupMenu::childHiding(PopupMenu *child) {
|
||||||
if (_activeSubmenu && _activeSubmenu == child) {
|
if (_activeSubmenu && _activeSubmenu == child) {
|
||||||
_activeSubmenu = nullptr;
|
_activeSubmenu = nullptr;
|
||||||
}
|
}
|
||||||
|
if (!_activeSubmenu) {
|
||||||
|
_menu->setChildShownAction(nullptr);
|
||||||
|
}
|
||||||
if (!_hiding && !isHidden()) {
|
if (!_hiding && !isHidden()) {
|
||||||
raise();
|
raise();
|
||||||
activateWindow();
|
activateWindow();
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public:
|
||||||
[[nodiscard]] not_null<PopupMenu*> ensureSubmenu(
|
[[nodiscard]] not_null<PopupMenu*> ensureSubmenu(
|
||||||
not_null<QAction*> action);
|
not_null<QAction*> action);
|
||||||
void removeSubmenu(not_null<QAction*> action);
|
void removeSubmenu(not_null<QAction*> action);
|
||||||
|
void checkSubmenuShow();
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
void deleteOnHide(bool del);
|
void deleteOnHide(bool del);
|
||||||
|
|
@ -107,6 +108,7 @@ private:
|
||||||
|
|
||||||
bool popupSubmenuFromAction(const Menu::CallbackData &data);
|
bool popupSubmenuFromAction(const Menu::CallbackData &data);
|
||||||
void popupSubmenu(
|
void popupSubmenu(
|
||||||
|
not_null<QAction*> action,
|
||||||
not_null<PopupMenu*> submenu,
|
not_null<PopupMenu*> submenu,
|
||||||
int actionTop,
|
int actionTop,
|
||||||
TriggeredSource source);
|
TriggeredSource source);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue