From 5e37c06a6ad8f2cfe66687dd5e3577daa830cdf2 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 13 Jan 2021 18:58:09 +0300 Subject: [PATCH] Added action menu item with toggle view. --- CMakeLists.txt | 3 ++ ui/widgets/menu/menu.cpp | 25 +----------- ui/widgets/menu/menu.h | 1 - ui/widgets/menu/menu_action.cpp | 13 +----- ui/widgets/menu/menu_common.cpp | 27 +++++++++++++ ui/widgets/menu/menu_common.h | 5 +++ ui/widgets/menu/menu_toggle.cpp | 70 +++++++++++++++++++++++++++++++++ ui/widgets/menu/menu_toggle.h | 40 +++++++++++++++++++ 8 files changed, 148 insertions(+), 36 deletions(-) create mode 100644 ui/widgets/menu/menu_common.cpp create mode 100644 ui/widgets/menu/menu_toggle.cpp create mode 100644 ui/widgets/menu/menu_toggle.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0068c4c..56b575a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,11 +150,14 @@ PRIVATE ui/widgets/menu/menu.h ui/widgets/menu/menu_action.cpp ui/widgets/menu/menu_action.h + ui/widgets/menu/menu_common.cpp ui/widgets/menu/menu_common.h ui/widgets/menu/menu_item_base.cpp ui/widgets/menu/menu_item_base.h ui/widgets/menu/menu_separator.cpp ui/widgets/menu/menu_separator.h + ui/widgets/menu/menu_toggle.cpp + ui/widgets/menu/menu_toggle.h ui/widgets/popup_menu.cpp ui/widgets/popup_menu.h ui/widgets/scroll_area.cpp diff --git a/ui/widgets/menu/menu.cpp b/ui/widgets/menu/menu.cpp index 246f565..95eb817 100644 --- a/ui/widgets/menu/menu.cpp +++ b/ui/widgets/menu/menu.cpp @@ -58,14 +58,8 @@ not_null Menu::addAction( 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; + auto action = CreateAction(this, text, std::move(callback)); + return addAction(std::move(action), icon, iconOver); } not_null Menu::addAction( @@ -288,10 +282,6 @@ void Menu::setSelected(int selected) { const auto source = _mouseSelection ? TriggeredSource::Mouse : TriggeredSource::Keyboard; - // updateSelectedItem(); - // if (_selected >= 0 && _selected != _pressed && _actionsData[_selected].toggle) { - // _actionsData[_selected].toggle->setStyle(_st.itemToggle); - // } if (_selected >= 0) { _actionWidgets[_selected]->setSelected(false, source); } @@ -299,17 +289,6 @@ void Menu::setSelected(int selected) { if (_selected >= 0) { _actionWidgets[_selected]->setSelected(true, source); } - // if (_selected >= 0 && _actionsData[_selected].toggle && _actions[_selected]->isEnabled()) { - // _actionsData[_selected].toggle->setStyle(_st.itemToggleOver); - // } - // updateSelectedItem(); - // if (_activatedCallback) { - // auto source = _mouseSelection ? TriggeredSource::Mouse : TriggeredSource::Keyboard; - // _activatedCallback( - // (_selected >= 0) ? _actions[_selected].get() : nullptr, - // itemTop(_selected), - // source); - // } } } diff --git a/ui/widgets/menu/menu.h b/ui/widgets/menu/menu.h index 27adde3..10051ac 100644 --- a/ui/widgets/menu/menu.h +++ b/ui/widgets/menu/menu.h @@ -16,7 +16,6 @@ namespace Ui::Menu { class ItemBase; -//class ToggleView; class RippleAnimation; class Menu : public RpWidget { diff --git a/ui/widgets/menu/menu_action.cpp b/ui/widgets/menu/menu_action.cpp index ba37e58..2a9241a 100644 --- a/ui/widgets/menu/menu_action.cpp +++ b/ui/widgets/menu/menu_action.cpp @@ -161,18 +161,7 @@ void Action::processAction() { + textWidth + padding.right() + additionalWidth; - // if (action->isCheckable()) { - // auto updateCallback = [this, index] { updateItem(index); }; - // if (_toggle) { - // _toggle->setUpdateCallback(updateCallback); - // _toggle->setChecked(action->isChecked(), anim::type::normal); - // } else { - // _toggle = std::make_unique(_st.itemToggle, action->isChecked(), updateCallback); - // } - // goodWidth += _st.itemPadding.right() + _toggle->getSize().width() - _st.itemToggleShift; - // } else { - // _toggle.reset(); - // } + const auto w = std::clamp(goodWidth, _st.widthMin, _st.widthMax); _textWidth = w - (goodWidth - textWidth); _shortcut = actionShortcut; diff --git a/ui/widgets/menu/menu_common.cpp b/ui/widgets/menu/menu_common.cpp new file mode 100644 index 0000000..7e29038 --- /dev/null +++ b/ui/widgets/menu/menu_common.cpp @@ -0,0 +1,27 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/widgets/menu/menu_common.h" + +#include + +namespace Ui::Menu { + +not_null CreateAction( + QWidget *parent, + const QString &text, + Fn &&callback) { + const auto action = new QAction(text, parent); + parent->connect( + action, + &QAction::triggered, + action, + std::move(callback), + Qt::QueuedConnection); + return action; +} + +} // namespace Ui::Menu diff --git a/ui/widgets/menu/menu_common.h b/ui/widgets/menu/menu_common.h index e1d19f4..6d3de70 100644 --- a/ui/widgets/menu/menu_common.h +++ b/ui/widgets/menu/menu_common.h @@ -21,4 +21,9 @@ struct CallbackData { bool selected = false; }; +not_null CreateAction( + QWidget *parent, + const QString &text, + Fn &&callback); + } // namespace Ui::Menu diff --git a/ui/widgets/menu/menu_toggle.cpp b/ui/widgets/menu/menu_toggle.cpp new file mode 100644 index 0000000..c96eb3f --- /dev/null +++ b/ui/widgets/menu/menu_toggle.cpp @@ -0,0 +1,70 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/widgets/menu/menu_toggle.h" + +#include "ui/widgets/checkbox.h" + +namespace Ui::Menu { + +Toggle::Toggle( + not_null parent, + const style::Menu &st, + const QString &text, + Fn &&callback, + const style::icon *icon, + const style::icon *iconOver) +: Action( + parent, + st, + CreateAction(parent, text, std::move(callback)), + icon, + iconOver) +, _padding(st.itemPadding) +, _toggleShift(st.itemToggleShift) +, _itemToggle(st.itemToggle) +, _itemToggleOver(st.itemToggleOver) { + + const auto processAction = [=] { + if (!action()->isCheckable()) { + _toggle.reset(); + return; + } + if (_toggle) { + _toggle->setChecked(action()->isChecked(), anim::type::normal); + } else { + _toggle = std::make_unique( + st.itemToggle, + action()->isChecked(), + [=] { update(); }); + } + }; + processAction(); + connect(action(), &QAction::changed, [=] { processAction(); }); + + selects( + ) | rpl::start_with_next([=](const CallbackData &data) { + if (!_toggle) { + return; + } + _toggle->setStyle(data.selected ? _itemToggleOver : _itemToggle); + }, lifetime()); + +} + +void Toggle::paintEvent(QPaintEvent *e) { + Action::paintEvent(e); + if (_toggle) { + Painter p(this); + const auto toggleSize = _toggle->getSize(); + _toggle->paint( + p, + width() - _padding.right() - toggleSize.width() + _toggleShift, + (contentHeight() - toggleSize.height()) / 2, width()); + } +} + +} // namespace Ui::Menu diff --git a/ui/widgets/menu/menu_toggle.h b/ui/widgets/menu/menu_toggle.h new file mode 100644 index 0000000..8b46d66 --- /dev/null +++ b/ui/widgets/menu/menu_toggle.h @@ -0,0 +1,40 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +#include "ui/widgets/menu/menu_action.h" +#include "styles/style_widgets.h" + +namespace Ui { +class ToggleView; +} // namespace Ui + +namespace Ui::Menu { + +class Toggle : public Action { +public: + Toggle( + not_null parent, + const style::Menu &st, + const QString &text, + Fn &&callback, + const style::icon *icon, + const style::icon *iconOver); + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + const style::margins &_padding; + const int _toggleShift; + const style::Toggle &_itemToggle; + const style::Toggle &_itemToggleOver; + std::unique_ptr _toggle; + +}; + +} // namespace Ui::Menu