moved elided label paint method to static so that it can be used by other item delegates

This commit is contained in:
csoler 2020-02-18 10:50:55 +01:00
parent e4dc72169c
commit 09c5d93631
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
4 changed files with 163 additions and 129 deletions

View File

@ -74,19 +74,9 @@ void ElidedLabel::clear()
void ElidedLabel::paintEvent(QPaintEvent *event)
{
QLabel::paintEvent(event);
QList<QPair<QTextLine,QPoint> > lLines;
QString elidedLastLine = "";
QPainter painter(this);
QFontMetrics fontMetrics = painter.fontMetrics();
QRect cr = contentsRect();
cr.adjust(margin(), margin(), -margin(), -margin());
bool didElide = false;
QChar ellipsisChar(0x2026);//= "…"
int lineSpacing = fontMetrics.lineSpacing();
int y = 0;
QString plainText = "";
QString plainText = "";
if (mOnlyPlainText)
{
plainText = mContent;
@ -95,13 +85,38 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
td.setHtml(mContent);
plainText = td.toPlainText();
}
QRect cr(contentsRect());
cr.adjust(margin(), margin(), -margin(), -margin());
bool didElide = paintElidedLine(painter,plainText,cr,alignment(),wordWrap(),true,mRectElision);
//Send signal if changed
if (didElide != mElided)
{
mElided = didElide;
emit elisionChanged(didElide);
}
}
bool ElidedLabel::paintElidedLine(QPainter& painter,QString plainText,const QRect& cr,Qt::Alignment alignment,bool wordWrap,bool drawRoundRect,QRect& rectElision)
{
QList<QPair<QTextLine,QPoint> > lLines;
QString elidedLastLine = "";
QFontMetrics fontMetrics = painter.fontMetrics();
bool didElide = false;
QChar ellipsisChar(0x2026);//= "…"
int lineSpacing = fontMetrics.lineSpacing();
int y = 0;
plainText = plainText.replace("\n",QChar(QChar::LineSeparator));
plainText = plainText.replace("\r",QChar(QChar::LineSeparator));
QTextLayout textLayout(plainText, painter.font());
QTextOption to = textLayout.textOption();
to.setAlignment(alignment());
to.setWrapMode(wordWrap() ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
to.setAlignment(alignment);
to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
textLayout.setTextOption(to);
textLayout.beginLayout();
@ -115,7 +130,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
line.setLineWidth(cr.width());
int nextLineY = y + lineSpacing;
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap()) {
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap) {
//Line written normaly, next line will too
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
y = nextLineY;
@ -123,8 +138,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
//The next line can't be written.
QString lastLine = plainText.mid(line.textStart()).split(QChar(QChar::LineSeparator)).at(0);
QTextLine lineEnd = textLayout.createLine();
if (!lineEnd.isValid() && (wordWrap()
|| (fontMetrics.width(lastLine) < cr.width()))) {
if (!lineEnd.isValid() && (wordWrap || (fontMetrics.width(lastLine) < cr.width()))) {
//No more text for next line so this one is OK
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
elidedLastLine="";
@ -150,11 +164,11 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
if (didElide) iHeight += lineSpacing;
//Compute lines translation with alignment
if (alignment() & Qt::AlignTop)
if (alignment & Qt::AlignTop)
iTransY = 0;
if (alignment() & Qt::AlignBottom)
if (alignment & Qt::AlignBottom)
iTransY = cr.height() - iHeight;
if (alignment() & Qt::AlignVCenter)
if (alignment & Qt::AlignVCenter)
iTransY = (cr.height() - iHeight) / 2;
QPair<QTextLine,QPoint> pair;
@ -166,7 +180,8 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
}
//Print last elided line
if (didElide) {
if (didElide)
{
int width = fontMetrics.width(elidedLastLine);
if (lastPos.y() == -1){
y = iTransY;// Only one line
@ -175,32 +190,35 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
}
if (width < cr.width()){
//Text don't taking all line (with line break), so align it
if (alignment() & Qt::AlignLeft)
if (alignment & Qt::AlignLeft)
iTransX = 0;
if (alignment() & Qt::AlignRight)
if (alignment & Qt::AlignRight)
iTransX = cr.width() - width;
if (alignment() & Qt::AlignHCenter)
if (alignment & Qt::AlignHCenter)
iTransX = (cr.width() - width) / 2;
if (alignment() & Qt::AlignJustify)
if (alignment & Qt::AlignJustify)
iTransX = 0;
}
painter.drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine);
//Draw button to get ToolTip
mRectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left()
, y + cr.top()
, fontMetrics.width(ellipsisChar)
, fontMetrics.height() - 1);
painter.drawRoundRect(mRectElision);
} else {
mRectElision = QRect();
}
//Send signal if changed
if (didElide != mElided) {
mElided = didElide;
emit elisionChanged(didElide);
if(drawRoundRect)
{
rectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left()
, y + cr.top()
, fontMetrics.width(ellipsisChar)
, fontMetrics.height() - 1);
painter.drawRoundRect(rectElision);
}
else
rectElision = QRect();
}
else
rectElision = QRect();
return didElide;
}
void ElidedLabel::mousePressEvent(QMouseEvent *ev)

