Add a custom tooltip to display elided data in RDTreeViews

This commit is contained in:
baldurk
2017-06-09 18:41:21 +01:00
parent 1574103613
commit a292838f43
2 changed files with 121 additions and 0 deletions
@@ -23,9 +23,12 @@
******************************************************************************/
#include "RDTreeView.h"
#include <QLabel>
#include <QMouseEvent>
#include <QPainter>
#include <QProxyStyle>
#include <QStylePainter>
#include <QToolTip>
RDTreeViewDelegate::RDTreeViewDelegate(RDTreeView *view) : QStyledItemDelegate(view), m_View(view)
{
@@ -49,21 +52,115 @@ QSize RDTreeViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
return ret;
}
RDTipLabel::RDTipLabel() : QLabel(NULL)
{
int margin = style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, NULL, this);
int opacity = style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, NULL, this);
setWindowFlags(Qt::ToolTip);
setAttribute(Qt::WA_TransparentForMouseEvents);
setForegroundRole(QPalette::ToolTipText);
setBackgroundRole(QPalette::ToolTipBase);
setMargin(margin + 1);
setFrameStyle(QFrame::NoFrame);
setAlignment(Qt::AlignLeft);
setIndent(1);
setWindowOpacity(opacity / 255.0);
}
void RDTipLabel::paintEvent(QPaintEvent *ev)
{
QStylePainter p(this);
QStyleOptionFrame opt;
opt.init(this);
p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
p.end();
QLabel::paintEvent(ev);
}
void RDTipLabel::resizeEvent(QResizeEvent *e)
{
QStyleHintReturnMask frameMask;
QStyleOption option;
option.init(this);
if(style()->styleHint(QStyle::SH_ToolTip_Mask, &option, this, &frameMask))
setMask(frameMask.region);
QLabel::resizeEvent(e);
}
RDTreeView::RDTreeView(QWidget *parent) : QTreeView(NULL)
{
setMouseTracking(true);
setItemDelegate(new RDTreeViewDelegate(this));
m_ElidedTooltip = new RDTipLabel();
m_ElidedTooltip->hide();
}
RDTreeView::~RDTreeView()
{
delete m_ElidedTooltip;
}
void RDTreeView::mouseMoveEvent(QMouseEvent *e)
{
if(m_ElidedTooltip->isVisible() && !m_ElidedTooltip->geometry().contains(QCursor::pos()))
m_ElidedTooltip->hide();
m_currentHoverIndex = indexAt(e->pos());
QTreeView::mouseMoveEvent(e);
}
void RDTreeView::leaveEvent(QEvent *e)
{
if(m_ElidedTooltip->isVisible() && !m_ElidedTooltip->geometry().contains(QCursor::pos()))
m_ElidedTooltip->hide();
m_currentHoverIndex = QModelIndex();
QTreeView::leaveEvent(e);
}
bool RDTreeView::viewportEvent(QEvent *event)
{
if(m_TooltipElidedItems && event->type() == QEvent::ToolTip)
{
QHelpEvent *he = (QHelpEvent *)event;
QModelIndex index = indexAt(he->pos());
QAbstractItemDelegate *delegate = itemDelegate(index);
if(delegate)
{
QStyleOptionViewItem option;
option.initFrom(this);
option.rect = visualRect(index);
// delegates get first dibs at processing the event
bool ret = delegate->helpEvent(he, this, option, index);
if(ret)
return true;
QSize desiredSize = delegate->sizeHint(option, index);
if(desiredSize.width() > option.rect.width())
{
const QString fullText = index.data(Qt::DisplayRole).toString();
if(!fullText.isEmpty())
{
// need to use a custom label tooltip since the QToolTip freaks out as we're placing it
// underneath the cursor instead of next to it (so that the tooltip lines up over the row)
m_ElidedTooltip->move(viewport()->mapToGlobal(option.rect.topLeft()));
m_ElidedTooltip->setText(fullText);
m_ElidedTooltip->show();
}
}
}
}
return QTreeView::viewportEvent(event);
}
void RDTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+24
View File
@@ -24,6 +24,7 @@
#pragma once
#include <QLabel>
#include <QStyledItemDelegate>
#include <QTreeView>
@@ -41,22 +42,42 @@ public:
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
class RDTipLabel : public QLabel
{
private:
Q_OBJECT
int m_TooltipMargin = 0;
public:
explicit RDTipLabel();
int tipMargin() { return m_TooltipMargin; }
protected:
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *);
};
class RDTreeView : public QTreeView
{
Q_OBJECT
public:
explicit RDTreeView(QWidget *parent = 0);
virtual ~RDTreeView();
void showBranches() { m_VisibleBranches = true; }
void hideBranches() { m_VisibleBranches = false; }
void showGridLines() { m_VisibleGridLines = true; }
void hideGridLines() { m_VisibleGridLines = false; }
void setTooltipElidedItems(bool tool) { m_TooltipElidedItems = tool; }
bool tooltipElidedItems() { return m_TooltipElidedItems; }
void setItemVerticalMargin(int vertical) { m_VertMargin = vertical; }
int verticalItemMargin() { return m_VertMargin; }
protected:
void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
void mouseMoveEvent(QMouseEvent *e) override;
void leaveEvent(QEvent *e) override;
bool viewportEvent(QEvent *event) override;
void drawRow(QPainter *painter, const QStyleOptionViewItem &options,
const QModelIndex &index) const override;
@@ -69,6 +90,9 @@ protected:
private:
bool m_VisibleBranches = true;
bool m_VisibleGridLines = true;
bool m_TooltipElidedItems = true;
RDTipLabel *m_ElidedTooltip;
int m_VertMargin = 6;