forked from blue/squawk
avatar painting is returned to delegate; sender names now are not painted in every message
This commit is contained in:
parent
7130e674c4
commit
9ac0ca10f3
@ -338,20 +338,6 @@ void FeedView::paintEvent(QPaintEvent* event)
|
|||||||
drawDateDevider(option.rect.bottom(), lastDate, painter);
|
drawDateDevider(option.rect.bottom(), lastDate, painter);
|
||||||
}
|
}
|
||||||
lastDate = currentDate;
|
lastDate = currentDate;
|
||||||
|
|
||||||
|
|
||||||
if ((option.rect.y() < 1) || (index.row() == m->rowCount() - 1)) {
|
|
||||||
drawAvatar(index, option, painter);
|
|
||||||
} else {
|
|
||||||
QString mySender = index.data(Models::MessageFeed::Sender).toString();
|
|
||||||
QModelIndex prevIndex = m->index(index.row() + 1, 0, rootIndex());
|
|
||||||
if (
|
|
||||||
(prevIndex.data(Models::MessageFeed::Sender).toString() != mySender) ||
|
|
||||||
(prevIndex.data(Models::MessageFeed::Date).toDateTime().daysTo(currentDate) != 0)
|
|
||||||
) {
|
|
||||||
drawAvatar(index, option, painter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!lastDate.isNull() && inZone) { //if after drawing all messages there is still space
|
if (!lastDate.isNull() && inZone) { //if after drawing all messages there is still space
|
||||||
drawDateDevider(option.rect.bottom(), lastDate, painter);
|
drawDateDevider(option.rect.bottom(), lastDate, painter);
|
||||||
@ -374,40 +360,6 @@ void FeedView::drawDateDevider(int top, const QDateTime& date, QPainter& painter
|
|||||||
painter.restore();
|
painter.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedView::drawAvatar(const QModelIndex& index, const QStyleOptionViewItem& option, QPainter& painter)
|
|
||||||
{
|
|
||||||
int currentRow = index.row();
|
|
||||||
int y = option.rect.y();
|
|
||||||
bool firstAttempt = true;
|
|
||||||
QString mySender = index.data(Models::MessageFeed::Sender).toString();
|
|
||||||
QDateTime currentDate = index.data(Models::MessageFeed::Date).toDateTime();
|
|
||||||
QIcon icon(index.data(Models::MessageFeed::Avatar).toString());
|
|
||||||
while (y < 0 && currentRow > 0) {
|
|
||||||
QRect rect;
|
|
||||||
if (firstAttempt) {
|
|
||||||
firstAttempt = false;
|
|
||||||
rect = option.rect;
|
|
||||||
} else {
|
|
||||||
QModelIndex ci = model()->index(currentRow, 0, rootIndex());
|
|
||||||
if (
|
|
||||||
(ci.data(Models::MessageFeed::Sender).toString() != mySender) ||
|
|
||||||
(ci.data(Models::MessageFeed::Date).toDateTime().daysTo(currentDate) != 0)
|
|
||||||
) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rect = visualRect(ci);
|
|
||||||
}
|
|
||||||
y = std::min(0, rect.bottom() - margin - avatarHeight);
|
|
||||||
--currentRow;
|
|
||||||
}
|
|
||||||
if (index.data(Models::MessageFeed::SentByMe).toBool()) {
|
|
||||||
painter.drawPixmap(option.rect.width() - avatarHeight - margin, y + halfMargin, icon.pixmap(avatarHeight, avatarHeight));
|
|
||||||
} else {
|
|
||||||
painter.drawPixmap(margin, y + halfMargin, icon.pixmap(avatarHeight, avatarHeight));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FeedView::verticalScrollbarValueChanged(int value)
|
void FeedView::verticalScrollbarValueChanged(int value)
|
||||||
{
|
{
|
||||||
vo = verticalScrollBar()->maximum() - value;
|
vo = verticalScrollBar()->maximum() - value;
|
||||||
|
@ -74,7 +74,6 @@ private:
|
|||||||
bool tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewItem& option, const QAbstractItemModel* model, uint32_t totalHeight);
|
bool tryToCalculateGeometriesWithNoScrollbars(const QStyleOptionViewItem& option, const QAbstractItemModel* model, uint32_t totalHeight);
|
||||||
void positionProgress();
|
void positionProgress();
|
||||||
void drawDateDevider(int top, const QDateTime& date, QPainter& painter);
|
void drawDateDevider(int top, const QDateTime& date, QPainter& painter);
|
||||||
void drawAvatar(const QModelIndex& index, const QStyleOptionViewItem& option, QPainter& painter);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Hint {
|
struct Hint {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
|
||||||
#include "messagedelegate.h"
|
#include "messagedelegate.h"
|
||||||
#include "messagefeed.h"
|
#include "messagefeed.h"
|
||||||
@ -104,7 +105,10 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
painter->fillRect(option.rect, option.palette.brush(QPalette::Inactive, QPalette::Highlight));
|
painter->fillRect(option.rect, option.palette.brush(QPalette::Inactive, QPalette::Highlight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ntds = needToDrawSender(index, data);
|
||||||
|
if (ntds || option.rect.y() < 1) {
|
||||||
|
paintAvatar(data, index, option, painter);
|
||||||
|
}
|
||||||
|
|
||||||
QStyleOptionViewItem opt = option;
|
QStyleOptionViewItem opt = option;
|
||||||
QRect messageRect = option.rect.adjusted(margin, margin / 2, -(avatarHeight + 2 * margin), -margin / 2);
|
QRect messageRect = option.rect.adjusted(margin, margin / 2, -(avatarHeight + 2 * margin), -margin / 2);
|
||||||
@ -122,13 +126,19 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.text).size();
|
messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.text).size();
|
||||||
bodySize = messageSize;
|
bodySize = messageSize;
|
||||||
}
|
}
|
||||||
messageSize.rheight() += nickMetrics.lineSpacing();
|
|
||||||
|
if (ntds) {
|
||||||
|
messageSize.rheight() += nickMetrics.lineSpacing();
|
||||||
|
}
|
||||||
messageSize.rheight() += dateMetrics.height();
|
messageSize.rheight() += dateMetrics.height();
|
||||||
QString dateString = data.date.toLocalTime().toString("hh:mm");
|
QString dateString = data.date.toLocalTime().toString("hh:mm");
|
||||||
|
|
||||||
if (messageSize.width() < opt.rect.width()) {
|
if (messageSize.width() < opt.rect.width()) {
|
||||||
QSize senderSize = nickMetrics.boundingRect(messageRect, 0, data.sender).size();
|
if (ntds) {
|
||||||
if (senderSize.width() > messageSize.width()) {
|
QSize senderSize = nickMetrics.boundingRect(messageRect, 0, data.sender).size();
|
||||||
messageSize.setWidth(senderSize.width());
|
if (senderSize.width() > messageSize.width()) {
|
||||||
|
messageSize.setWidth(senderSize.width());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QSize dateSize = dateMetrics.boundingRect(messageRect, 0, dateString).size();
|
QSize dateSize = dateMetrics.boundingRect(messageRect, 0, dateString).size();
|
||||||
int addition = 0;
|
int addition = 0;
|
||||||
@ -147,9 +157,11 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRect rect;
|
QRect rect;
|
||||||
painter->setFont(nickFont);
|
if (ntds) {
|
||||||
painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect);
|
painter->setFont(nickFont);
|
||||||
opt.rect.adjust(0, rect.height() + textMargin, 0, 0);
|
painter->drawText(opt.rect, opt.displayAlignment, data.sender, &rect);
|
||||||
|
opt.rect.adjust(0, rect.height() + textMargin, 0, 0);
|
||||||
|
}
|
||||||
painter->save();
|
painter->save();
|
||||||
switch (data.attach.state) {
|
switch (data.attach.state) {
|
||||||
case Models::none:
|
case Models::none:
|
||||||
@ -244,25 +256,75 @@ void MessageDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageDelegate::paintAvatar(const Models::FeedItem& data, const QModelIndex& index, const QStyleOptionViewItem& option, QPainter* painter) const
|
||||||
|
{
|
||||||
|
int currentRow = index.row();
|
||||||
|
int y = option.rect.y();
|
||||||
|
bool firstAttempt = true;
|
||||||
|
QIcon icon(data.avatar);
|
||||||
|
while (y < 0 && currentRow > 0) {
|
||||||
|
QRect rect;
|
||||||
|
if (firstAttempt) {
|
||||||
|
firstAttempt = false;
|
||||||
|
rect = option.rect;
|
||||||
|
} else {
|
||||||
|
QModelIndex ci = index.siblingAtRow(currentRow);
|
||||||
|
if (
|
||||||
|
(ci.data(Models::MessageFeed::Sender).toString() != data.sender) ||
|
||||||
|
(ci.data(Models::MessageFeed::Date).toDateTime().daysTo(data.date) != 0)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//TODO this is really bad, but for now I have no idea how else can I access the view;
|
||||||
|
const QAbstractItemView* view = static_cast<const QAbstractItemView*>(option.styleObject);
|
||||||
|
rect = view->visualRect(ci);
|
||||||
|
}
|
||||||
|
y = std::min(0, rect.bottom() - margin - avatarHeight);
|
||||||
|
--currentRow;
|
||||||
|
}
|
||||||
|
if (data.sentByMe) {
|
||||||
|
painter->drawPixmap(option.rect.width() - avatarHeight - margin, y + margin / 2, icon.pixmap(avatarHeight, avatarHeight));
|
||||||
|
} else {
|
||||||
|
painter->drawPixmap(margin, y + margin / 2, icon.pixmap(avatarHeight, avatarHeight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageDelegate::needToDrawAvatar(const QModelIndex& index, const Models::FeedItem& data, const QStyleOptionViewItem& option) const
|
||||||
|
{
|
||||||
|
return (option.rect.y() < 1) || needToDrawSender(index, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageDelegate::needToDrawSender(const QModelIndex& index, const Models::FeedItem& data) const
|
||||||
|
{
|
||||||
|
if (index.row() == index.model()->rowCount() - 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
QModelIndex prevIndex = index.siblingAtRow(index.row() + 1);
|
||||||
|
|
||||||
|
return (prevIndex.data(Models::MessageFeed::Sender).toString() != data.sender) ||
|
||||||
|
(prevIndex.data(Models::MessageFeed::Date).toDateTime().daysTo(data.date) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
QRect messageRect = option.rect.adjusted(0, margin / 2, -(avatarHeight + 3 * margin), -margin / 2);
|
QRect messageRect = option.rect.adjusted(0, margin / 2, -(avatarHeight + 3 * margin), -margin / 2);
|
||||||
QStyleOptionViewItem opt = option;
|
QStyleOptionViewItem opt = option;
|
||||||
opt.rect = messageRect;
|
opt.rect = messageRect;
|
||||||
QVariant va = index.data(Models::MessageFeed::Attach);
|
QVariant vi = index.data(Models::MessageFeed::Bulk);
|
||||||
Models::Attachment attach = qvariant_cast<Models::Attachment>(va);
|
Models::FeedItem data = qvariant_cast<Models::FeedItem>(vi);
|
||||||
QString body = index.data(Models::MessageFeed::Text).toString();
|
|
||||||
QSize messageSize(0, 0);
|
QSize messageSize(0, 0);
|
||||||
if (body.size() > 0) {
|
if (data.text.size() > 0) {
|
||||||
messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, body).size();
|
messageSize = bodyMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.text).size();
|
||||||
messageSize.rheight() += textMargin;
|
messageSize.rheight() += textMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (attach.state) {
|
switch (data.attach.state) {
|
||||||
case Models::none:
|
case Models::none:
|
||||||
break;
|
break;
|
||||||
case Models::uploading:
|
case Models::uploading:
|
||||||
messageSize.rheight() += Preview::calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
|
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin;
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Models::downloading:
|
case Models::downloading:
|
||||||
messageSize.rheight() += barHeight + textMargin;
|
messageSize.rheight() += barHeight + textMargin;
|
||||||
@ -272,25 +334,28 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
|||||||
break;
|
break;
|
||||||
case Models::ready:
|
case Models::ready:
|
||||||
case Models::local:
|
case Models::local:
|
||||||
messageSize.rheight() += Preview::calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
|
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin;
|
||||||
break;
|
break;
|
||||||
case Models::errorDownload:
|
case Models::errorDownload:
|
||||||
messageSize.rheight() += buttonHeight + textMargin;
|
messageSize.rheight() += buttonHeight + textMargin;
|
||||||
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, attach.error).size().height() + textMargin;
|
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size().height() + textMargin;
|
||||||
break;
|
break;
|
||||||
case Models::errorUpload:
|
case Models::errorUpload:
|
||||||
messageSize.rheight() += Preview::calculateAttachSize(attach.localPath, messageRect).height() + textMargin;
|
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin;
|
||||||
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, attach.error).size().height() + textMargin;
|
messageSize.rheight() += dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size().height() + textMargin;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
messageSize.rheight() += nickMetrics.lineSpacing();
|
if (needToDrawSender(index, data)) {
|
||||||
messageSize.rheight() += textMargin;
|
messageSize.rheight() += nickMetrics.lineSpacing();
|
||||||
|
messageSize.rheight() += textMargin;
|
||||||
|
}
|
||||||
|
|
||||||
messageSize.rheight() += dateMetrics.height() > statusIconSize ? dateMetrics.height() : statusIconSize;
|
messageSize.rheight() += dateMetrics.height() > statusIconSize ? dateMetrics.height() : statusIconSize;
|
||||||
|
|
||||||
if (messageSize.height() < avatarHeight) {
|
// if (messageSize.height() < avatarHeight) {
|
||||||
messageSize.setHeight(avatarHeight);
|
// messageSize.setHeight(avatarHeight);
|
||||||
}
|
// }
|
||||||
|
|
||||||
messageSize.rheight() += margin;
|
messageSize.rheight() += margin;
|
||||||
|
|
||||||
|
@ -65,12 +65,16 @@ protected:
|
|||||||
void paintBar(QProgressBar* bar, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const;
|
void paintBar(QProgressBar* bar, QPainter* painter, bool sentByMe, QStyleOptionViewItem& option) const;
|
||||||
void paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
void paintPreview(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
||||||
void paintComment(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
void paintComment(const Models::FeedItem& data, QPainter* painter, QStyleOptionViewItem& option) const;
|
||||||
|
void paintAvatar(const Models::FeedItem& data, const QModelIndex& index, const QStyleOptionViewItem& option, QPainter* painter) const;
|
||||||
QPushButton* getButton(const Models::FeedItem& data) const;
|
QPushButton* getButton(const Models::FeedItem& data) const;
|
||||||
QProgressBar* getBar(const Models::FeedItem& data) const;
|
QProgressBar* getBar(const Models::FeedItem& data) const;
|
||||||
QLabel* getStatusIcon(const Models::FeedItem& data) const;
|
QLabel* getStatusIcon(const Models::FeedItem& data) const;
|
||||||
QLabel* getPencilIcon(const Models::FeedItem& data) const;
|
QLabel* getPencilIcon(const Models::FeedItem& data) const;
|
||||||
QLabel* getBody(const Models::FeedItem& data) const;
|
QLabel* getBody(const Models::FeedItem& data) const;
|
||||||
void clearHelperWidget(const Models::FeedItem& data) const;
|
void clearHelperWidget(const Models::FeedItem& data) const;
|
||||||
|
|
||||||
|
bool needToDrawAvatar(const QModelIndex& index, const Models::FeedItem& data, const QStyleOptionViewItem& option) const;
|
||||||
|
bool needToDrawSender(const QModelIndex& index, const Models::FeedItem& data) const;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onButtonPushed() const;
|
void onButtonPushed() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user