Browse Source

Enlarge desktop chat and member avatars

master
evgeny 6 days ago
parent
commit
29ee55d751
  1. 19
      tools/chatgui/src/accountdelegate.cpp
  2. 2
      tools/chatgui/src/accountlist.cpp
  3. 19
      tools/chatgui/src/memberlistmodel.cpp
  4. 4
      tools/chatgui/src/memberlistmodel.h
  5. 15
      tools/chatgui/src/messagedelegate.cpp
  6. 3
      tools/chatgui/src/messagedelegate.h
  7. 2
      tools/chatgui/src/messagelist.cpp

19
tools/chatgui/src/accountdelegate.cpp

@ -1,6 +1,7 @@
#include "accountdelegate.h" #include "accountdelegate.h"
#include "flagpainter.h" #include "flagpainter.h"
#include "memberlistmodel.h" #include "memberlistmodel.h"
#include "debug_ui.h"
#include <QPainter> #include <QPainter>
#include <QFont> #include <QFont>
#include <QMouseEvent> #include <QMouseEvent>
@ -9,8 +10,16 @@ static QRect inviteButtonRect(const QRect& row) {
return QRect(row.right() - 31, row.center().y() - 14, 28, 28); 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) 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, void AccountDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const { const QModelIndex &index) const {
@ -24,11 +33,11 @@ void AccountDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
painter->fillRect(option.rect, option.palette.alternateBase()); painter->fillRect(option.rect, option.palette.alternateBase());
const int margin = 4; const int margin = 4;
const int iconSz = 24; const int iconSz = MemberListModel::kAvatarSize;
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
if (!icon.isNull()) 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 int x = option.rect.left() + iconSz + margin * 3;
const bool canInvite = !index.data(Qt::UserRole + 2).toBool(); 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; event->type() != QEvent::MouseButtonDblClick) return false;
auto* mouse = static_cast<QMouseEvent*>(event); auto* mouse = static_cast<QMouseEvent*>(event);
if (mouse->button() != Qt::LeftButton) return false; 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) { if (event->type()==QEvent::MouseButtonPress) {
m_avatarPress=onAvatar ? index : QModelIndex(); m_avatarPosition=mouse->pos(); 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, QSize AccountDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const { const QModelIndex &index) const {
(void)option; (void)index; (void)option; (void)index;
return QSize(160, 36); return QSize(160, MemberListModel::kRowHeight);
} }

2
tools/chatgui/src/accountlist.cpp

@ -96,7 +96,7 @@ AccountList::AccountList(DbManager* db, QWidget *parent)
m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_listView->setSelectionMode(QAbstractItemView::SingleSelection); m_listView->setSelectionMode(QAbstractItemView::SingleSelection);
m_listView->setMouseTracking(true); 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->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); m_listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
m_listView->setContextMenuPolicy(Qt::CustomContextMenu); m_listView->setContextMenuPolicy(Qt::CustomContextMenu);

19
tools/chatgui/src/memberlistmodel.cpp

@ -17,12 +17,14 @@ extern "C" {
static void applyPhoto(MemberListItem& item, const QString& channel) { static void applyPhoto(MemberListItem& item, const QString& channel) {
auto* manager = AvatarManager::instance(); if (!manager) return; auto* manager = AvatarManager::instance(); if (!manager) return;
const QImage image = manager->image(channel, item.nodeId); if (image.isNull()) 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); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing);
QPainterPath clip; clip.addEllipse(QRectF(0, 0, 24, 24)); painter.setClipPath(clip); painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.drawImage(QRect(0, 0, 24, 24), image); painter.setClipping(false); 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.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) MemberListModel::MemberListModel(QObject* parent)
@ -136,16 +138,17 @@ static void deserialize_member(const uint8_t* src, MemberListItem& item) {
item.name = QString::fromUtf8(name); item.name = QString::fromUtf8(name);
QColor c = item.online ? QColor("#4CAF50") : QColor("#9E9E9E"); 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); QPainter p(&pm);
p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing);
p.setBrush(c); p.setBrush(c);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.drawEllipse(2, 2, 20, 20); p.drawEllipse(0, 0, size, size);
p.setPen(Qt::white); 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.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(); p.end();
item.avatar = pm; item.avatar = pm;
} }

4
tools/chatgui/src/memberlistmodel.h

