mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-06 21:58:57 -04:00
moved elided label paint method to static so that it can be used by other item delegates
This commit is contained in:
parent
e4dc72169c
commit
09c5d93631
4 changed files with 163 additions and 129 deletions
|
@ -74,19 +74,9 @@ void ElidedLabel::clear()
|
||||||
void ElidedLabel::paintEvent(QPaintEvent *event)
|
void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QLabel::paintEvent(event);
|
QLabel::paintEvent(event);
|
||||||
QList<QPair<QTextLine,QPoint> > lLines;
|
|
||||||
QString elidedLastLine = "";
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
QFontMetrics fontMetrics = painter.fontMetrics();
|
QString plainText = "";
|
||||||
QRect cr = contentsRect();
|
|
||||||
cr.adjust(margin(), margin(), -margin(), -margin());
|
|
||||||
|
|
||||||
bool didElide = false;
|
|
||||||
QChar ellipsisChar(0x2026);//= "…"
|
|
||||||
int lineSpacing = fontMetrics.lineSpacing();
|
|
||||||
int y = 0;
|
|
||||||
|
|
||||||
QString plainText = "";
|
|
||||||
if (mOnlyPlainText)
|
if (mOnlyPlainText)
|
||||||
{
|
{
|
||||||
plainText = mContent;
|
plainText = mContent;
|
||||||
|
@ -95,13 +85,38 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
td.setHtml(mContent);
|
td.setHtml(mContent);
|
||||||
plainText = td.toPlainText();
|
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("\n",QChar(QChar::LineSeparator));
|
||||||
plainText = plainText.replace("\r",QChar(QChar::LineSeparator));
|
plainText = plainText.replace("\r",QChar(QChar::LineSeparator));
|
||||||
|
|
||||||
QTextLayout textLayout(plainText, painter.font());
|
QTextLayout textLayout(plainText, painter.font());
|
||||||
QTextOption to = textLayout.textOption();
|
QTextOption to = textLayout.textOption();
|
||||||
to.setAlignment(alignment());
|
to.setAlignment(alignment);
|
||||||
to.setWrapMode(wordWrap() ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
|
to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
|
||||||
textLayout.setTextOption(to);
|
textLayout.setTextOption(to);
|
||||||
|
|
||||||
textLayout.beginLayout();
|
textLayout.beginLayout();
|
||||||
|
@ -115,7 +130,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
line.setLineWidth(cr.width());
|
line.setLineWidth(cr.width());
|
||||||
int nextLineY = y + lineSpacing;
|
int nextLineY = y + lineSpacing;
|
||||||
|
|
||||||
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap()) {
|
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap) {
|
||||||
//Line written normaly, next line will too
|
//Line written normaly, next line will too
|
||||||
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
|
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
|
||||||
y = nextLineY;
|
y = nextLineY;
|
||||||
|
@ -123,8 +138,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
//The next line can't be written.
|
//The next line can't be written.
|
||||||
QString lastLine = plainText.mid(line.textStart()).split(QChar(QChar::LineSeparator)).at(0);
|
QString lastLine = plainText.mid(line.textStart()).split(QChar(QChar::LineSeparator)).at(0);
|
||||||
QTextLine lineEnd = textLayout.createLine();
|
QTextLine lineEnd = textLayout.createLine();
|
||||||
if (!lineEnd.isValid() && (wordWrap()
|
if (!lineEnd.isValid() && (wordWrap || (fontMetrics.width(lastLine) < cr.width()))) {
|
||||||
|| (fontMetrics.width(lastLine) < cr.width()))) {
|
|
||||||
//No more text for next line so this one is OK
|
//No more text for next line so this one is OK
|
||||||
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
|
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
|
||||||
elidedLastLine="";
|
elidedLastLine="";
|
||||||
|
@ -150,11 +164,11 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
if (didElide) iHeight += lineSpacing;
|
if (didElide) iHeight += lineSpacing;
|
||||||
|
|
||||||
//Compute lines translation with alignment
|
//Compute lines translation with alignment
|
||||||
if (alignment() & Qt::AlignTop)
|
if (alignment & Qt::AlignTop)
|
||||||
iTransY = 0;
|
iTransY = 0;
|
||||||
if (alignment() & Qt::AlignBottom)
|
if (alignment & Qt::AlignBottom)
|
||||||
iTransY = cr.height() - iHeight;
|
iTransY = cr.height() - iHeight;
|
||||||
if (alignment() & Qt::AlignVCenter)
|
if (alignment & Qt::AlignVCenter)
|
||||||
iTransY = (cr.height() - iHeight) / 2;
|
iTransY = (cr.height() - iHeight) / 2;
|
||||||
|
|
||||||
QPair<QTextLine,QPoint> pair;
|
QPair<QTextLine,QPoint> pair;
|
||||||
|
@ -166,7 +180,8 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Print last elided line
|
//Print last elided line
|
||||||
if (didElide) {
|
if (didElide)
|
||||||
|
{
|
||||||
int width = fontMetrics.width(elidedLastLine);
|
int width = fontMetrics.width(elidedLastLine);
|
||||||
if (lastPos.y() == -1){
|
if (lastPos.y() == -1){
|
||||||
y = iTransY;// Only one line
|
y = iTransY;// Only one line
|
||||||
|
@ -175,32 +190,35 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
|
||||||
}
|
}
|
||||||
if (width < cr.width()){
|
if (width < cr.width()){
|
||||||
//Text don't taking all line (with line break), so align it
|
//Text don't taking all line (with line break), so align it
|
||||||
if (alignment() & Qt::AlignLeft)
|
if (alignment & Qt::AlignLeft)
|
||||||
iTransX = 0;
|
iTransX = 0;
|
||||||
if (alignment() & Qt::AlignRight)
|
if (alignment & Qt::AlignRight)
|
||||||
iTransX = cr.width() - width;
|
iTransX = cr.width() - width;
|
||||||
if (alignment() & Qt::AlignHCenter)
|
if (alignment & Qt::AlignHCenter)
|
||||||
iTransX = (cr.width() - width) / 2;
|
iTransX = (cr.width() - width) / 2;
|
||||||
if (alignment() & Qt::AlignJustify)
|
if (alignment & Qt::AlignJustify)
|
||||||
iTransX = 0;
|
iTransX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine);
|
painter.drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine);
|
||||||
//Draw button to get ToolTip
|
//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(drawRoundRect)
|
||||||
if (didElide != mElided) {
|
{
|
||||||
mElided = didElide;
|
rectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left()
|
||||||
emit elisionChanged(didElide);
|
, 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)
|
void ElidedLabel::mousePressEvent(QMouseEvent *ev)
|
||||||
|
|
|
@ -48,6 +48,8 @@ public:
|
||||||
QColor textColor() const { return mTextColor; }
|
QColor textColor() const { return mTextColor; }
|
||||||
void setTextColor(const QColor &color);
|
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:
|
public slots:
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
void setOnlyPlainText(const bool &value);
|
void setOnlyPlainText(const bool &value);
|
||||||
|
|
|
@ -178,3 +178,104 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
|
||||||
|
|
||||||
return RSTreeWidgetItem::data(column, role);
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <retroshare/rsidentity.h>
|
#include "retroshare/rsidentity.h"
|
||||||
#include <retroshare/rspeers.h>
|
#include "retroshare/rspeers.h"
|
||||||
|
|
||||||
#include "gui/common/RSTreeWidgetItem.h"
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
|
#include "gui/common/ElidedLabel.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
|
||||||
/*****
|
/*****
|
||||||
|
@ -88,96 +89,8 @@ public:
|
||||||
mReloadPeriod = 0;
|
mReloadPeriod = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
{
|
void paint(QPainter *painter, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void launchAsyncLoading() const
|
void launchAsyncLoading() const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue