//-----------------------------------------------------------------------------
void vktraceviewer_QTimelineView::paint(QPainter *painter, QPaintEvent *event)
{
    m_threadHeight = event->rect().height();
    if (m_threadIdList.count() > 0)
    {
        m_threadHeight /= m_threadIdList.count();
    }

    int arrowHeight = 12;
    int arrowTop = 2;
    int arrowHalfWidth = 4;

    QPolygon triangle(3);
    triangle.setPoint(0, 0, arrowTop);
    triangle.setPoint(1, -arrowHalfWidth, arrowTop+arrowHeight);
    triangle.setPoint(2, arrowHalfWidth, arrowTop+arrowHeight);

    QList<uint32_t> threadList = getModelThreadList();

    calculateRectsIfNecessary();

    if (m_pPixmap == NULL)
    {
        int pixmapHeight = event->rect().height();
        int pixmapWidth = event->rect().width();

        m_pPixmap = new QPixmap(pixmapWidth, pixmapHeight);

        for (int t = 0; t < m_threadIdList.size(); t++)
        {
            m_threadMask[m_threadIdList[t]] = QVector<int>(pixmapWidth, 0);
        }

        QPainter pixmapPainter(m_pPixmap);

        // fill entire background with background color
        pixmapPainter.fillRect(event->rect(), m_background);
        drawBaseTimelines(&pixmapPainter, event->rect(), threadList);

        if (model() != NULL)
        {
            int numRows = model()->rowCount();

            for (int r = 0; r < numRows; r++)
            {
                QModelIndex index = model()->index(r, vktraceviewer_QTraceFileModel::Column_EntrypointName);

                drawTimelineItem(&pixmapPainter, index);
            }
        }
    }
    painter->drawPixmap(event->rect(), *m_pPixmap, m_pPixmap->rect());

    if (model() == NULL)
    {
        return;
    }

    // draw current api call marker
    int currentIndexRow = currentIndex().row();
    if (currentIndexRow >= 0)
    {
        // Overlay a black rectangle around the current item.
        // For more information on how rects are drawn as outlines,
        // see here: http://qt-project.org/doc/qt-4.8/qrectf.html#rendering
        int penWidth = 2;
        int penWidthHalf = 1;
        QPen blackPen(Qt::black);
        blackPen.setWidth(penWidth);
        blackPen.setJoinStyle(Qt::MiterJoin);
        painter->setPen(blackPen);

        // Don't fill the rectangle
        painter->setBrush(Qt::NoBrush);

        QModelIndex index = model()->index(currentIndexRow, vktraceviewer_QTraceFileModel::Column_EntrypointName);
        QRectF rect = visualRect(index);
        rect.adjust(-penWidthHalf, -penWidthHalf, penWidthHalf, penWidthHalf);
        painter->drawRect(rect);

        // Draw marker underneath the current rect
        painter->save();
        QPainter::RenderHints hints = painter->renderHints();
        painter->setRenderHints(QPainter::Antialiasing);
        painter->setPen(m_trianglePen);
        painter->setBrush(QColor(Qt::yellow));
        painter->translate(rect.center().x(), rect.bottom());
        painter->drawPolygon(triangle);
        painter->setRenderHints(hints, false);
        painter->restore();
    }
}
Ejemplo n.º 2
0
void vogleditor_QTimelineView::paint(QPainter *painter, QPaintEvent *event)
{
    int gap = 10;
    int arrowHeight = 10;
    int arrowTop = event->rect().height()/2-gap-arrowHeight;
    int arrowHalfWidth = 3;
     m_lineLength = event->rect().width()-2*gap;

    QPolygon triangle(3);
    triangle.setPoint(0, 0, arrowTop);
    triangle.setPoint(1, -arrowHalfWidth, arrowTop+arrowHeight);
    triangle.setPoint(2, arrowHalfWidth, arrowTop+arrowHeight);

    drawBaseTimeline(painter, event->rect(), gap);

    if (m_pModel == NULL)
    {
        return;
    }

    if (m_pModel->get_root_item() == NULL)
    {
        return;
    }

    if (m_pPixmap != NULL)
    {
        int rectHeight = event->rect().height();
        int rectWidth = event->rect().width();
        int pmHeight = m_pPixmap->height();
        int pmWidth = m_pPixmap->width();

        float widthPctDelta = (float)(rectWidth - pmWidth) / (float)pmWidth;
        float heightPctDelta = (float)(rectHeight - pmHeight) / (float)pmHeight;

        // If the resize is of a 'signficant' amount, then delete the pixmap so that it will be regenerated at the new size.
        if (fabs(widthPctDelta) > 0.2 ||
            fabs(heightPctDelta) > 0.2)
        {
            deletePixmap();
        }
    }

    if (m_pPixmap == NULL)
    {
        m_pPixmap = new QPixmap(event->rect().width(), event->rect().height());
        QPainter pixmapPainter(m_pPixmap);
        drawBaseTimeline(&pixmapPainter, event->rect(), gap);

        // translate drawing to vertical center of rect
        // everything will have a small gap on the left and right sides
        pixmapPainter.translate(gap, event->rect().height()/2);

        if (m_pModel->get_root_item()->getBrush() == NULL)
        {
            m_pModel->get_root_item()->setBrush(&m_triangleBrush);
        }

        m_horizontalScale = (float)m_lineLength / (float)m_pModel->get_root_item()->getDuration();

        // we don't want to draw the root item, but all of its children
        int numChildren = m_pModel->get_root_item()->childCount();
        int height = event->rect().height()/2-2*gap;

        pixmapPainter.setBrush(m_triangleBrush);
        pixmapPainter.setPen(m_trianglePen);

        float minimumOffset = 0;
        for (int c = 0; c < numChildren; c++)
        {
            vogleditor_timelineItem* pChild = m_pModel->get_root_item()->child(c);
            drawTimelineItem(&pixmapPainter, pChild, height, minimumOffset);
        }
    }

    painter->drawPixmap(event->rect(), *m_pPixmap, m_pPixmap->rect());

    // translate drawing to vertical center of rect
    // everything will have a small gap on the left and right sides
    painter->translate(gap, event->rect().height()/2);

    painter->setBrush(m_triangleBrush);
    painter->setPen(m_trianglePen);

    int numChildren = m_pModel->get_root_item()->childCount();
    for (int c = 0; c < numChildren; c++)
    {
        vogleditor_timelineItem* pChild = m_pModel->get_root_item()->child(c);

        // draw current frame marker
        if (pChild->getFrameItem() != NULL && pChild->getFrameItem()->frameNumber() == m_curFrame)
        {
            painter->save();
            painter->translate(scalePositionHorizontally(pChild->getBeginTime()), 0);
            painter->drawPolygon(triangle);
            painter->restore();
        }

        // draw current api call marker
        if (pChild->getApiCallItem() != NULL && pChild->getApiCallItem()->globalCallIndex() == m_curApiCallNumber)
        {
            painter->save();
            painter->translate(scalePositionHorizontally(pChild->getBeginTime()), 0);
            painter->drawPolygon(triangle);
            painter->restore();
        }
    }
}
Ejemplo n.º 3
0
void vogleditor_QTimelineView::drawTimelineItem(QPainter *painter, vogleditor_timelineItem *pItem, int height, double &minimumOffset)
{
    float duration = pItem->getDuration();
    if (duration < 0)
    {
        return;
    }
    if (pItem->isMarker()) // frame marker
    {
        painter->setBrush(m_triangleBrushWhite);
        painter->setPen(m_trianglePen);

        float offset = scalePositionHorizontally(pItem->getBeginTime());
        painter->drawLine(QLineF(offset, -height, offset, height));
    }
    else
    {
        // only draw if the item will extend beyond the minimum offset and it is on-screen
        double leftOffset = scalePositionHorizontally(pItem->getBeginTime());
        double scaledWidth = scaleDurationHorizontally(duration);
        double rightOffset = leftOffset + scaledWidth;
        if (minimumOffset < rightOffset && rightOffset>m_scroll && leftOffset<m_scroll+width() )
        {
            // Set brush fill color
            if (pItem->getBrush())
            {
                painter->setBrush(*(pItem->getBrush()));
            }
            else // create brush with color relative to time duration of apicall
            {
                float durationRatio = duration / m_maxItemDuration;
                int intensity = std::min(255, (int)(durationRatio * 255.0f));
                QColor color(intensity, 255 - intensity, 0);
                painter->setBrush(QBrush(color));
            }
            // don't draw boundary. It can add an extra pixel to rect width
            painter->setPen(Qt::NoPen);

            // Clamp the item so that it is 1 pixel wide.
            // This is intentionally being done before updating the minimum offset
            // so that small items after the current item will not be drawn
            if (scaledWidth < 1)
            {
                scaledWidth = 1;
            }

            // update minimum offset
            minimumOffset = leftOffset + scaledWidth;
            int startTimePx = leftOffset - m_roundoff;
            int durationPx = scaledWidth + m_roundoff;

            // draw the colored box that represents this item
            QRect rect;
            rect.setLeft(startTimePx);
            rect.setTop(-height / 2);
            rect.setWidth(durationPx);
            rect.setHeight(height);
            painter->drawRect(rect);

            //Add the position of this item to the timelineItemPosCache for use by itemUnderPos().
            timelineItemPos itemPos;
            itemPos.pItem=pItem;
            itemPos.leftOffset=startTimePx;
            itemPos.rightOffset=startTimePx+durationPx;
            m_timelineItemPosCache.append(itemPos);
        }

        // If only State/Render groups to display, we're done (if debug groups
        // are checked continue to draw individual apicalls)
        //
        // TODO: test replacing following if-block check with just:
        //       if (pItem->isGroupItem())
        if (g_settings.group_state_render_stat() && !g_settings.group_debug_marker_in_use())
        {
            return;
        }
        // now draw all children
        int numChildren = pItem->childCount();
        for (int c = 0; c < numChildren; c++)
        {
            drawTimelineItem(painter, pItem->child(c), height - 1, minimumOffset);
        }
    }

}
Ejemplo n.º 4
0
void vogleditor_QTimelineView::drawTimelineItem(QPainter* painter, vogleditor_timelineItem *pItem, int height, float& minimumOffset)
{
   float duration = pItem->getDuration();
   if (duration < 0)
   {
      return;
   }

   painter->save();
   if (pItem->isMarker())
   {
      painter->setBrush(m_triangleBrush);
      painter->setPen(m_trianglePen);

      float offset = scalePositionHorizontally(pItem->getBeginTime());
      painter->drawLine(QLineF(offset, -height, offset, height));
   }
   else
   {
       // only draw if the item will extend beyond the minimum offset
       float leftOffset = scalePositionHorizontally(pItem->getBeginTime());
       float scaledWidth = scaleDurationHorizontally(duration);
       if (minimumOffset < leftOffset + scaledWidth)
       {
           float durationRatio = duration / m_maxItemDuration;
           int intensity = std::min(255, (int)(durationRatio * 255.0f));
           //   painter->setBrush(*(pItem->getBrush()));
           QColor color(intensity, 255-intensity, 0);
           painter->setBrush(QBrush(color));
           painter->setPen(color);

           // Clamp the item so that it is 1 pixel wide.
           // This is intentionally being done before updating the minimum offset
           // so that small items after the current item will not be drawn
           if (scaledWidth < 1)
           {
               scaledWidth = 1;
           }

           // update minimum offset
           minimumOffset = leftOffset + scaledWidth;

           // draw the colored box that represents this item
           QRectF rect;
           rect.setLeft(leftOffset);
           rect.setTop(-height/2);
           rect.setWidth(scaledWidth);
           rect.setHeight(height);
           painter->drawRect(rect);

           // now draw all children
           int numChildren = pItem->childCount();
           for (int c = 0; c < numChildren; c++)
           {
               drawTimelineItem(painter, pItem->child(c), height-1, minimumOffset);
           }
       }
   }

   painter->restore();
}
Ejemplo n.º 5
0
void vogleditor_QTimelineView::paint(QPainter *painter, QPaintEvent *event)
{
    m_gap = 10;
    int arrowHeight = 10;
    int arrowTop = height() / 2 - m_gap - arrowHeight;
    int arrowHalfWidth = 3;
    m_lineLength = (double)width()*(double)m_zoom - 2 * m_gap;

    QPolygon triangle(3);
    triangle.setPoint(0, 0, arrowTop);
    triangle.setPoint(1, -arrowHalfWidth, arrowTop + arrowHeight);
    triangle.setPoint(2, arrowHalfWidth, arrowTop + arrowHeight);

    painter->save();
    painter->translate(-m_scroll, 0);    
    drawBaseTimeline(painter, event->rect(), m_gap);
    //Go back to unscrolled coordinates to paint the pixmap to the widget.
    painter->restore();

    if (m_pModel == NULL)
    {
        return;
    }

    if (m_pModel->get_root_item() == NULL)
    {
        return;
    }

    if (m_pPixmap == NULL)
    {
        m_timelineItemPosCache.clear();
        m_pPixmap = new QPixmap(event->rect().width(), event->rect().height());
        m_pPixmap->fill(Qt::transparent);
        QPainter pixmapPainter(m_pPixmap);

        //Apply the scroll translation:
        pixmapPainter.translate(-m_scroll, 0);
        // translate drawing to vertical center of rect
        // everything will have a small gap on the left and right sides
        pixmapPainter.translate(m_gap, height() / 2);

        m_horizontalScale = (double)m_lineLength / (double)m_pModel->get_root_item()->getDuration();

        // we don't want to draw the root item, but all of its children
        int numChildren = m_pModel->get_root_item()->childCount();
        int i_height = height() / 2 - 2 * m_gap;

        pixmapPainter.setBrush(m_triangleBrushWhite);
        pixmapPainter.setPen(m_trianglePen);

        double minimumOffset = 0;
        vogleditor_timelineItem *rootItem = m_pModel->get_root_item();
        for (int c = 0; c < numChildren; c++)
        {
            vogleditor_timelineItem *pChild = rootItem->child(c);
            drawTimelineItem(&pixmapPainter, pChild, i_height, minimumOffset);
        }
    }

    painter->drawPixmap(event->rect(), *m_pPixmap, m_pPixmap->rect());

    painter->translate(-m_scroll, 0);
    painter->setBrush(m_triangleBrushWhite);
    painter->setPen(m_trianglePen);

    // translate drawing to vertical center of rect
    // everything will have a small gap on the left and right sides
    painter->translate(m_gap, height() / 2);

    if (m_curFrameTime!=-1)
    {
        painter->save();
        //translate to the point to draw marker
        painter->translate(scalePositionHorizontally(m_curFrameTime), 0);
        painter->setBrush(m_triangleBrushBlack);
        painter->drawPolygon(triangle);
        painter->restore();
    }

    // draw current api call marker
    if (m_curApiCallTime!=-1)
    {
        double xpos = scalePositionHorizontally(m_curApiCallTime);
        xpos -= m_roundoff;

        painter->save();
        //translate to the point to draw marker
        painter->translate(xpos, 0);
        painter->drawPolygon(triangle);
        painter->restore();
    }
}