return static_cast<float>(value);\r
}\r
\r
-//-----------------------------------------------------------------------------\r
+//=============================================================================\r
+glvdebug_QTimelineItemDelegate::glvdebug_QTimelineItemDelegate(QObject *parent)\r
+ : QAbstractItemDelegate(parent)\r
+{\r
+ assert(parent != NULL);\r
+}\r
+\r
+glvdebug_QTimelineItemDelegate::~glvdebug_QTimelineItemDelegate()\r
+{\r
+\r
+}\r
+\r
+void glvdebug_QTimelineItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const\r
+{\r
+ glv_trace_packet_header* pHeader = (glv_trace_packet_header*)index.internalPointer();\r
+\r
+ if (pHeader->entrypoint_end_time <= pHeader->entrypoint_begin_time)\r
+ {\r
+ return;\r
+ }\r
+\r
+ float duration = u64ToFloat(pHeader->entrypoint_end_time - pHeader->entrypoint_begin_time);\r
+\r
+ painter->save();\r
+ {\r
+ glvdebug_QTimelineView* pTimeline = (glvdebug_QTimelineView*)parent();\r
+ if (pTimeline != NULL)\r
+ {\r
+ QRectF rect = pTimeline->itemRect(index);\r
+\r
+ if (rect.isValid())\r
+ {\r
+ float durationRatio = duration / pTimeline->getMaxItemDuration();\r
+ int intensity = std::min(255, (int)(durationRatio * 255.0f));\r
+ QColor color(intensity, 255-intensity, 0);\r
+ painter->setBrush(QBrush(color));\r
+ painter->setPen(color);\r
+\r
+ painter->drawRect(rect);\r
+ }\r
+ }\r
+ }\r
+\r
+ painter->restore();\r
+}\r
+\r
+QSize glvdebug_QTimelineItemDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index) const\r
+{\r
+ QSize size;\r
+\r
+ glvdebug_QTimelineView* pTimeline = (glvdebug_QTimelineView*)parent();\r
+ if (pTimeline != NULL)\r
+ {\r
+ QRectF rect = pTimeline->itemRect(index);\r
+\r
+ size = rect.toRect().size();\r
+ }\r
+ return QSize();\r
+}\r
+\r
+//=============================================================================\r
glvdebug_QTimelineView::glvdebug_QTimelineView(QWidget *parent) :\r
QAbstractItemView(parent),\r
m_maxItemDuration(0),\r
m_threadHeight(0),\r
- m_pPixmap(NULL)\r
+ m_pPixmap(NULL),\r
+ m_itemDelegate(this)\r
{\r
horizontalScrollBar()->setRange(0,0);\r
verticalScrollBar()->setRange(0,0);\r
\r
m_background = QBrush(QColor(200,200,200));\r
- m_trianglePen = QPen(Qt::black);\r
+ m_trianglePen = QPen(Qt::darkGray);\r
m_trianglePen.setWidth(1);\r
m_textPen = QPen(Qt::white);\r
m_textFont.setPixelSize(50);\r
return;\r
}\r
\r
+ setItemDelegate(&m_itemDelegate);\r
+\r
int numRows = model()->rowCount();\r
for (int i = 0; i < numRows; i++)\r
{\r
uint64_t duration = pHeader->entrypoint_end_time - pHeader->entrypoint_begin_time;\r
\r
float leftOffset = scalePositionHorizontally(pHeader->entrypoint_begin_time);\r
+ leftOffset += 10; // leaves a small margin on the left side;\r
float scaledWidth = scaleDurationHorizontally(duration);\r
\r
// Clamp the item so that it is 1 pixel wide.\r
QModelIndex index = model()->index(r, glvdebug_QTraceFileModel::Column_EntrypointName);\r
QRectF rectf = itemRect(index);\r
QRect rect = rectf.toRect();\r
- int gap = 10;\r
- if (rect.contains(wx-gap, wy))\r
+ if (rect.contains(wx, wy))\r
{\r
return index;\r
}\r
{\r
int numThreads = threadList.count();\r
\r
- //int left = rect.x();\r
- //int top = rect.y();\r
- int width = rect.width();\r
int height = (numThreads > 0) ? rect.height() / numThreads : rect.height();\r
\r
for (int i = 0; i < numThreads; i++)\r
{\r
int threadTop = (i*height);\r
\r
- painter->save();\r
-\r
- // move painter to top corner for this thread\r
- painter->translate(0, threadTop);\r
-\r
- painter->drawText(0, 15, QString("Thread %1").arg(threadList[i]));\r
-\r
- // translate drawing to vertical center of rect\r
- painter->translate(0, height/2);\r
-\r
- // everything will have a small gap on the left and right sides\r
- painter->translate(gap, 0);\r
-\r
- // draw the actual timeline\r
- int lineLength = width-2*gap;\r
- painter->drawLine(0,0, lineLength, 0);\r
+ painter->drawText(0, threadTop + 15, QString("Thread %1").arg(threadList[i]));\r
\r
- painter->restore();\r
+ // draw the timeline in the middle of this thread's area\r
+ int lineStart = gap;\r
+ int lineEnd = m_lineLength + lineStart;\r
+ int lineY = threadTop + height/2;\r
+ painter->drawLine(lineStart, lineY, lineEnd, lineY);\r
}\r
}\r
\r
}\r
\r
int gap = 10;\r
- int arrowHeight = 10;\r
- int arrowTop = m_threadHeight-gap-arrowHeight;\r
- int arrowHalfWidth = 3;\r
+ int arrowHeight = 12;\r
+ int arrowTop = 2;\r
+ int arrowHalfWidth = 4;\r
m_lineLength = event->rect().width()-2*gap;\r
\r
QPolygon triangle(3);\r
pixmapPainter.fillRect(event->rect(), m_background);\r
drawBaseTimelines(&pixmapPainter, event->rect(), threadList, gap);\r
\r
- // translate sideways to insert a small gap on the left side\r
- pixmapPainter.translate(gap, 0);\r
-\r
m_horizontalScale = (float)m_lineLength / u64ToFloat(m_rawEndTime - m_rawStartTime);\r
\r
if (model() != NULL)\r
return;\r
}\r
\r
- painter->save();\r
+ // draw current api call marker\r
+ int currentIndexRow = currentIndex().row();\r
+ if (currentIndexRow >= 0)\r
{\r
- // translate to leave a small gap on the left\r
- painter->translate(gap, 0);\r
-\r
- int currentIndexRow = currentIndex().row();\r
- if (currentIndexRow >= 0)\r
- {\r
- // draw current api call marker\r
- QModelIndex index = model()->index(currentIndexRow, glvdebug_QTraceFileModel::Column_EntrypointName);\r
- glv_trace_packet_header* pHeader = (glv_trace_packet_header*)index.internalPointer();\r
-\r
- // Overlay a black rectangle around the current item.\r
- // For more information on how rects are drawn as outlines,\r
- // see here: http://qt-project.org/doc/qt-4.8/qrectf.html#rendering\r
- int penWidth = 2;\r
- int penWidthHalf = 1;\r
- QPen blackPen(Qt::black);\r
- blackPen.setWidth(penWidth);\r
- blackPen.setJoinStyle(Qt::MiterJoin);\r
- painter->setPen(blackPen);\r
-\r
- // Don't fill the rectangle\r
- painter->setBrush(Qt::NoBrush);\r
-\r
- QRectF rect = itemRect(index);\r
- rect.adjust(-penWidthHalf, -penWidthHalf, penWidthHalf-1, penWidthHalf+1);\r
- painter->drawRect(rect);\r
-\r
- // translate down to the proper thread\r
- int threadIndex = m_threadIdList.indexOf(pHeader->thread_id);\r
- painter->translate(0, m_threadHeight * threadIndex);\r
-\r
- // Draw marker at midpoint of call duration.\r
- uint64_t halfDuration = (pHeader->entrypoint_end_time - pHeader->entrypoint_begin_time) / 2;\r
- drawCurrentApiCallMarker(painter, triangle, pHeader->entrypoint_begin_time + halfDuration);\r
- }\r
+ // Overlay a black rectangle around the current item.\r
+ // For more information on how rects are drawn as outlines,\r
+ // see here: http://qt-project.org/doc/qt-4.8/qrectf.html#rendering\r
+ int penWidth = 2;\r
+ int penWidthHalf = 1;\r
+ QPen blackPen(Qt::black);\r
+ blackPen.setWidth(penWidth);\r
+ blackPen.setJoinStyle(Qt::MiterJoin);\r
+ painter->setPen(blackPen);\r
+\r
+ // Don't fill the rectangle\r
+ painter->setBrush(Qt::NoBrush);\r
+\r
+ QModelIndex index = model()->index(currentIndexRow, glvdebug_QTraceFileModel::Column_EntrypointName);\r
+ QRectF rect = itemRect(index);\r
+ rect.adjust(-penWidthHalf, -penWidthHalf, penWidthHalf-1, penWidthHalf+1);\r
+ painter->drawRect(rect);\r
+\r
+ // Draw marker underneath the current rect\r
+ painter->save();\r
+ QPainter::RenderHints hints = painter->renderHints();\r
+ painter->setRenderHints(QPainter::Antialiasing);\r
+ painter->setPen(m_trianglePen);\r
+ painter->setBrush(QColor(Qt::yellow));\r
+ painter->translate(rect.center().x(), rect.bottom());\r
+ painter->drawPolygon(triangle);\r
+ painter->setRenderHints(hints, false);\r
+ painter->restore();\r
}\r
- painter->restore();\r
-}\r
-\r
-//-----------------------------------------------------------------------------\r
-void glvdebug_QTimelineView::drawCurrentApiCallMarker(QPainter* painter, QPolygon& triangle, uint64_t rawTime)\r
-{\r
- painter->save();\r
- painter->setPen(m_trianglePen);\r
- painter->setBrush(QColor(Qt::yellow));\r
- painter->translate(scalePositionHorizontally(rawTime), 0);\r
- painter->drawPolygon(triangle);\r
- painter->restore();\r
}\r
\r
//-----------------------------------------------------------------------------\r
void glvdebug_QTimelineView::drawTimelineItem(QPainter* painter, const QModelIndex &index, int height)\r
{\r
glv_trace_packet_header* pHeader = (glv_trace_packet_header*)index.internalPointer();\r
-\r
- float duration = u64ToFloat(pHeader->entrypoint_end_time - pHeader->entrypoint_begin_time);\r
- if (duration < 0)\r
+ if (pHeader == NULL)\r
{\r
return;\r
}\r
\r
- painter->save();\r
+ if (pHeader->entrypoint_end_time <= pHeader->entrypoint_begin_time)\r
{\r
- int threadIndex = m_threadIdList.indexOf(pHeader->thread_id);\r
+ return;\r
+ }\r
\r
- // only draw if the item will extend beyond the minimum offset\r
-// float leftOffset = scalePositionHorizontally(pHeader->entrypoint_begin_time);\r
-// float scaledWidth = scaleDurationHorizontally(duration);\r
-// if (m_threadIdMinOffset[threadIndex] < leftOffset + scaledWidth)\r
- {\r
- QRectF rect = itemRect(index);\r
\r
- if (rect.isValid())\r
- {\r
- float durationRatio = duration / m_maxItemDuration;\r
- int intensity = std::min(255, (int)(durationRatio * 255.0f));\r
- QColor color(intensity, 255-intensity, 0);\r
- painter->setBrush(QBrush(color));\r
- painter->setPen(color);\r
+ QRectF rect = itemRect(index);\r
+ if (!rect.isValid() || rect.bottom() < 0 ||\r
+ rect.y() > viewport()->height())\r
+ {\r
+ return;\r
+ }\r
\r
- // update minimum offset\r
- m_threadIdMinOffset[threadIndex] = rect.left() + rect.width();\r
+ QStyleOptionViewItem option = viewOptions();\r
+ option.rect = rect.toRect();\r
+ if (selectionModel()->isSelected(index))\r
+ option.state |= QStyle::State_Selected;\r
+ if (currentIndex() == index)\r
+ option.state |= QStyle::State_HasFocus;\r
\r
- painter->drawRect(rect);\r
- }\r
- }\r
- }\r
\r
- painter->restore();\r
+ itemDelegate()->paint(painter, option, index);\r
}\r