]> git.cworth.org Git - vogl/blob - src/vogleditor/vogleditor_qtimelineview.cpp
Initial vogl checkin
[vogl] / src / vogleditor / vogleditor_qtimelineview.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include <QtGui>
27 #include "vogleditor_qtimelineview.h"
28 #include "vogleditor_frameitem.h"
29
30 vogleditor_QTimelineView::vogleditor_QTimelineView(QWidget *parent) :
31    QWidget(parent),
32    m_curFrame(0),
33    m_curApiCallNumber(0),
34    m_pModel(NULL),
35    m_pPixmap(NULL)
36 {
37    QLinearGradient gradient(QPointF(50, -20), QPointF(80, 20));
38    gradient.setColorAt(0.0, Qt::white);
39    gradient.setColorAt(1.0, QColor(0xa6, 0xce, 0x39));
40
41    m_background = QBrush(QColor(200,200,200));//QBrush(parent->palette().brush(parent->backgroundRole()));
42    m_triangleBrush = QBrush(gradient);
43    m_trianglePen = QPen(Qt::black);
44    m_trianglePen.setWidth(1);
45    m_textPen = QPen(Qt::white);
46    m_textFont.setPixelSize(50);
47
48    m_horizontalScale = 1;
49    m_lineLength = 1;
50 }
51
52 vogleditor_QTimelineView::~vogleditor_QTimelineView()
53 {
54     deletePixmap();
55 }
56
57 void vogleditor_QTimelineView::paintEvent(QPaintEvent *event)
58 {
59     QPainter painter;
60     painter.begin(this);
61     paint(&painter, event);
62     painter.end();
63 }
64
65 void vogleditor_QTimelineView::drawBaseTimeline(QPainter* painter, const QRect& rect, int gap)
66 {
67     painter->save();
68
69     // fill entire background with background color
70     painter->fillRect(rect, m_background);
71
72     // translate drawing to vertical center of rect
73     painter->translate(0, rect.height()/2);
74
75     painter->setBrush(m_triangleBrush);
76     painter->setPen(m_trianglePen);
77
78     // everything will have a small gap on the left and right sides
79     painter->translate(gap, 0);
80
81     // draw the actual timeline
82     int lineLength = rect.width()-2*gap;
83     painter->drawLine(0,0, lineLength, 0);
84
85     painter->restore();
86 }
87
88 void vogleditor_QTimelineView::paint(QPainter *painter, QPaintEvent *event)
89 {
90     int gap = 10;
91     int arrowHeight = 10;
92     int arrowTop = event->rect().height()/2-gap-arrowHeight;
93     int arrowHalfWidth = 3;
94      m_lineLength = event->rect().width()-2*gap;
95
96     QPolygon triangle(3);
97     triangle.setPoint(0, 0, arrowTop);
98     triangle.setPoint(1, -arrowHalfWidth, arrowTop+arrowHeight);
99     triangle.setPoint(2, arrowHalfWidth, arrowTop+arrowHeight);
100
101     drawBaseTimeline(painter, event->rect(), gap);
102
103     if (m_pModel == NULL)
104     {
105         return;
106     }
107
108     if (m_pModel->get_root_item() == NULL)
109     {
110         return;
111     }
112
113     if (m_pPixmap != NULL)
114     {
115         if (m_pPixmap->height() != event->rect().height() ||
116             m_pPixmap->width() != event->rect().width())
117         {
118             deletePixmap();
119         }
120     }
121
122     if (m_pPixmap == NULL)
123     {
124         m_pPixmap = new QPixmap(event->rect().width(), event->rect().height());
125         QPainter pixmapPainter(m_pPixmap);
126         drawBaseTimeline(&pixmapPainter, event->rect(), gap);
127
128         // translate drawing to vertical center of rect
129         // everything will have a small gap on the left and right sides
130         pixmapPainter.translate(gap, event->rect().height()/2);
131
132         if (m_pModel->get_root_item()->getBrush() == NULL)
133         {
134             m_pModel->get_root_item()->setBrush(&m_triangleBrush);
135         }
136
137         m_horizontalScale = (float)m_lineLength / (float)m_pModel->get_root_item()->getDuration();
138
139         // we don't want to draw the root item, but all of its children
140         int numChildren = m_pModel->get_root_item()->childCount();
141         int height = event->rect().height()/2-2*gap;
142
143         pixmapPainter.setBrush(m_triangleBrush);
144         pixmapPainter.setPen(m_trianglePen);
145
146         for (int c = 0; c < numChildren; c++)
147         {
148             vogleditor_timelineItem* pChild = m_pModel->get_root_item()->child(c);
149             drawTimelineItem(&pixmapPainter, pChild, height);
150         }
151     }
152
153     painter->drawPixmap(event->rect(), *m_pPixmap, event->rect());
154
155     // translate drawing to vertical center of rect
156     // everything will have a small gap on the left and right sides
157     painter->translate(gap, event->rect().height()/2);
158
159     painter->setBrush(m_triangleBrush);
160     painter->setPen(m_trianglePen);
161
162     int numChildren = m_pModel->get_root_item()->childCount();
163     for (int c = 0; c < numChildren; c++)
164     {
165         vogleditor_timelineItem* pChild = m_pModel->get_root_item()->child(c);
166
167         // draw current frame marker
168         if (pChild->getFrameItem() != NULL && pChild->getFrameItem()->frameNumber() == m_curFrame)
169         {
170             painter->save();
171             painter->translate(scalePositionHorizontally(pChild->getBeginTime()), 0);
172             painter->drawPolygon(triangle);
173             painter->restore();
174         }
175
176         // draw current api call marker
177         if (pChild->getApiCallItem() != NULL && pChild->getApiCallItem()->globalCallIndex() == m_curApiCallNumber)
178         {
179             painter->save();
180             painter->translate(scalePositionHorizontally(pChild->getBeginTime()), 0);
181             painter->drawPolygon(triangle);
182             painter->restore();
183         }
184     }
185 }
186
187 float vogleditor_QTimelineView::scaleDurationHorizontally(float value)
188 {
189    float scaled = value * m_horizontalScale;
190    if (scaled <= 0)
191    {
192       scaled = 1;
193    }
194
195    return scaled;
196 }
197
198 float vogleditor_QTimelineView::scalePositionHorizontally(float value)
199 {
200    float horizontalShift = m_pModel->get_root_item()->getBeginTime();
201    float horizontalLength = m_pModel->get_root_item()->getDuration();
202    float offset = ((value - horizontalShift) / horizontalLength) * m_lineLength;
203
204    return offset;
205 }
206
207 void vogleditor_QTimelineView::drawTimelineItem(QPainter* painter, vogleditor_timelineItem *pItem, int height)
208 {
209    float duration = pItem->getDuration();
210    if (duration < 0)
211    {
212       return;
213    }
214
215    painter->save();
216    if (pItem->isMarker())
217    {
218       painter->setBrush(m_triangleBrush);
219       painter->setPen(m_trianglePen);
220
221       float offset = scalePositionHorizontally(pItem->getBeginTime());
222       painter->drawLine(QLineF(offset, -height, offset, height));
223    }
224    else
225    {
226       float durationRatio = duration / m_maxItemDuration;
227       int intensity = std::min(255, (int)(durationRatio * 255.0f));
228       //   painter->setBrush(*(pItem->getBrush()));
229       QColor color(intensity, 255-intensity, 0);
230       painter->setBrush(QBrush(color));
231       painter->setPen(color);
232       QRectF rect;
233       rect.setLeft(scalePositionHorizontally(pItem->getBeginTime()));
234       rect.setTop(-height/2);
235       rect.setWidth(scaleDurationHorizontally(duration));
236       rect.setHeight(height);
237       painter->drawRect(rect);
238
239       // now draw all children
240       int numChildren = pItem->childCount();
241       for (int c = 0; c < numChildren; c++)
242       {
243          drawTimelineItem(painter, pItem->child(c), height-1);
244       }
245    }
246
247    painter->restore();
248 }