feat: create delegate for project item views
This allows us to define custom painting for list view items. In particular, this is applied to the mod downloader, in order to allow displaying both the mod name and mod description, and settings their effects (like bold or underline) independent of each other. Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
0f61f5ba03
commit
4a13dbe3bb
8 changed files with 139 additions and 24 deletions
78
launcher/ui/widgets/ProjectItem.cpp
Normal file
78
launcher/ui/widgets/ProjectItem.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "ProjectItem.h"
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
|
||||
ProjectItemDelegate::ProjectItemDelegate(QWidget* parent) : QStyledItemDelegate(parent) {}
|
||||
|
||||
void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
painter->save();
|
||||
|
||||
QStyleOptionViewItem opt(option);
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
auto& rect = opt.rect;
|
||||
auto icon_width = rect.height(), icon_height = rect.height();
|
||||
auto remaining_width = rect.width() - icon_width;
|
||||
|
||||
if (opt.state & QStyle::State_Selected) {
|
||||
painter->fillRect(rect, opt.palette.highlight());
|
||||
painter->setPen(opt.palette.highlightedText().color());
|
||||
} else if (opt.state & QStyle::State_MouseOver) {
|
||||
painter->fillRect(rect, opt.palette.window());
|
||||
}
|
||||
|
||||
{ // Icon painting
|
||||
// Square-sized, occupying the left portion
|
||||
opt.icon.paint(painter, rect.x(), rect.y(), icon_width, icon_height);
|
||||
}
|
||||
|
||||
{ // Title painting
|
||||
auto title = index.data(UserDataTypes::TITLE).toString();
|
||||
|
||||
painter->save();
|
||||
|
||||
auto font = opt.font;
|
||||
if (index.data(UserDataTypes::SELECTED).toBool()) {
|
||||
// Set nice font
|
||||
font.setBold(true);
|
||||
font.setUnderline(true);
|
||||
}
|
||||
|
||||
font.setPointSize(font.pointSize() + 2);
|
||||
painter->setFont(font);
|
||||
|
||||
// On the top, aligned to the left after the icon
|
||||
painter->drawText(rect.x() + icon_width, rect.y() + QFontMetrics(font).height(), title);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
{ // Description painting
|
||||
auto description = index.data(UserDataTypes::DESCRIPTION).toString();
|
||||
|
||||
QTextLayout text_layout(description, opt.font);
|
||||
|
||||
qreal height = 0;
|
||||
auto cut_text = viewItemTextLayout(text_layout, remaining_width, height);
|
||||
|
||||
// Get first line unconditionally
|
||||
description = cut_text.first().second;
|
||||
// Get second line, elided if needed
|
||||
if (cut_text.size() > 1) {
|
||||
if (cut_text.size() > 2)
|
||||
description += opt.fontMetrics.elidedText(cut_text.at(1).second, opt.textElideMode, cut_text.at(1).first);
|
||||
else
|
||||
description += cut_text.at(1).second;
|
||||
}
|
||||
|
||||
// On the bottom, aligned to the left after the icon, and featuring at most two lines of text (with some margin space to spare)
|
||||
painter->drawText(rect.x() + icon_width, rect.y() + rect.height() - 2.2 * opt.fontMetrics.height(), remaining_width,
|
||||
2 * opt.fontMetrics.height(), Qt::TextWordWrap, description);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue