Allow enabling + selecting menu item under cursor.

This commit is contained in:
John Preston 2021-09-08 14:36:59 +03:00
parent beb09445d1
commit 02c1bd5674
4 changed files with 22 additions and 5 deletions

View file

@ -110,10 +110,12 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
if (!findSelectedAction() if (!findSelectedAction()
&& data.index < _actionWidgets.size() && data.index < _actionWidgets.size()
&& _childShownAction == data.action) { && _childShownAction == data.action) {
_actionWidgets[data.index]->setSelected(true); const auto widget = _actionWidgets[data.index].get();
widget->setSelected(true, widget->lastTriggeredSource());
} }
return; return;
} }
_lastSelectedByMouse = (data.source == TriggeredSource::Mouse);
for (auto i = 0; i < _actionWidgets.size(); i++) { for (auto i = 0; i < _actionWidgets.size(); i++) {
if (i != data.index) { if (i != data.index) {
_actionWidgets[i]->setSelected(false); _actionWidgets[i]->setSelected(false);
@ -131,6 +133,15 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
} }
}, widget->lifetime()); }, widget->lifetime());
QObject::connect(action.get(), &QAction::changed, widget.get(), [=] {
// Select an item under mouse that was disabled and became enabled.
if (_lastSelectedByMouse
&& !findSelectedAction()
&& action->isEnabled()) {
updateSelected(QCursor::pos());
}
});
const auto raw = widget.get(); const auto raw = widget.get();
_actionWidgets.push_back(std::move(widget)); _actionWidgets.push_back(std::move(widget));
@ -222,6 +233,9 @@ void Menu::updateSelected(QPoint globalPosition) {
for (const auto &widget : _actionWidgets) { for (const auto &widget : _actionWidgets) {
const auto widgetRect = QRect(widget->pos(), widget->size()); const auto widgetRect = QRect(widget->pos(), widget->size());
if (widgetRect.contains(p)) { if (widgetRect.contains(p)) {
_lastSelectedByMouse = true;
// It may actually fail to become selected (if it is disabled).
widget->setSelected(true); widget->setSelected(true);
break; break;
} }
@ -271,7 +285,8 @@ void Menu::handleKeyPress(not_null<QKeyEvent*> e) {
} else if (newSelected >= _actions.size()) { } else if (newSelected >= _actions.size()) {
newSelected -= _actions.size(); newSelected -= _actions.size();
} }
} while (newSelected != start && (!_actionWidgets[newSelected]->isEnabled())); } while (newSelected != start
&& (!_actionWidgets[newSelected]->isEnabled()));
if (_actionWidgets[newSelected]->isEnabled()) { if (_actionWidgets[newSelected]->isEnabled()) {
setSelected(newSelected, false); setSelected(newSelected, false);

View file

@ -120,6 +120,7 @@ private:
std::vector<base::unique_qptr<ItemBase>> _actionWidgets; std::vector<base::unique_qptr<ItemBase>> _actionWidgets;
int _forceWidth = 0; int _forceWidth = 0;
bool _lastSelectedByMouse = false;
QPointer<QAction> _childShownAction; QPointer<QAction> _childShownAction;

View file

@ -84,13 +84,13 @@ bool Action::hasSubmenu() const {
} }
void Action::paint(Painter &p) { void Action::paint(Painter &p) {
const auto enabled = _action->isEnabled(); const auto enabled = isEnabled();
const auto selected = isSelected(); const auto selected = isSelected();
if (selected && _st.itemBgOver->c.alpha() < 255) { if (selected && _st.itemBgOver->c.alpha() < 255) {
p.fillRect(0, 0, width(), _height, _st.itemBg); p.fillRect(0, 0, width(), _height, _st.itemBg);
} }
p.fillRect(0, 0, width(), _height, selected ? _st.itemBgOver : _st.itemBg); p.fillRect(0, 0, width(), _height, selected ? _st.itemBgOver : _st.itemBg);
if (isEnabled()) { if (enabled) {
paintRipple(p, 0, 0); paintRipple(p, 0, 0);
} }
if (const auto icon = (selected ? _iconOver : _icon)) { if (const auto icon = (selected ? _iconOver : _icon)) {
@ -124,6 +124,7 @@ void Action::paint(Painter &p) {
} }
void Action::processAction() { void Action::processAction() {
setPointerCursor(isEnabled());
if (_action->text().isEmpty()) { if (_action->text().isEmpty()) {
_shortcut = QString(); _shortcut = QString();
_text.clear(); _text.clear();

View file

@ -17,7 +17,7 @@ ItemBase::ItemBase(
void ItemBase::setSelected( void ItemBase::setSelected(
bool selected, bool selected,
TriggeredSource source) { TriggeredSource source) {
if (!isEnabled()) { if (selected && !isEnabled()) {
return; return;
} }
if (_selected.current() != selected) { if (_selected.current() != selected) {