1 #include "graphwidget.h"
5 GraphWidget::GraphWidget(QWidget* parent) :
13 m_horizontalScrollbar(NULL),
18 m_horizontalScrollbarPolicy(Qt::ScrollBarAlwaysOff),
19 m_verticalScrollbar(NULL),
24 m_verticalScrollbarPolicy(Qt::ScrollBarAlwaysOff)
26 m_selection.type = SelectionState::None;
28 m_verticalScrollbar = new QScrollBar(this);
29 m_verticalScrollbar->setOrientation(Qt::Vertical);
30 m_verticalScrollbar->hide();
31 m_verticalScrollbar->resize(m_verticalScrollbar->sizeHint());
33 m_horizontalScrollbar = new QScrollBar(this);
34 m_horizontalScrollbar->setOrientation(Qt::Horizontal);
35 m_horizontalScrollbar->hide();
36 m_horizontalScrollbar->resize(m_horizontalScrollbar->sizeHint());
39 setAutoFillBackground(true);
43 GraphView* GraphWidget::view()
49 GraphLabelWidget* GraphWidget::label()
55 GraphAxisWidget* GraphWidget::axis(AxisPosition pos)
76 void GraphWidget::setView(GraphView* view)
83 m_view->setSelectionState(&m_selection);
89 void GraphWidget::setLabel(GraphLabelWidget* label)
96 void GraphWidget::setAxis(AxisPosition pos, GraphAxisWidget* axis)
102 m_axisTop->setOrientation(GraphAxisWidget::Horizontal);
103 m_axisTop->setSelectionState(&m_selection);
109 m_axisLeft->setOrientation(GraphAxisWidget::Vertical);
110 m_axisLeft->setSelectionState(&m_selection);
116 m_axisRight->setOrientation(GraphAxisWidget::Vertical);
117 m_axisRight->setSelectionState(&m_selection);
123 m_axisBottom->setOrientation(GraphAxisWidget::Horizontal);
124 m_axisBottom->setSelectionState(&m_selection);
134 void GraphWidget::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
136 m_horizontalScrollbarPolicy = policy;
141 void GraphWidget::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
143 m_verticalScrollbarPolicy = policy;
148 void GraphWidget::resizeEvent(QResizeEvent *e)
155 /* Used if a selection would be shared between graphs with different axis */
156 SelectionState GraphWidget::transformSelectionIn(SelectionState state)
162 /* Used if a selection would be shared between graphs with different axis */
163 SelectionState GraphWidget::transformSelectionOut(SelectionState state)
169 /* Update the scrollbars based on current view */
170 void GraphWidget::updateScrollbars()
172 /* Vertical scroll bar */
173 qint64 size = (m_verticalMax - m_verticalMin) - (m_verticalEnd - m_verticalStart);
175 if (size <= INT_MAX) {
176 m_verticalScrollbar->setValue(m_verticalStart - m_verticalMin);
177 m_verticalScrollbar->setPageStep(m_verticalEnd - m_verticalStart);
178 m_verticalScrollbar->setRange(0, size);
180 /* QScrollBar only supports up to INT_MAX values,
181 * here we must scale our values to match this */
182 double curSize = m_verticalEnd - m_verticalStart;
183 double pages = (m_verticalMax - m_verticalMin) / curSize;
184 double value = (m_verticalStart - m_verticalMin) / curSize;
186 m_verticalScrollbar->setValue(value);
187 m_verticalScrollbar->setPageStep(1);
188 m_verticalScrollbar->setRange(0, pages);
191 /* Adhere to scrollbar policy */
192 bool visible = false;
194 if (m_verticalScrollbarPolicy == Qt::ScrollBarAlwaysOn) {
196 } else if (m_verticalScrollbarPolicy == Qt::ScrollBarAlwaysOff) {
198 } else if (m_verticalScrollbarPolicy == Qt::ScrollBarAsNeeded) {
199 visible = m_verticalMin != m_verticalStart || m_verticalMax != m_verticalEnd;
202 if (visible != m_verticalScrollbar->isVisible()) {
203 m_verticalScrollbar->setVisible(visible);
207 /* Horizontal scroll bar */
208 size = (m_horizontalMax - m_horizontalMin) - (m_horizontalEnd - m_horizontalStart);
210 if (size <= INT_MAX) {
211 m_horizontalScrollbar->setValue(m_horizontalStart - m_horizontalMin);
212 m_horizontalScrollbar->setPageStep(m_horizontalEnd - m_horizontalStart);
213 m_horizontalScrollbar->setRange(0, size);
215 /* QScrollBar only supports up to INT_MAX values,
216 * here we must scale our values to match this */
217 double dxdv = INT_MAX / (double)size;
218 double value = (m_horizontalStart - m_horizontalMin) * dxdv;
219 double pageStep = (m_horizontalEnd - m_horizontalStart) * dxdv;
221 m_horizontalScrollbar->setValue((int)value);
222 m_horizontalScrollbar->setPageStep((int)pageStep);
223 m_horizontalScrollbar->setRange(0, INT_MAX);
226 /* Adhere to scrollbar policy */
229 if (m_horizontalScrollbarPolicy == Qt::ScrollBarAlwaysOn) {
231 } else if (m_horizontalScrollbarPolicy == Qt::ScrollBarAlwaysOff) {
233 } else if (m_horizontalScrollbarPolicy == Qt::ScrollBarAsNeeded) {
234 visible = m_horizontalMin != m_horizontalStart || m_horizontalMax != m_horizontalEnd;
237 if (visible != m_horizontalScrollbar->isVisible()) {
238 m_horizontalScrollbar->setVisible(visible);
244 /* Update all signal / slot connections */
245 void GraphWidget::updateConnections()
248 connect(m_view, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
250 connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), this, SLOT(horizontalViewChange(qint64,qint64)), Qt::UniqueConnection);
251 connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), this, SLOT(horizontalRangeChange(qint64,qint64)), Qt::UniqueConnection);
253 connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), this, SLOT(verticalViewChange(qint64,qint64)), Qt::UniqueConnection);
254 connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), this, SLOT(verticalRangeChange(qint64,qint64)), Qt::UniqueConnection);
259 connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), m_axisTop, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
260 connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), m_axisTop, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
263 connect(m_axisTop, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
268 connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), m_axisLeft, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
269 connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), m_axisLeft, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
272 connect(m_axisLeft, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
277 connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), m_axisRight, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
278 connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), m_axisRight, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
281 connect(m_axisRight, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
286 connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), m_axisBottom, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
287 connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), m_axisBottom, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
290 connect(m_axisBottom, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
293 if (m_horizontalScrollbar) {
294 connect(m_horizontalScrollbar, SIGNAL(actionTriggered(int)), this, SLOT(horizontalScrollAction(int)));
297 if (m_verticalScrollbar) {
298 connect(m_verticalScrollbar, SIGNAL(actionTriggered(int)), this, SLOT(verticalScrollAction(int)));
303 /* Recalculate the layout */
304 void GraphWidget::updateLayout()
307 int padX = 0, padY = 0;
310 padY += m_axisTop->height();
314 padY += m_axisBottom->height();
318 padX += m_axisLeft->width();
322 padX += m_axisRight->width();
325 if (m_horizontalScrollbar->isVisible()) {
326 padY += m_horizontalScrollbar->height();
329 if (m_verticalScrollbar->isVisible()) {
330 padX += m_verticalScrollbar->width();
334 x = m_axisLeft ? m_axisLeft->width() : 0;
337 m_axisTop->move(x, y);
338 m_axisTop->resize(width() - padX, m_axisTop->height());
342 x = m_axisLeft ? m_axisLeft->width() : 0;
343 y = height() - m_axisBottom->height();
345 if (m_horizontalScrollbar->isVisible()) {
346 y -= m_horizontalScrollbar->height();
349 m_axisBottom->move(x, y);
350 m_axisBottom->resize(width() - padX, m_axisBottom->height());
355 y = m_axisTop ? m_axisTop->height() : 0;
357 m_axisLeft->move(x, y);
358 m_axisLeft->resize(m_axisLeft->width(), height() - padY);
362 x = width() - m_axisRight->width();
363 y = m_axisTop ? m_axisTop->height() : 0;
365 if (m_verticalScrollbar->isVisible()) {
366 x -= m_verticalScrollbar->width();
369 m_axisRight->move(x, y);
370 m_axisRight->resize(m_axisRight->width(), height() - padY);
374 x = m_axisLeft ? m_axisLeft->width() : 0;
375 y = m_axisTop ? m_axisTop->height() : 0;
378 m_view->resize(width() - padX, height() - padY);
382 if (m_axisTop && m_axisLeft) {
384 m_label->resize(m_axisLeft->width(), m_axisTop->height());
388 if (m_verticalScrollbar) {
389 m_verticalScrollbar->move(width() - m_verticalScrollbar->width(), 0);
391 if (m_horizontalScrollbar) {
392 m_verticalScrollbar->resize(m_verticalScrollbar->width(), height() - m_horizontalScrollbar->height());
394 m_verticalScrollbar->resize(m_verticalScrollbar->width(), height());
398 if (m_horizontalScrollbar) {
399 m_horizontalScrollbar->move(0, height() - m_horizontalScrollbar->height());
401 if (m_verticalScrollbar) {
402 m_horizontalScrollbar->resize(width() - m_verticalScrollbar->width(), m_horizontalScrollbar->height());
404 m_horizontalScrollbar->resize(width(), m_horizontalScrollbar->height());
410 void GraphWidget::setSelection(SelectionState state)
412 m_selection = transformSelectionIn(state);
413 updateSelection(false);
417 void GraphWidget::setHorizontalView(qint64 start, qint64 end)
420 m_view->setHorizontalView(start, end);
425 void GraphWidget::setVerticalView(qint64 start, qint64 end)
428 m_view->setVerticalView(start, end);
433 /* Called when the view is translated / zoomed */
434 void GraphWidget::verticalViewChange(qint64 start, qint64 end)
436 m_verticalStart = start;
440 emit verticalViewChanged(start, end);
444 void GraphWidget::verticalRangeChange(qint64 start, qint64 end)
446 m_verticalMin = start;
450 emit verticalRangeChanged(start, end);
454 void GraphWidget::horizontalViewChange(qint64 start, qint64 end)
456 m_horizontalStart = start;
457 m_horizontalEnd = end;
460 emit horizontalViewChanged(start, end);
464 void GraphWidget::horizontalRangeChange(qint64 start, qint64 end)
466 m_horizontalMin = start;
467 m_horizontalMax = end;
470 emit horizontalRangeChanged(start, end);
474 /* User interaction with horizontal scroll bar */
475 void GraphWidget::horizontalScrollAction(int /*action*/)
477 int value = m_horizontalScrollbar->sliderPosition();
478 qint64 size = (m_horizontalMax - m_horizontalMin) - (m_horizontalEnd - m_horizontalStart);
480 /* Calculate the new scroll values */
481 if (size <= INT_MAX) {
482 m_horizontalEnd -= m_horizontalStart;
483 m_horizontalStart = value + m_horizontalMin;
484 m_horizontalEnd += value;
486 /* QScrollBar only supports up to INT_MAX values, here we must scale
487 * our values to match this */
488 double dxdv = INT_MAX / (double)size;
490 size = m_horizontalEnd - m_horizontalStart;
491 m_horizontalStart = value / dxdv + m_horizontalMin;
492 m_horizontalEnd = m_horizontalStart + size;
497 m_view->setHorizontalView(m_horizontalStart, m_horizontalEnd);
500 /* Update horizontal axes */
502 m_axisTop->setView(m_horizontalStart, m_horizontalEnd);
506 m_axisBottom->setView(m_horizontalStart, m_horizontalEnd);
509 /* Inform the world of our changes! */
510 emit horizontalViewChanged(m_horizontalStart, m_horizontalEnd);
514 /* User interaction with vertical scroll bar */
515 void GraphWidget::verticalScrollAction(int /*action*/)
517 int value = m_verticalScrollbar->sliderPosition();
518 qint64 size = (m_verticalMax - m_verticalMin) - (m_verticalEnd - m_verticalStart);
520 /* Calculate the new scroll values */
521 if (size <= INT_MAX) {
522 m_verticalEnd -= m_verticalStart;
523 m_verticalStart = value + m_verticalMin;
524 m_verticalEnd += value;
526 /* QScrollBar only supports up to INT_MAX values, here we must scale
527 * our values to match this */
528 double dxdv = INT_MAX / (double)size;
530 size = m_verticalEnd - m_verticalStart;
531 m_verticalStart = value / dxdv + m_verticalMin;
532 m_verticalEnd = m_verticalStart + size;
537 m_view->setVerticalView(m_verticalStart, m_verticalEnd);
540 /* Update vertical axes */
542 m_axisLeft->setView(m_verticalStart, m_verticalEnd);
546 m_axisRight->setView(m_verticalStart, m_verticalEnd);
549 /* Inform the world of our changes! */
550 emit verticalViewChanged(m_verticalStart, m_verticalEnd);
554 /* Update child elements when selection changes */
555 void GraphWidget::updateSelection(bool emitSignal)
566 m_axisLeft->update();
570 m_axisRight->update();
574 m_axisBottom->update();
578 emit selectionChanged(transformSelectionOut(m_selection));
583 #include "graphwidget.moc"