Enlarge desktop chat and member avatars
This commit is contained in:
1 parent
68cb9413db
commit
593aaa42dc
7 files changed
+42
-22
No files matched your search
@@ -1,6 +1,7 @@
|
||||
#include "accountdelegate.h"
|
||||
#include "flagpainter.h"
|
||||
#include "memberlistmodel.h"
|
||||
#include "debug_ui.h"
|
||||
#include <QPainter>
|
||||
#include <QFont>
|
||||
#include <QMouseEvent>
|
||||
@@ -9,8 +10,16 @@ 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) {}
|
||||
: 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 {
|
||||
@@ -24,11 +33,11 @@ void AccountDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
|
||||
painter->fillRect(option.rect, option.palette.alternateBase());
|
||||
|
||||
const int margin = 4;
|
||||
const int iconSz = 24;
|
||||
const int iconSz = MemberListModel::kAvatarSize;
|
||||
|
||||
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
|
||||
if (!icon.isNull())
|
||||
icon.paint(painter, option.rect.left() + margin, option.rect.top() + (option.rect.height() - iconSz) / 2, iconSz, iconSz);
|
||||
icon.paint(painter, avatarRect(option.rect));
|
||||
|
||||
const int x = option.rect.left() + iconSz + margin * 3;
|
||||
const bool canInvite = !index.data(Qt::UserRole + 2).toBool();
|
||||
@@ -96,7 +105,7 @@ bool AccountDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, cons
|
||||
event->type() != QEvent::MouseButtonDblClick) return false;
|
||||
auto* mouse = static_cast<QMouseEvent*>(event);
|
||||
if (mouse->button() != Qt::LeftButton) return false;
|
||||
const bool onAvatar=QRect(option.rect.left()+4,option.rect.center().y()-12,24,24).contains(mouse->pos());
|
||||
const bool onAvatar = avatarRect(option.rect).contains(mouse->pos());
|
||||
if (event->type()==QEvent::MouseButtonPress) {
|
||||
m_avatarPress=onAvatar ? index : QModelIndex(); m_avatarPosition=mouse->pos();
|
||||
}
|
||||
@@ -119,5 +128,5 @@ bool AccountDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, cons
|
||||
QSize AccountDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const {
|
||||
(void)option; (void)index;
|
||||
return QSize(160, 36);
|
||||
return QSize(160, MemberListModel::kRowHeight);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ AccountList::AccountList(DbManager* db, QWidget *parent)
|
||||
m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
m_listView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_listView->setMouseTracking(true);
|
||||
m_listView->setIconSize(QSize(24, 24));
|
||||
m_listView->setIconSize(QSize(MemberListModel::kAvatarSize, MemberListModel::kAvatarSize));
|
||||
m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
m_listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
@@ -17,12 +17,14 @@ extern "C" {
|
||||
static void applyPhoto(MemberListItem& item, const QString& channel) {
|
||||
auto* manager = AvatarManager::instance(); if (!manager) return;
|
||||
const QImage image = manager->image(channel, item.nodeId); if (image.isNull()) return;
|
||||
QPixmap pixmap(24, 24); pixmap.fill(Qt::transparent);
|
||||
const int size = MemberListModel::kAvatarSize;
|
||||
QPixmap pixmap(size, size); pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath clip; clip.addEllipse(QRectF(0, 0, 24, 24)); painter.setClipPath(clip);
|
||||
painter.drawImage(QRect(0, 0, 24, 24), image); painter.setClipping(false);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
QPainterPath clip; clip.addEllipse(QRectF(0, 0, size, size)); painter.setClipPath(clip);
|
||||
painter.drawImage(QRect(0, 0, size, size), image); painter.setClipping(false);
|
||||
painter.setPen(QPen(Qt::white, 1)); painter.setBrush(item.online ? QColor("#4CAF50") : QColor("#9E9E9E"));
|
||||
painter.drawEllipse(QRect(17, 17, 6, 6)); painter.end(); item.avatar = pixmap;
|
||||
painter.drawEllipse(QRect(size - 7, size - 7, 6, 6)); painter.end(); item.avatar = pixmap;
|
||||
}
|
||||
|
||||
MemberListModel::MemberListModel(QObject* parent)
|
||||
@@ -136,16 +138,17 @@ static void deserialize_member(const uint8_t* src, MemberListItem& item) {
|
||||
item.name = QString::fromUtf8(name);
|
||||
|
||||
QColor c = item.online ? QColor("#4CAF50") : QColor("#9E9E9E");
|
||||
QPixmap pm(24, 24); pm.fill(Qt::transparent);
|
||||
const int size = MemberListModel::kAvatarSize;
|
||||
QPixmap pm(size, size); pm.fill(Qt::transparent);
|
||||
QPainter p(&pm);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.setBrush(c);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(2, 2, 20, 20);
|
||||
p.drawEllipse(0, 0, size, size);
|
||||
p.setPen(Qt::white);
|
||||
QFont f; f.setBold(true); f.setPixelSize(12);
|
||||
QFont f; f.setBold(true); f.setPixelSize(size / 2);
|
||||
p.setFont(f);
|
||||
p.drawText(QRect(0, 0, 24, 24), Qt::AlignCenter, item.name.left(1));
|
||||
p.drawText(QRect(0, 0, size, size), Qt::AlignCenter, item.name.left(1));
|
||||
p.end();
|
||||
item.avatar = pm;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ struct MemberListItem {
|
||||
class MemberListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/* Высота строки 36 px, между аватарками остаётся 2 px. */
|
||||
static constexpr int kRowHeight = 36;
|
||||
static constexpr int kAvatarSize = kRowHeight - 2;
|
||||
|
||||
explicit MemberListModel(QObject* parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
@@ -83,7 +83,9 @@ QString MessageDelegate::linkAt(const QStyleOptionViewItem& option, const QModel
|
||||
}
|
||||
|
||||
MessageDelegate::MessageDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent) {}
|
||||
: QStyledItemDelegate(parent) {
|
||||
GUI_DEBUG("MessageDelegate: avatar size=%dpx", kAvatar);
|
||||
}
|
||||
|
||||
struct VoicePlayState {
|
||||
uint64_t playbackId = 0;
|
||||
@@ -442,7 +444,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
}
|
||||
|
||||
if (!L.narrow) {
|
||||
int avatarY = L.bubbleRect.bottom() - kAvatar;
|
||||
int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
|
||||
if (!L.isOutgoing)
|
||||
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
|
||||
else
|
||||
@@ -484,7 +486,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
L.videoDurBadgeRect = QRect(bx + thW - 66, thH - 26, 58, 18);
|
||||
|
||||
if (!L.narrow) {
|
||||
int avatarY = L.bubbleRect.bottom() - kAvatar;
|
||||
int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
|
||||
if (!L.isOutgoing)
|
||||
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
|
||||
else
|
||||
@@ -519,7 +521,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
L.imageBadgeRect = QRect(bx + thW - 150, thH - 26, 142, 18);
|
||||
|
||||
if (!L.narrow) {
|
||||
int avatarY = L.bubbleRect.bottom() - kAvatar;
|
||||
int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
|
||||
if (!L.isOutgoing)
|
||||
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
|
||||
else
|
||||
@@ -557,7 +559,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
L.statusRect = QRect(bx + kPadH + ih + 8 - 48, kPadTop + th + 2, L.bubbleWidth - 2*kPadH - ih - 8 + 48 - 40, th);
|
||||
|
||||
if (!L.narrow) {
|
||||
int avatarY = L.bubbleRect.bottom() - kAvatar;
|
||||
int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
|
||||
if (!L.isOutgoing)
|
||||
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
|
||||
else
|
||||
@@ -687,7 +689,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
|
||||
L.statusRect = QRect(txRect, contentTop + textH + 2, textW, kStatusH);
|
||||
|
||||
if (!L.narrow) {
|
||||
int avatarY = L.bubbleRect.bottom() - kAvatar;
|
||||
int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
|
||||
if (!L.isOutgoing)
|
||||
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
|
||||
else
|
||||
@@ -1617,6 +1619,7 @@ void MessageDelegate::drawAvatar(QPainter *p, const Layout &L,
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath clip;
|
||||
clip.addEllipse(L.avatarRect);
|
||||
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
p->setClipPath(clip);
|
||||
p->drawPixmap(L.avatarRect, av);
|
||||
p->restore();
|
||||
|
||||
@@ -52,6 +52,8 @@ enum MessageDataRole {
|
||||
class MessageDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static constexpr int kAvatar = 54;
|
||||
|
||||
explicit MessageDelegate(QObject *parent = nullptr);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
@@ -128,7 +130,6 @@ private:
|
||||
void drawAvatar(QPainter *p, const Layout &L,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
static constexpr int kAvatar = 36;
|
||||
static constexpr int kGap = 8;
|
||||
static constexpr int kRadius = 10;
|
||||
static constexpr int kPadH = 12;
|
||||
|
||||
@@ -77,7 +77,7 @@ static QIcon makeRadioIcon(const QColor& color) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
static QPixmap makeAvatar(const QColor &color, const QString &letter, int size = 36) {
|
||||
static QPixmap makeAvatar(const QColor &color, const QString &letter, int size = MessageDelegate::kAvatar) {
|
||||
QPixmap pix(size, size);
|
||||
pix.fill(Qt::transparent);
|
||||
QPainter p(&pix);
|
||||
|
||||
Reference in new issue
Block a user