View File

@ -48,6 +48,8 @@ public:
QColor textColor() const { return mTextColor; }
void setTextColor(const QColor &color);
static bool paintElidedLine(QPainter& painter, QString plainText, const QRect &cr, Qt::Alignment alignment, bool wordWrap, bool drawRoundRect, QRect &rectElision);
public slots:
void setText(const QString &text);
void setOnlyPlainText(const bool &value);

View File

@ -178,3 +178,104 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
return RSTreeWidgetItem::data(column, role);
}
QSize GxsIdTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::sizeHint(option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
const QRect r = option.rect;
QString str;
QList<QIcon> icons;
QString comment;
QFontMetricsF fm(option.font);
float f = fm.height();
QIcon icon ;
if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
else
icon = *icons.begin();
QPixmap pix = icon.pixmap(r.size());
return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height()));
}
void GxsIdTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const
{
if(!index.isValid())
{
std::cerr << "(EE) attempt to draw an invalid index." << std::endl;
return ;
}
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::paint(painter,option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
// draw default item
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
QRect r = option.rect;
QString str;
QString comment;
QFontMetricsF fm(painter->font());
float f = fm.height();
QIcon icon ;
if(id.isNull())
{
str = tr("[Notification]");
icon = QIcon(":/icons/logo_128.png");
}
else if(! computeNameIconAndComment(id,str,icon,comment))
if(mReloadPeriod > 3)
{
str = tr("[Unknown]");
icon = QIcon();
}
else
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
QPixmap pix = icon.pixmap(r.size());
const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2);
// draw pixmap at center of item
painter->drawPixmap(r.topLeft() + p, pix);
//painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str);
//cr.adjust(margin(), margin(), -margin(), -margin());
QRect mRectElision;
r.adjust(pix.height()+f,(r.height()-f)/2.0,0,0);
bool didElide = ElidedLabel::paintElidedLine(*painter,str,r,Qt::AlignLeft,false,false,mRectElision);
}

View File

@ -24,10 +24,11 @@
#include <QPainter>
#include <QTimer>
#include <QApplication>
#include <retroshare/rsidentity.h>
#include <retroshare/rspeers.h>
#include "retroshare/rsidentity.h"
#include "retroshare/rspeers.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "gui/common/ElidedLabel.h"
#include "gui/gxs/GxsIdDetails.h"
/*****
@ -88,96 +89,8 @@ public:
mReloadPeriod = 0;
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::sizeHint(option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
const QRect r = option.rect;
QString str;
QList<QIcon> icons;
QString comment;
QFontMetricsF fm(option.font);
float f = fm.height();
QIcon icon ;
if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
else
icon = *icons.begin();
QPixmap pix = icon.pixmap(r.size());
return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height()));
}
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override
{
if(!index.isValid())
{
std::cerr << "(EE) attempt to draw an invalid index." << std::endl;
return ;
}
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::paint(painter,option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
// draw default item
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
const QRect r = option.rect;
QString str;
QString comment;
QFontMetricsF fm(painter->font());
float f = fm.height();
QIcon icon ;
if(id.isNull())
{
str = tr("[Notification]");
icon = QIcon(":/icons/logo_128.png");
}
else if(! computeNameIconAndComment(id,str,icon,comment))
if(mReloadPeriod > 3)
{
str = tr("[Unknown]");
icon = QIcon();
}
else
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
QPixmap pix = icon.pixmap(r.size());
const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2);
// draw pixmap at center of item
painter->drawPixmap(r.topLeft() + p, pix);
painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str);
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
void launchAsyncLoading() const
{