@ -27,6 +27,10 @@ struct MemberListItem {
class MemberListModel : public QAbstractListModel { class MemberListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
/* Высота строки 36 px, между аватарками остаётся 2 px. */
static constexpr int kRowHeight = 36;
static constexpr int kAvatarSize = kRowHeight - 2;
explicit MemberListModel(QObject* parent = nullptr); explicit MemberListModel(QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override;

15
tools/chatgui/src/messagedelegate.cpp

@ -83,7 +83,9 @@ QString MessageDelegate::linkAt(const QStyleOptionViewItem& option, const QModel
} }
MessageDelegate::MessageDelegate(QObject *parent) MessageDelegate::MessageDelegate(QObject *parent)
: QStyledItemDelegate(parent) {} : QStyledItemDelegate(parent) {
GUI_DEBUG("MessageDelegate: avatar size=%dpx", kAvatar);
}
struct VoicePlayState { struct VoicePlayState {
uint64_t playbackId = 0; uint64_t playbackId = 0;
@ -442,7 +444,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
} }
if (!L.narrow) { if (!L.narrow) {
int avatarY = L.bubbleRect.bottom() - kAvatar; int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
if (!L.isOutgoing) if (!L.isOutgoing)
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar); L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
else else
@ -484,7 +486,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
L.videoDurBadgeRect = QRect(bx + thW - 66, thH - 26, 58, 18); L.videoDurBadgeRect = QRect(bx + thW - 66, thH - 26, 58, 18);
if (!L.narrow) { if (!L.narrow) {
int avatarY = L.bubbleRect.bottom() - kAvatar; int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
if (!L.isOutgoing) if (!L.isOutgoing)
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar); L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
else else
@ -519,7 +521,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
L.imageBadgeRect = QRect(bx + thW - 150, thH - 26, 142, 18); L.imageBadgeRect = QRect(bx + thW - 150, thH - 26, 142, 18);
if (!L.narrow) { if (!L.narrow) {
int avatarY = L.bubbleRect.bottom() - kAvatar; int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
if (!L.isOutgoing) if (!L.isOutgoing)
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar); L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
else 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); L.statusRect = QRect(bx + kPadH + ih + 8 - 48, kPadTop + th + 2, L.bubbleWidth - 2*kPadH - ih - 8 + 48 - 40, th);
if (!L.narrow) { if (!L.narrow) {
int avatarY = L.bubbleRect.bottom() - kAvatar; int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
if (!L.isOutgoing) if (!L.isOutgoing)
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar); L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
else else
@ -687,7 +689,7 @@ MessageDelegate::Layout MessageDelegate::calcLayout(
L.statusRect = QRect(txRect, contentTop + textH + 2, textW, kStatusH); L.statusRect = QRect(txRect, contentTop + textH + 2, textW, kStatusH);
if (!L.narrow) { if (!L.narrow) {
int avatarY = L.bubbleRect.bottom() - kAvatar; int avatarY = qMax(0, L.bubbleRect.bottom() + 1 - kAvatar);
if (!L.isOutgoing) if (!L.isOutgoing)
L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar); L.avatarRect = QRect(kMarginH, avatarY, kAvatar, kAvatar);
else else
@ -1617,6 +1619,7 @@ void MessageDelegate::drawAvatar(QPainter *p, const Layout &L,
p->setRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing);
QPainterPath clip; QPainterPath clip;
clip.addEllipse(L.avatarRect); clip.addEllipse(L.avatarRect);
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setClipPath(clip); p->setClipPath(clip);
p->drawPixmap(L.avatarRect, av); p->drawPixmap(L.avatarRect, av);
p->restore(); p->restore();

3
tools/chatgui/src/messagedelegate.h

@ -52,6 +52,8 @@ enum MessageDataRole {
class MessageDelegate : public QStyledItemDelegate { class MessageDelegate : public QStyledItemDelegate {
Q_OBJECT Q_OBJECT
public: public:
static constexpr int kAvatar = 54;
explicit MessageDelegate(QObject *parent = nullptr); explicit MessageDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, void paint(QPainter *painter, const QStyleOptionViewItem &option,
@ -128,7 +130,6 @@ private:
void drawAvatar(QPainter *p, const Layout &L, void drawAvatar(QPainter *p, const Layout &L,
const QModelIndex &index) const; const QModelIndex &index) const;
static constexpr int kAvatar = 36;
static constexpr int kGap = 8; static constexpr int kGap = 8;
static constexpr int kRadius = 10; static constexpr int kRadius = 10;
static constexpr int kPadH = 12; static constexpr int kPadH = 12;

2
tools/chatgui/src/messagelist.cpp

@ -77,7 +77,7 @@ static QIcon makeRadioIcon(const QColor& color) {
return icon; 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); QPixmap pix(size, size);
pix.fill(Qt::transparent); pix.fill(Qt::transparent);
QPainter p(&pix); QPainter p(&pix);

Loading…
Cancel
Save