92 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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<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();
 | 
						|
		_text->resizeToWidth(width - 2 * skip);
 | 
						|
		_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();
 | 
						|
	auto min = _text->textMaxWidth() / 2;
 | 
						|
	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 * 2 + max);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace Ui::Menu
 |