1 #include "histogramview.h"
10 HistogramView::HistogramView(QWidget* parent) :
14 setMouseTracking(true);
16 m_gradientUnselected.setColorAt(0.9, QColor(200, 200, 200));
17 m_gradientUnselected.setColorAt(0.0, QColor(220, 220, 220));
19 m_gradientSelected.setColorAt(0.9, QColor(0, 0, 210));
20 m_gradientSelected.setColorAt(0.0, QColor(130, 130, 255));
24 void HistogramView::setDataProvider(GraphDataProvider* data)
30 m_data->setSelectionState(m_selectionState);
31 setDefaultView(0, m_data->size());
39 void HistogramView::setSelectionState(SelectionState* state)
42 m_data->setSelectionState(state);
45 GraphView::setSelectionState(state);
49 void HistogramView::setSelectedGradient(const QLinearGradient& gradient)
51 m_gradientSelected = gradient;
55 void HistogramView::setUnelectedGradient(const QLinearGradient& gradient)
57 m_gradientUnselected = gradient;
61 void HistogramView::mouseMoveEvent(QMouseEvent *e)
63 GraphView::mouseMoveEvent(e);
65 if (e->buttons() || !m_data) {
70 qint64 index = itemAtPosition(e->pos());
71 qint64 time = valueAtPosition(e->pos());
73 if (m_data->value(index) >= time) {
74 QToolTip::showText(e->globalPos(), m_data->itemTooltip(index));
81 void HistogramView::mouseDoubleClickEvent(QMouseEvent *e)
83 if (e->button() == Qt::LeftButton) {
84 qint64 index = itemAtPosition(e->pos());
85 qint64 time = valueAtPosition(e->pos());
87 if (m_data->value(index) >= time) {
88 m_data->itemDoubleClicked(index);
93 GraphView::mouseDoubleClickEvent(e);
97 void HistogramView::update()
103 for (qint64 i = m_viewLeft; i < m_viewRight; ++i) {
104 qint64 value = m_data->value(i);
106 if (value > m_graphTop) {
116 void HistogramView::resizeEvent(QResizeEvent *)
118 m_gradientSelected.setStart(0, height());
119 m_gradientUnselected.setStart(0, height());
123 /* Draw the histogram
125 * When the view is zoomed such that there is more than one item occupying a single pixel
126 * the one with the highest value will be displayed.
128 void HistogramView::paintEvent(QPaintEvent *)
134 QBrush selectedBrush = QBrush(m_gradientSelected);
135 QPen selectedPen = QPen(selectedBrush, 1);
137 QBrush unselectedBrush = QBrush(m_gradientUnselected);
138 QPen unselectedPen = QPen(unselectedBrush, 1);
140 QPainter painter(this);
141 painter.fillRect(0, 0, width(), height(), Qt::white);
143 double dydv = height() / (double)m_graphTop;
144 double dxdv = width() / (double)(m_viewRight - m_viewLeft);
145 bool selection = m_selectionState && m_selectionState->type != SelectionState::None;
148 /* Less than one pixel per item */
149 qint64 longestValue = m_graphBottom;
150 qint64 longestSelected = m_graphBottom;
155 painter.setPen(unselectedPen);
157 painter.setPen(selectedPen);
160 for (qint64 i = m_viewLeft; i < m_viewRight; ++i) {
161 qint64 value = m_data->value(i);
164 if (value > longestValue) {
165 longestValue = value;
168 if (selection && m_data->selected(i) && value > longestSelected) {
169 longestSelected = value;
176 painter.drawLine(lastX, height(), lastX, height() - (longestValue * dydv));
178 if (selection && longestSelected > m_graphBottom) {
179 painter.setPen(selectedPen);
180 painter.drawLine(lastX, height(), lastX, height() - (longestSelected * dydv));
181 painter.setPen(unselectedPen);
182 longestSelected = m_graphBottom;
185 longestValue = m_graphBottom;
190 /* Draw rectangles for graph */
193 for (qint64 i = m_viewLeft; i < m_viewRight; ++i, x += dxdv) {
194 qint64 value = m_data->value(i);
195 int y = qMax<int>(1, value * dydv);
197 if (!selection || m_data->selected(i)) {
198 painter.fillRect(x, height() - y, dxdv, y, selectedBrush);
200 painter.fillRect(x, height() - y, dxdv, y, unselectedBrush);
205 /* Draw the borders for the selection */
206 if (m_selectionState && m_selectionState->type == SelectionState::Horizontal) {
207 double dxdt = width() / (double)m_viewWidth;
208 double scroll = m_viewLeft * dxdt;
209 double left = (m_selectionState->start * dxdt) - scroll;
210 double right = (m_selectionState->end * dxdt) - scroll;
212 painter.setPen(Qt::green);
214 if (left >= 0 && left <= width()) {
215 painter.drawLine(left, 0, left, height());
218 if (right >= 0 && right <= width()) {
219 painter.drawLine(right, 0, right, height());
225 /* Find the item with the highest value at pos.x() +/- 1,
226 * the mouse must be within the bar height-wise.
228 qint64 HistogramView::itemAtPosition(QPoint pos) {
229 double dvdx = m_viewWidth / (double)width();
231 qint64 left = qFloor(dvdx * (pos.x() - 1)) + m_viewLeft;
232 qint64 right = qCeil(dvdx * (pos.x() + 1)) + m_viewLeft;
234 qint64 longestIndex = 0;
235 qint64 longestValue = 0;
237 left = qBound<qint64>(0, left, m_data->size() - 1);
238 right = qBound<qint64>(0, right, m_data->size() - 1);
240 for (qint64 i = left; i <= right; ++i) {
241 if (m_data->value(i) > longestValue) {
242 longestValue = m_data->value(i);
251 /* Return the value at position */
252 qint64 HistogramView::valueAtPosition(QPoint pos) {
253 double value = m_graphTop / (double)height();
254 value *= height() - pos.y();
255 value += m_graphBottom;
256 return (qint64)value;