| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // 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"
- #include "ui/qt_object_factory.h"
- namespace Ui::Menu {
- MultilineAction::MultilineAction(
- not_null<Ui::RpWidget*> 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<Ui::FlatLabel>(
- this,
- rpl::single(std::move(about)),
- stLabel))
- , _dummyAction(Ui::CreateChild<QAction>(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();
- const auto rightSkip = _icon ? _st.itemIconPosition.x() : skip;
- _text->resizeToWidth(width - skip - rightSkip);
- _text->moveToLeft(skip, top);
- resize(width, contentHeight());
- }, lifetime());
- }
- not_null<QAction*> MultilineAction::action() const {
- return _dummyAction;
- }
- bool MultilineAction::isEnabled() const {
- return true;
- }
- int MultilineAction::contentHeight() const {
- const auto skip = _labelPosition.y();
- return skip
- + std::max(_text->height(), _icon ? _icon->height() : 0)
- + 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();
- const auto rightSkip = _icon ? _st.itemIconPosition.x() : skip;
- auto min = _text->textMaxWidth() / 4;
- auto max = _icon ? _st.widthMax : (_text->textMaxWidth() - skip);
- _text->resizeToWidth(max);
- const auto height = _icon
- ? ((_st.itemIconPosition.y() * 2) + _icon->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 + rightSkip + max);
- }
- } // namespace Ui::Menu
|