Allow inserting actions in the middle of Menu.

This commit is contained in:
John Preston 2022-08-31 17:50:54 +04:00
parent 4d45396174
commit a5766cb1f6
4 changed files with 36 additions and 18 deletions

View file

@ -94,21 +94,30 @@ not_null<QAction*> Menu::addAction(
} }
not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) { not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
const auto action = widget->action(); return insertAction(_actions.size(), std::move(widget));
_actions.emplace_back(action); }
widget->setParent(this); not_null<QAction*> Menu::insertAction(
int position,
base::unique_qptr<ItemBase> widget) {
Expects(position >= 0 && position <= _actions.size());
Expects(position >= 0 && position <= _actionWidgets.size());
const auto top = _actionWidgets.empty() const auto raw = widget.get();
? 0 const auto action = raw->action();
: _actionWidgets.back()->y() + _actionWidgets.back()->height(); _actions.insert(begin(_actions) + position, action);
widget->moveToLeft(0, top); raw->setParent(this);
widget->show(); raw->show();
raw->setIndex(position);
for (auto i = position, to = int(_actionWidgets.size()); i != to; ++i) {
_actionWidgets[i]->setIndex(i + 1);
}
_actionWidgets.insert(
begin(_actionWidgets) + position,
std::move(widget));
widget->setIndex(_actionWidgets.size()); raw->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() if (!findSelectedAction()
@ -128,16 +137,16 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
if (_activatedCallback) { if (_activatedCallback) {
_activatedCallback(data); _activatedCallback(data);
} }
}, widget->lifetime()); }, raw->lifetime());
widget->clicks( raw->clicks(
) | rpl::start_with_next([=](const CallbackData &data) { ) | rpl::start_with_next([=](const CallbackData &data) {
if (_triggeredCallback) { if (_triggeredCallback) {
_triggeredCallback(data); _triggeredCallback(data);
} }
}, widget->lifetime()); }, raw->lifetime());
QObject::connect(action.get(), &QAction::changed, widget.get(), [=] { QObject::connect(action.get(), &QAction::changed, raw, [=] {
// Select an item under mouse that was disabled and became enabled. // Select an item under mouse that was disabled and became enabled.
if (_lastSelectedByMouse if (_lastSelectedByMouse
&& !findSelectedAction() && !findSelectedAction()
@ -146,9 +155,6 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
} }
}); });
const auto raw = widget.get();
_actionWidgets.push_back(std::move(widget));
const auto recountWidth = [=] { const auto recountWidth = [=] {
return _forceWidth return _forceWidth
? _forceWidth ? _forceWidth

View file

@ -53,6 +53,9 @@ public:
const style::icon *iconOver = nullptr); const style::icon *iconOver = nullptr);
not_null<QAction*> addSeparator( not_null<QAction*> addSeparator(
const style::MenuSeparator *st = nullptr); const style::MenuSeparator *st = nullptr);
not_null<QAction*> insertAction(
int position,
base::unique_qptr<ItemBase> widget);
void clearActions(); void clearActions();
void finishAnimating(); void finishAnimating();

View file

@ -407,6 +407,12 @@ not_null<QAction*> PopupMenu::addSeparator(const style::MenuSeparator *st) {
return _menu->addSeparator(st); return _menu->addSeparator(st);
} }
not_null<QAction*> PopupMenu::insertAction(
int position,
base::unique_qptr<Menu::ItemBase> widget) {
return _menu->insertAction(position, std::move(widget));
}
void PopupMenu::clearActions() { void PopupMenu::clearActions() {
_submenus.clear(); _submenus.clear();
return _menu->clearActions(); return _menu->clearActions();

View file

@ -51,6 +51,9 @@ public:
const style::icon *iconOver = nullptr); const style::icon *iconOver = nullptr);
not_null<QAction*> addSeparator( not_null<QAction*> addSeparator(
const style::MenuSeparator *st = nullptr); const style::MenuSeparator *st = nullptr);
not_null<QAction*> insertAction(
int position,
base::unique_qptr<Menu::ItemBase> widget);
void clearActions(); void clearActions();
[[nodiscard]] const std::vector<not_null<QAction*>> &actions() const; [[nodiscard]] const std::vector<not_null<QAction*>> &actions() const;