You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

132 lines
5.8 KiB

#include "accountdelegate.h"
#include "flagpainter.h"
#include "memberlistmodel.h"
#include "debug_ui.h"
#include <QPainter>
#include <QFont>
#include <QMouseEvent>
static QRect inviteButtonRect(const QRect& row) {
return QRect(row.right() - 31, row.center().y() - 14, 28, 28);
}
static QRect avatarRect(const QRect& row) {
const int size = MemberListModel::kAvatarSize;
return QRect(row.left() + 4, row.top() + (row.height() - size) / 2, size, size);
}
AccountDelegate::AccountDelegate(QObject *parent)
: QStyledItemDelegate(parent) {
GUI_DEBUG("AccountDelegate: row height=%dpx avatar=%dpx gap=%dpx", MemberListModel::kRowHeight,
MemberListModel::kAvatarSize, MemberListModel::kRowHeight - MemberListModel::kAvatarSize);
}
void AccountDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const {
painter->save();
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
else if (option.state & QStyle::State_MouseOver)
painter->fillRect(option.rect, option.palette.alternateBase().color().lighter(115));
else
painter->fillRect(option.rect, option.palette.alternateBase());
const int margin = 4;
const int iconSz = MemberListModel::kAvatarSize;
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
if (!icon.isNull())
icon.paint(painter, avatarRect(option.rect));
const int x = option.rect.left() + iconSz + margin * 3;
const bool canInvite = !index.data(Qt::UserRole + 2).toBool();
const int w = option.rect.right() - x - margin - (canInvite ? 32 : 0);
const int yMid = option.rect.top() + option.rect.height() / 2;
uint8_t flags = (uint8_t)(index.data(Qt::UserRole + 3).toInt() & 0xFF);
QFont nameFont = painter->font();
nameFont.setBold(true);
nameFont.setPixelSize(13);
if (flags & MEMBER_FLAG_DELETED) nameFont.setStrikeOut(true);
painter->setFont(nameFont);
QColor textColor = option.palette.color(QPalette::Text);
if (option.state & QStyle::State_Selected) textColor = option.palette.color(QPalette::HighlightedText);
if (index.data(Qt::UserRole + 2).toBool()) textColor = QColor("#4CAF50");
painter->setPen(textColor);
const uint8_t visualFlags = flags & (MEMBER_FLAG_SUPERNODE | MEMBER_FLAG_ADMIN | MEMBER_FLAG_MODER);
int flagX = x;
if (visualFlags) {
FlagPainter::draw(painter, flags, flagX, option.rect.top() + (option.rect.height() - nameFont.pixelSize()) / 2, nameFont.pixelSize());
int n = __builtin_popcount(visualFlags);
flagX += nameFont.pixelSize() * n + (n - 1) * 2;
}
if (index.data(Qt::UserRole + 4).toBool()) {
FlagPainter::drawStorage(painter, flagX, option.rect.top() + (option.rect.height() - nameFont.pixelSize()) / 2, nameFont.pixelSize());
flagX += nameFont.pixelSize() + 2;
}
if (flags & MEMBER_FLAG_RADIO) {
FlagPainter::drawRadio(painter, flagX, option.rect.top() + (option.rect.height() - nameFont.pixelSize()) / 2,
nameFont.pixelSize(), textColor);
flagX += nameFont.pixelSize() + 2;
}
QString name = index.data(Qt::DisplayRole).toString();
painter->drawText(QRect(flagX, option.rect.top() + 2, w - (flagX - x), yMid - option.rect.top() - 2),
Qt::AlignLeft | Qt::AlignBottom, name);
QFont subFont = painter->font();
subFont.setBold(false);
subFont.setPixelSize(10);
painter->setFont(subFont);
painter->setPen(QColor(130, 130, 130));
QString sub = index.data(Qt::UserRole + 1).toString();
if (!sub.isEmpty())
painter->drawText(QRect(flagX, yMid + 2, w - (flagX - x), option.rect.bottom() - yMid - 2),
Qt::AlignLeft | Qt::AlignTop, sub);
if (canInvite) {
QFont plusFont = nameFont; plusFont.setPixelSize(22); plusFont.setStrikeOut(false);
painter->setFont(plusFont);
painter->setPen(option.palette.color(QPalette::Link));
painter->drawText(inviteButtonRect(option.rect), Qt::AlignCenter, QStringLiteral("+"));
}
painter->restore();
}
bool AccountDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
const QModelIndex& index) {
Q_UNUSED(model);
if (event->type() != QEvent::MouseButtonPress && event->type() != QEvent::MouseButtonRelease &&
event->type() != QEvent::MouseButtonDblClick) return false;
auto* mouse = static_cast<QMouseEvent*>(event);
if (mouse->button() != Qt::LeftButton) return false;
const bool onAvatar = avatarRect(option.rect).contains(mouse->pos());
if (event->type()==QEvent::MouseButtonPress) {
m_avatarPress=onAvatar ? index : QModelIndex(); m_avatarPosition=mouse->pos();
}
if (onAvatar) {
if (event->type()==QEvent::MouseButtonRelease && m_avatarPress==index && (mouse->pos()-m_avatarPosition).manhattanLength()<5)
emit avatarRequested(index);
if (event->type()==QEvent::MouseButtonRelease) m_avatarPress=QPersistentModelIndex();
return true;
}
if (index.data(Qt::UserRole + 2).toBool()) return false;
const bool inside = inviteButtonRect(option.rect).contains(mouse->pos());
if (event->type() == QEvent::MouseButtonPress) { m_invitePress = inside ? index : QModelIndex(); return inside; }
if (event->type() == QEvent::MouseButtonDblClick) return inside;
const bool activate = inside && m_invitePress == index;
m_invitePress = QPersistentModelIndex();
if (activate) emit inviteRequested(index);
return activate;
}
QSize AccountDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const {
(void)option; (void)index;
return QSize(160, MemberListModel::kRowHeight);
}