From 2996fb7030679e49deb093431a8db42243131d29 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 1 Mar 2023 18:31:54 +0300 Subject: [PATCH] Moved out menu item with multiline text to separated file. --- CMakeLists.txt | 2 + ui/widgets/menu/menu_multiline_action.cpp | 88 +++++++++++++++++++++++ ui/widgets/menu/menu_multiline_action.h | 51 +++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 ui/widgets/menu/menu_multiline_action.cpp create mode 100644 ui/widgets/menu/menu_multiline_action.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a0a53d28..201b0fc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,8 @@ PRIVATE ui/widgets/menu/menu_common.h ui/widgets/menu/menu_item_base.cpp ui/widgets/menu/menu_item_base.h + ui/widgets/menu/menu_multiline_action.cpp + ui/widgets/menu/menu_multiline_action.h ui/widgets/menu/menu_separator.cpp ui/widgets/menu/menu_separator.h ui/widgets/menu/menu_toggle.cpp diff --git a/ui/widgets/menu/menu_multiline_action.cpp b/ui/widgets/menu/menu_multiline_action.cpp new file mode 100644 index 00000000..5da592b7 --- /dev/null +++ b/ui/widgets/menu/menu_multiline_action.cpp @@ -0,0 +1,88 @@ +// 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_multiline_action.h" + +#include "ui/widgets/labels.h" + +namespace Ui::Menu { + +MultilineAction::MultilineAction( + not_null parent, + const style::Menu &st, + const style::FlatLabel &stLabel, + QPoint labelPosition, + TextWithEntities &&about, + const style::icon *icon, + const style::icon *iconOver) +: ItemBase(parent, st) +, _st(st) +, _icon(icon) +, _iconOver(iconOver ? iconOver : icon) +, _labelPosition(labelPosition) +, _text(base::make_unique_q( + this, + rpl::single(std::move(about)), + stLabel)) +, _dummyAction(Ui::CreateChild(parent.get())) { + ItemBase::enableMouseSelecting(); + _text->setAttribute(Qt::WA_TransparentForMouseEvents); + updateMinWidth(); + parent->widthValue() | rpl::start_with_next([=](int width) { + const auto top = _labelPosition.y(); + const auto skip = _labelPosition.x(); + _text->resizeToWidth(width - 2 * skip); + _text->moveToLeft(skip, top); + resize(width, contentHeight()); + }, lifetime()); +} + +not_null MultilineAction::action() const { + return _dummyAction; +} + +bool MultilineAction::isEnabled() const { + return true; +} + +int MultilineAction::contentHeight() const { + const auto skip = _labelPosition.y(); + return skip + _text->height() + skip; +} + +void MultilineAction::paintEvent(QPaintEvent *e) { + auto p = QPainter(this); + const auto selected = isSelected(); + p.fillRect(rect(), selected ? _st.itemBgOver : _st.itemBg); + RippleButton::paintRipple(p, 0, 0); + if (const auto icon = (selected ? _iconOver : _icon)) { + icon->paint(p, _st.itemIconPosition, width()); + } +} + +void MultilineAction::updateMinWidth() { + const auto skip = _labelPosition.x(); + auto min = _text->naturalWidth() / 2; + auto max = _text->naturalWidth() - skip; + _text->resizeToWidth(max); + const auto height = _text->height(); + _text->resizeToWidth(min); + const auto heightMax = _text->height(); + if (heightMax > height) { + while (min + 1 < max) { + const auto middle = (max + min) / 2; + _text->resizeToWidth(middle); + if (_text->height() > height) { + min = middle; + } else { + max = middle; + } + } + } + ItemBase::setMinWidth(skip * 2 + max); +} + +} // namespace Ui::Menu diff --git a/ui/widgets/menu/menu_multiline_action.h b/ui/widgets/menu/menu_multiline_action.h new file mode 100644 index 00000000..3f1c846c --- /dev/null +++ b/ui/widgets/menu/menu_multiline_action.h @@ -0,0 +1,51 @@ +// 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_item_base.h" + +namespace style { +struct FlatLabel; +struct Menu; +} // namespace style + +namespace Ui { +class FlatLabel; +class RpWidget; +} // namespace Ui + +namespace Ui::Menu { + +class MultilineAction final : public ItemBase { +public: + MultilineAction( + not_null parent, + const style::Menu &st, + const style::FlatLabel &stLabel, + QPoint labelPosition, + TextWithEntities &&about, + const style::icon *icon = nullptr, + const style::icon *iconOver = nullptr); + + not_null action() const override; + bool isEnabled() const override; + +private: + int contentHeight() const override; + void paintEvent(QPaintEvent *e) override; + void updateMinWidth(); + + const style::Menu &_st; + const style::icon *_icon; + const style::icon *_iconOver; + const QPoint _labelPosition; + const base::unique_qptr _text; + const not_null _dummyAction; + +}; + +} // namespace Ui::Menu