From 607655941d60551b2b48039164089caf6aab958e Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 19 Apr 2019 11:35:35 +0400 Subject: [PATCH] Improve Ui::Menu interface. --- .../dialogs/dialogs_inner_widget.cpp | 8 +++- .../admin_log/history_admin_log_inner.cpp | 2 +- .../history/history_inner_widget.cpp | 2 +- .../history/view/history_view_list_widget.cpp | 2 +- .../SourceFiles/ui/widgets/dropdown_menu.cpp | 8 ++-- .../SourceFiles/ui/widgets/dropdown_menu.h | 9 ++-- Telegram/SourceFiles/ui/widgets/labels.cpp | 2 +- Telegram/SourceFiles/ui/widgets/menu.cpp | 48 ++++++++++--------- Telegram/SourceFiles/ui/widgets/menu.h | 15 +++--- .../SourceFiles/ui/widgets/popup_menu.cpp | 10 ++-- Telegram/SourceFiles/ui/widgets/popup_menu.h | 9 ++-- 11 files changed, 60 insertions(+), 55 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index dfc69f7db..49364276f 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -1616,8 +1616,12 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { selectByMouse(globalPosition); } }); - _menu->popup(e->globalPos()); - e->accept(); + if (_menu->actions().empty()) { + _menu = nullptr; + } else { + _menu->popup(e->globalPos()); + e->accept(); + } } void DialogsInner::onParentGeometryChanged() { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 5e22d2b50..f0b0171c6 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -1065,7 +1065,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } - if (_menu->actions().isEmpty()) { + if (_menu->actions().empty()) { _menu = nullptr; } else { _menu->popup(e->globalPos()); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 8af07d706..203f5af7e 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1782,7 +1782,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } - if (_menu->actions().isEmpty()) { + if (_menu->actions().empty()) { _menu = nullptr; } else { _menu->popup(e->globalPos()); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 2ea577fcb..018e8bf15 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -1614,7 +1614,7 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { _overState)); _menu = FillContextMenu(this, request); - if (_menu && !_menu->actions().isEmpty()) { + if (_menu && !_menu->actions().empty()) { _menu->popup(e->globalPos()); e->accept(); } else if (_menu) { diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp index 5a6477ac5..46cf75c1e 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.cpp @@ -51,15 +51,15 @@ void DropdownMenu::init() { hide(); } -QAction *DropdownMenu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { +not_null DropdownMenu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { return _menu->addAction(text, receiver, member, icon, iconOver); } -QAction *DropdownMenu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { +not_null DropdownMenu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { return _menu->addAction(text, std::move(callback), icon, iconOver); } -QAction *DropdownMenu::addSeparator() { +not_null DropdownMenu::addSeparator() { return _menu->addSeparator(); } @@ -70,7 +70,7 @@ void DropdownMenu::clearActions() { return _menu->clearActions(); } -DropdownMenu::Actions &DropdownMenu::actions() { +const std::vector> &DropdownMenu::actions() const { return _menu->actions(); } diff --git a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h index a9ab80cca..759f95e53 100644 --- a/Telegram/SourceFiles/ui/widgets/dropdown_menu.h +++ b/Telegram/SourceFiles/ui/widgets/dropdown_menu.h @@ -19,17 +19,16 @@ class DropdownMenu : public InnerDropdown { public: DropdownMenu(QWidget *parent, const style::DropdownMenu &st = st::defaultDropdownMenu); - QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addSeparator(); + not_null addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addSeparator(); void clearActions(); void setHiddenCallback(Fn callback) { _hiddenCallback = std::move(callback); } - using Actions = Ui::Menu::Actions; - Actions &actions(); + const std::vector> &actions() const; ~DropdownMenu(); diff --git a/Telegram/SourceFiles/ui/widgets/labels.cpp b/Telegram/SourceFiles/ui/widgets/labels.cpp index d5ef9184c..deb6cd0fe 100644 --- a/Telegram/SourceFiles/ui/widgets/labels.cpp +++ b/Telegram/SourceFiles/ui/widgets/labels.cpp @@ -557,7 +557,7 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason) } } - if (_contextMenu->actions().isEmpty()) { + if (_contextMenu->actions().empty()) { delete _contextMenu; _contextMenu = nullptr; } else { diff --git a/Telegram/SourceFiles/ui/widgets/menu.cpp b/Telegram/SourceFiles/ui/widgets/menu.cpp index 24c232099..6e42b7c0d 100644 --- a/Telegram/SourceFiles/ui/widgets/menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/menu.cpp @@ -43,30 +43,28 @@ void Menu::init() { setAttribute(Qt::WA_OpaquePaintEvent); } -QAction *Menu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { - auto action = addAction(new QAction(text, this), icon, iconOver); +not_null Menu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { + const auto action = addAction(new QAction(text, this), icon, iconOver); connect(action, SIGNAL(triggered(bool)), receiver, member, Qt::QueuedConnection); return action; } -QAction *Menu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { - auto action = addAction(new QAction(text, this), icon, iconOver); +not_null Menu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { + const auto action = addAction(new QAction(text, this), icon, iconOver); connect(action, &QAction::triggered, action, std::move(callback), Qt::QueuedConnection); return action; } -QAction *Menu::addAction(QAction *action, const style::icon *icon, const style::icon *iconOver) { +not_null Menu::addAction(not_null action, const style::icon *icon, const style::icon *iconOver) { connect(action, SIGNAL(changed()), this, SLOT(actionChanged())); - _actions.push_back(action); - - auto createData = [icon, iconOver, action] { + _actions.emplace_back(action); + _actionsData.push_back([&] { auto data = ActionData(); data.icon = icon; data.iconOver = iconOver ? iconOver : icon; data.hasSubmenu = (action->menu() != nullptr); return data; - }; - _actionsData.push_back(createData()); + }()); auto newWidth = qMax(width(), _st.widthMin); newWidth = processAction(action, _actions.size() - 1, newWidth); @@ -81,8 +79,8 @@ QAction *Menu::addAction(QAction *action, const style::icon *icon, const style:: return action; } -QAction *Menu::addSeparator() { - auto separator = new QAction(this); +not_null Menu::addSeparator() { + const auto separator = new QAction(this); separator->setSeparator(true); return addAction(separator); } @@ -113,7 +111,7 @@ void Menu::finishAnimating() { } } -int Menu::processAction(QAction *action, int index, int width) { +int Menu::processAction(not_null action, int index, int width) { auto &data = _actionsData[index]; if (action->isSeparator() || action->text().isEmpty()) { data.text = data.shortcut = QString(); @@ -149,10 +147,10 @@ int Menu::processAction(QAction *action, int index, int width) { void Menu::setShowSource(TriggeredSource source) { _mouseSelection = (source == TriggeredSource::Mouse); - setSelected((source == TriggeredSource::Mouse || _actions.isEmpty()) ? -1 : 0); + setSelected((source == TriggeredSource::Mouse || _actions.empty()) ? -1 : 0); } -Menu::Actions &Menu::actions() { +const std::vector> &Menu::actions() const { return _actions; } @@ -163,8 +161,9 @@ void Menu::setForceWidth(int forceWidth) { void Menu::actionChanged() { auto newWidth = _st.widthMin; - for (auto i = 0, count = _actions.size(); i != count; ++i) { - newWidth = processAction(_actions[i], i, newWidth); + auto index = 0; + for (const auto action : _actions) { + newWidth = processAction(action, index++, newWidth); } if (newWidth != width() && !_forceWidth) { resize(newWidth, height()); @@ -188,10 +187,10 @@ void Menu::paintEvent(QPaintEvent *e) { int top = _st.skip; p.translate(0, top); p.setFont(_st.itemFont); - for (int i = 0, count = _actions.size(); i != count; ++i) { + for (int i = 0, count = int(_actions.size()); i != count; ++i) { if (clip.top() + clip.height() <= top) break; - auto action = _actions[i]; + const auto action = _actions[i]; auto &data = _actionsData[i]; auto actionHeight = action->isSeparator() ? _separatorHeight : _itemHeight; top += actionHeight; @@ -300,12 +299,14 @@ void Menu::handleKeyPress(int key) { if (_selected >= 0 && _actionsData[_selected].hasSubmenu) { itemPressed(TriggeredSource::Keyboard); return; - } else if (_selected < 0 && !_actions.isEmpty()) { + } else if (_selected < 0 && !_actions.empty()) { _mouseSelection = false; setSelected(0); } } - if ((key != Qt::Key_Up && key != Qt::Key_Down) || _actions.size() < 1) return; + if ((key != Qt::Key_Up && key != Qt::Key_Down) || _actions.empty()) { + return; + } auto delta = (key == Qt::Key_Down ? 1 : -1), start = _selected; if (start < 0 || start >= _actions.size()) { @@ -367,7 +368,10 @@ void Menu::setSelected(int selected) { updateSelectedItem(); if (_activatedCallback) { auto source = _mouseSelection ? TriggeredSource::Mouse : TriggeredSource::Keyboard; - _activatedCallback((_selected >= 0) ? _actions[_selected] : nullptr, itemTop(_selected), source); + _activatedCallback( + (_selected >= 0) ? _actions[_selected].get() : nullptr, + itemTop(_selected), + source); } } } diff --git a/Telegram/SourceFiles/ui/widgets/menu.h b/Telegram/SourceFiles/ui/widgets/menu.h index 3a995b7a8..34e249fa7 100644 --- a/Telegram/SourceFiles/ui/widgets/menu.h +++ b/Telegram/SourceFiles/ui/widgets/menu.h @@ -21,9 +21,9 @@ public: Menu(QWidget *parent, const style::Menu &st = st::defaultMenu); Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu); - QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addSeparator(); + not_null addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addSeparator(); void clearActions(); void finishAnimating(); @@ -39,8 +39,7 @@ public: void setShowSource(TriggeredSource source); void setForceWidth(int forceWidth); - using Actions = QList; - Actions &actions(); + const std::vector> &actions() const; void setResizedCallback(Fn callback) { _resizedCallback = std::move(callback); @@ -107,8 +106,8 @@ private: void init(); // Returns the new width. - int processAction(QAction *action, int index, int width); - QAction *addAction(QAction *a, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + int processAction(not_null action, int index, int width); + not_null addAction(not_null action, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); void setSelected(int selected); void setPressed(int pressed); @@ -131,7 +130,7 @@ private: Fn _mouseReleaseDelegate; QMenu *_wappedMenu = nullptr; - Actions _actions; + std::vector> _actions; std::vector _actionsData; int _forceWidth = 0; diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp index 8395caa87..ab9b72468 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.cpp +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.cpp @@ -91,26 +91,26 @@ void PopupMenu::handleMenuResize() { _inner = rect().marginsRemoved(_padding); } -QAction *PopupMenu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { +not_null PopupMenu::addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon, const style::icon *iconOver) { return _menu->addAction(text, receiver, member, icon, iconOver); } -QAction *PopupMenu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { +not_null PopupMenu::addAction(const QString &text, Fn callback, const style::icon *icon, const style::icon *iconOver) { return _menu->addAction(text, std::move(callback), icon, iconOver); } -QAction *PopupMenu::addSeparator() { +not_null PopupMenu::addSeparator() { return _menu->addSeparator(); } void PopupMenu::clearActions() { - for (auto submenu : base::take(_submenus)) { + for (const auto &submenu : base::take(_submenus)) { delete submenu; } return _menu->clearActions(); } -PopupMenu::Actions &PopupMenu::actions() { +const std::vector> &PopupMenu::actions() const { return _menu->actions(); } diff --git a/Telegram/SourceFiles/ui/widgets/popup_menu.h b/Telegram/SourceFiles/ui/widgets/popup_menu.h index 6126b4317..add2722ea 100644 --- a/Telegram/SourceFiles/ui/widgets/popup_menu.h +++ b/Telegram/SourceFiles/ui/widgets/popup_menu.h @@ -20,13 +20,12 @@ public: PopupMenu(QWidget *parent, const style::PopupMenu &st = st::defaultPopupMenu); PopupMenu(QWidget *parent, QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu); - QAction *addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); - QAction *addSeparator(); + not_null addAction(const QString &text, const QObject *receiver, const char* member, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addAction(const QString &text, Fn callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr); + not_null addSeparator(); void clearActions(); - using Actions = Ui::Menu::Actions; - Actions &actions(); + const std::vector> &actions() const; void deleteOnHide(bool del); void popup(const QPoint &p);