From bbff0fce1c21b755e84ae0796d5b5090c15fa773 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 4 May 2017 20:33:49 +0100 Subject: [PATCH] Implement row colouring and tree colouring in event browser. * Also do custom painting of branches to do proper full-row colouring instead of leaving an ugly gap around the tree controls. --- qrenderdoc/Code/QRDUtils.cpp | 25 +++++ qrenderdoc/Code/QRDUtils.h | 2 + qrenderdoc/Widgets/Extended/RDTreeWidget.cpp | 103 +++++++++++++++++++ qrenderdoc/Widgets/Extended/RDTreeWidget.h | 9 ++ qrenderdoc/Windows/EventBrowser.cpp | 34 ++++-- 5 files changed, 167 insertions(+), 6 deletions(-) diff --git a/qrenderdoc/Code/QRDUtils.cpp b/qrenderdoc/Code/QRDUtils.cpp index b9b8da778..26b9289cd 100644 --- a/qrenderdoc/Code/QRDUtils.cpp +++ b/qrenderdoc/Code/QRDUtils.cpp @@ -932,3 +932,28 @@ QString GetSystemUsername() return username; } + +static float getLuminance(const QColor &col) +{ + return (float)(0.2126 * qPow(col.redF(), 2.2) + 0.7152 * qPow(col.greenF(), 2.2) + + 0.0722 * qPow(col.blueF(), 2.2)); +} + +QColor contrastingColor(const QColor &col, const QColor &defaultCol) +{ + float backLum = getLuminance(col); + float textLum = getLuminance(defaultCol); + + bool backDark = backLum < 0.2f; + bool textDark = textLum < 0.2f; + + // if they're contrasting, use the text colour desired + if(backDark != textDark) + return defaultCol; + + // otherwise pick a contrasting colour + if(backDark) + return QColor(Qt::white); + else + return QColor(Qt::black); +} diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index ec2d5c4c5..83e450ace 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -862,3 +862,5 @@ void ShowProgressDialog(QWidget *window, const QString &labelText, ProgressFinis ProgressUpdateMethod update = ProgressUpdateMethod()); QString GetSystemUsername(); + +QColor contrastingColor(const QColor &col, const QColor &defaultCol); diff --git a/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp b/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp index 412e35c03..1dd43a55b 100644 --- a/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp +++ b/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include class RDTreeWidgetModel : public QAbstractItemModel { @@ -609,6 +612,106 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e) QTreeView::keyPressEvent(e); } +void RDTreeWidget::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const +{ + // we do our own custom branch rendering to ensure the backgrounds for the +/- markers are filled + // (as otherwise they don't show up well over selection or background fills) as well as to draw + // any vertical branch colors. + + painter->save(); + + // start at the left-most side of the rect + QRect branchRect(rect.left(), rect.top(), indentation(), rect.height()); + + RDTreeWidgetItem *item = m_model->itemForIndex(index); + + // first draw the coloured lines - we're only interested in parents for this, so push all the + // parents onto a stack + QStack parents; + + RDTreeWidgetItem *parent = item->parent(); + + while(parent && parent != m_root) + { + parents.push(parent); + parent = parent->parent(); + } + + // fill in the background behind the lines for the whole row, since by default it doesn't show up + // behind the tree lines. There's SH_ItemView_ShowDecorationSelected which controls that for the + // selection highlight but that requires a proxy style and there's no equivalent for the + // background colour. + // + // Instead we just manually fill the background colour, and handle the highlight colour when + // appropriate. + + QRect allLinesRect(rect.left(), rect.top(), rect.left() + parents.count() * indentation() + 1, + rect.height()); + if(selectionModel()->isSelected(index)) + { + QPalette::ColorGroup group = QPalette::Normal; + + if(!isEnabled()) + group = QPalette::Disabled; + else if(!hasFocus()) + group = QPalette::Inactive; + + painter->fillRect(allLinesRect, palette().brush(group, QPalette::Highlight)); + } + else if(item->m_back != QBrush()) + { + painter->fillRect(allLinesRect, item->m_back); + } + + // we now iterate from the top-most parent down, moving in from the left + QPen oldPen = painter->pen(); + while(!parents.isEmpty()) + { + parent = parents.pop(); + + if(parent->m_treeCol.isValid()) + { + // draw a centred pen vertically down the middle of branchRect + + painter->setPen(QPen(QBrush(parent->m_treeCol), parent->m_treeColWidth)); + + QPointF topCentre = QRectF(branchRect).center(); + QPointF bottomCentre = topCentre; + + topCentre.setY(branchRect.top()); + bottomCentre.setY(branchRect.bottom()); + + painter->drawLine(topCentre, bottomCentre); + } + + branchRect.moveLeft(branchRect.left() + indentation()); + } + painter->setPen(oldPen); + + // branchRect is now over the box/lines for the current item. + + // draw a rect of QPalette Base color behind the branch indicator if we have children, since by + // default there might not be one and the indicator won't always show up well over the background + // color + /* + if(item->childCount() > 0) + { + // TODO find a portable rect + const int radius = 9 / 2; + QPoint topleft = branchRect.center(); + topleft.setX(topleft.x() - radius + 1); + topleft.setY(topleft.y() - radius + 1); + + painter->fillRect(QRect(topleft, QSize(radius * 2, radius * 2)), + palette().brush(QPalette::Base)); + } + */ + + painter->restore(); + + QTreeView::drawBranches(painter, rect, index); +} + void RDTreeWidget::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { emit itemSelectionChanged(); diff --git a/qrenderdoc/Widgets/Extended/RDTreeWidget.h b/qrenderdoc/Widgets/Extended/RDTreeWidget.h index a66733232..9e4084c19 100644 --- a/qrenderdoc/Widgets/Extended/RDTreeWidget.h +++ b/qrenderdoc/Widgets/Extended/RDTreeWidget.h @@ -72,6 +72,11 @@ public: m_italic = italic; dataChanged(Qt::FontRole); } + inline void setTreeColor(QColor col, float pixels) + { + m_treeCol = col; + m_treeColWidth = pixels; + } inline void setBackgroundColor(QColor background) { setBackground(QBrush(background)); } inline void setForegroundColor(QColor foreground) { setForeground(QBrush(foreground)); } inline void setBackground(QBrush background) @@ -132,6 +137,8 @@ private: QString m_tooltip; bool m_bold = false; bool m_italic = false; + QColor m_treeCol; + float m_treeColWidth = 0.0f; QBrush m_back; QBrush m_fore; QVariant m_tag; @@ -201,6 +208,8 @@ private: void focusOutEvent(QFocusEvent *event) override; void keyPressEvent(QKeyEvent *e) override; + void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override; + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; diff --git a/qrenderdoc/Windows/EventBrowser.cpp b/qrenderdoc/Windows/EventBrowser.cpp index a6ac5141a..9767660f6 100644 --- a/qrenderdoc/Windows/EventBrowser.cpp +++ b/qrenderdoc/Windows/EventBrowser.cpp @@ -202,17 +202,19 @@ uint EventBrowser::AddDrawcalls(RDTreeWidgetItem *parent, for(int32_t i = 0; i < draws.count; i++) { - RDTreeWidgetItem *child = new RDTreeWidgetItem( - {ToQStr(draws[i].name), QFormatStr("%1").arg(draws[i].eventID), lit("0.0")}); + const DrawcallDescription &d = draws[i]; - lastEID = AddDrawcalls(child, draws[i].children); + RDTreeWidgetItem *child = + new RDTreeWidgetItem({ToQStr(d.name), QFormatStr("%1").arg(d.eventID), lit("0.0")}); - if(lastEID > draws[i].eventID) - child->setText(COL_EID, QFormatStr("%1-%2").arg(draws[i].eventID).arg(lastEID)); + lastEID = AddDrawcalls(child, d.children); + + if(lastEID > d.eventID) + child->setText(COL_EID, QFormatStr("%1-%2").arg(d.eventID).arg(lastEID)); if(lastEID == 0) { - lastEID = draws[i].eventID; + lastEID = d.eventID; if((draws[i].flags & DrawFlags::SetMarker) && i + 1 < draws.count) lastEID = draws[i + 1].eventID; @@ -220,6 +222,26 @@ uint EventBrowser::AddDrawcalls(RDTreeWidgetItem *parent, child->setTag(QVariant::fromValue(EventItemTag(draws[i].eventID, lastEID))); + if(m_Ctx.Config().EventBrowser_ApplyColors) + { + // if alpha isn't 0, assume the colour is valid + if((d.flags & (DrawFlags::PushMarker | DrawFlags::SetMarker)) && d.markerColor[3] > 0.0f) + { + QColor col = QColor::fromRgb( + qRgb(d.markerColor[0] * 255.0f, d.markerColor[1] * 255.0f, d.markerColor[2] * 255.0f)); + + child->setTreeColor(col, 3.0f); + + if(m_Ctx.Config().EventBrowser_ColorEventRow) + { + QColor textCol = ui->events->palette().color(QPalette::Text); + + child->setBackgroundColor(col); + child->setForegroundColor(contrastingColor(col, textCol)); + } + } + } + parent->addChild(child); }