Slightly refactored creating new items in menu.

This commit is contained in:
23rd 2021-01-13 03:49:42 +03:00
parent 98fa99ae42
commit df0a8ff589
4 changed files with 95 additions and 63 deletions

View file

@ -53,80 +53,94 @@ void Menu::init() {
}, lifetime());
}
not_null<QAction*> Menu::addAction(const QString &text, Fn<void()> callback, const style::icon *icon, const style::icon *iconOver) {
not_null<QAction*> Menu::addAction(
const QString &text,
Fn<void()> 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);
connect(
action,
&QAction::triggered,
action,
std::move(callback),
Qt::QueuedConnection);
return action;
}
not_null<QAction*> Menu::addAction(const QString &text, std::unique_ptr<QMenu> submenu) {
not_null<QAction*> Menu::addAction(
const QString &text,
std::unique_ptr<QMenu> submenu) {
const auto action = new QAction(text, this);
action->setMenu(submenu.release());
return addAction(action, nullptr, nullptr);
}
not_null<QAction*> Menu::addAction(not_null<QAction*> action, const style::icon *icon, const style::icon *iconOver) {
not_null<QAction*> Menu::addAction(
not_null<QAction*> action,
const style::icon *icon,
const style::icon *iconOver) {
if (action->isSeparator()) {
return addSeparator();
}
auto item = base::make_unique_q<Action>(
this,
_st,
0,
std::move(action),
icon,
iconOver ? iconOver : icon,
(action->menu() != nullptr));
return addAction(std::move(item));
}
not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
const auto action = widget->action();
_actions.emplace_back(action);
const auto top = _actionWidgets.empty()
? 0
: _actionWidgets.back()->y() + _actionWidgets.back()->height();
const auto index = _actionWidgets.size();
if (action->isSeparator()) {
auto widget = base::make_unique_q<Separator>(this, _st, index);
widget->moveToLeft(0, top);
widget->show();
_actionWidgets.push_back(std::move(widget));
} else {
auto widget = base::make_unique_q<Action>(
this,
_st,
index,
action,
icon,
iconOver ? iconOver : icon,
(action->menu() != nullptr));
widget->moveToLeft(0, top);
widget->show();
widget->selects(
) | rpl::start_with_next([=](const CallbackData &data) {
if (!data.selected) {
return;
widget->moveToLeft(0, top);
widget->show();
widget->selects(
) | rpl::start_with_next([=](const CallbackData &data) {
if (!data.selected) {
return;
}
for (auto i = 0; i < _actionWidgets.size(); i++) {
if (i != data.index) {
_actionWidgets[i]->setSelected(false);
}
for (auto i = 0; i < _actionWidgets.size(); i++) {
if (i != data.index) {
_actionWidgets[i]->setSelected(false);
}
}
if (_activatedCallback) {
_activatedCallback(data);
}
}, widget->lifetime());
}
if (_activatedCallback) {
_activatedCallback(data);
}
}, widget->lifetime());
widget->clicks(
) | rpl::start_with_next([=](const CallbackData &data) {
if (_triggeredCallback) {
_triggeredCallback(data);
}
}, widget->lifetime());
widget->clicks(
) | rpl::start_with_next([=](const CallbackData &data) {
if (_triggeredCallback) {
_triggeredCallback(data);
}
}, widget->lifetime());
widget->contentWidthValue(
) | rpl::start_with_next([=] {
const auto newWidth = _forceWidth
? _forceWidth
: _actionWidgets.empty()
? _st.widthMin
: (*ranges::max_element(
_actionWidgets,
std::greater<>(),
&ItemBase::width))->contentWidth();
resize(newWidth, height());
}, widget->lifetime());
_actionWidgets.push_back(std::move(widget));
}
widget->contentWidthValue(
) | rpl::start_with_next([=] {
const auto newWidth = _forceWidth
? _forceWidth
: _actionWidgets.empty()
? _st.widthMin
: (*ranges::max_element(
_actionWidgets,
std::greater<>(),
&ItemBase::width))->contentWidth();
resize(newWidth, height());
}, widget->lifetime());
_actionWidgets.push_back(std::move(widget));
const auto newHeight = ranges::accumulate(
_actionWidgets,
@ -142,7 +156,8 @@ not_null<QAction*> Menu::addAction(not_null<QAction*> action, const style::icon
not_null<QAction*> Menu::addSeparator() {
const auto separator = new QAction(this);
separator->setSeparator(true);
return addAction(separator);
auto item = base::make_unique_q<Separator>(this, _st, 0, separator);
return addAction(std::move(item));
}
void Menu::clearActions() {

View file

@ -25,8 +25,14 @@ public:
Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu);
~Menu();
not_null<QAction*> addAction(const QString &text, Fn<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
not_null<QAction*> addAction(const QString &text, std::unique_ptr<QMenu> submenu);
not_null<QAction*> addAction(
const QString &text,
Fn<void()> callback,
const style::icon *icon = nullptr,
const style::icon *iconOver = nullptr);
not_null<QAction*> addAction(
const QString &text,
std::unique_ptr<QMenu> submenu);
not_null<QAction*> addSeparator();
void clearActions();
void finishAnimating();
@ -80,7 +86,11 @@ private:
void updateSelected(QPoint globalPosition);
void init();
not_null<QAction*> addAction(not_null<QAction*> action, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
not_null<QAction*> addAction(
not_null<QAction*> action,
const style::icon *icon = nullptr,
const style::icon *iconOver = nullptr);
not_null<QAction*> addAction(base::unique_qptr<ItemBase> widget);
void setSelected(int selected);
void clearMouseSelection();

View file

@ -13,13 +13,15 @@ namespace Ui::Menu {
Separator::Separator(
not_null<RpWidget*> parent,
const style::Menu &st,
int index)
int index,
not_null<QAction*> action)
: ItemBase(parent, st, index)
, _lineWidth(st.separatorWidth)
, _padding(st.separatorPadding)
, _fg(st.separatorFg)
, _bg(st.itemBg)
, _height(_padding.top() + _lineWidth + _padding.bottom()) {
, _height(_padding.top() + _lineWidth + _padding.bottom())
, _action(action) {
initResizeHook(parent->sizeValue());
paintRequest(
@ -37,7 +39,7 @@ Separator::Separator(
}
QAction *Separator::action() const {
return nullptr;
return _action;
}
bool Separator::isEnabled() const {

View file

@ -15,7 +15,11 @@ namespace Ui::Menu {
class Separator : public ItemBase {
public:
Separator(not_null<RpWidget*> parent, const style::Menu &st, int index);
Separator(
not_null<RpWidget*> parent,
const style::Menu &st,
int index,
not_null<QAction*> action);
QAction *action() const override;
bool isEnabled() const override;
@ -29,6 +33,7 @@ private:
const style::color &_fg;
const style::color &_bg;
const int _height;
const not_null<QAction*> _action;
};