From ee59e61f224be1922b94e5a1f98c9810e5324530 2012-07-27 10:15:44 From: Michal Klocek Date: 2012-07-27 10:15:44 Subject: [PATCH] Adds scroll and zoom to chartviewer --- diff --git a/demos/chartviewer/chartviewer.pro b/demos/chartviewer/chartviewer.pro index ba82a5b..3965fce 100644 --- a/demos/chartviewer/chartviewer.pro +++ b/demos/chartviewer/chartviewer.pro @@ -1,5 +1,5 @@ !include( ../demos.pri ):error( "Couldn't find the demos.pri file!" ) TARGET = chartviewer QT += opengl -SOURCES = main.cpp chartwindow.cpp -HEADERS = chartwindow.h +SOURCES = main.cpp window.cpp view.cpp +HEADERS = window.h view.h \ No newline at end of file diff --git a/demos/chartviewer/main.cpp b/demos/chartviewer/main.cpp index 71434af..d52bc43 100644 --- a/demos/chartviewer/main.cpp +++ b/demos/chartviewer/main.cpp @@ -18,14 +18,14 @@ ** ****************************************************************************/ -#include "chartwindow.h" +#include "window.h" #include #include int main(int argc, char *argv[]) { QApplication a(argc, argv); - ChartWindow window; + Window window; window.show(); return a.exec(); } diff --git a/demos/chartviewer/view.cpp b/demos/chartviewer/view.cpp new file mode 100644 index 0000000..26d38b5 --- /dev/null +++ b/demos/chartviewer/view.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** + ** + ** Copyright (C) 2012 Digia Plc + ** All rights reserved. + ** For any questions to Digia, please use contact form at http://qt.digia.com + ** + ** This file is part of the Qt Commercial Charts Add-on. + ** + ** $QT_BEGIN_LICENSE$ + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Digia. + ** + ** If you have questions regarding the use of this file, please use + ** contact form at http://qt.digia.com + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include "view.h" +#include +#include +#include + +View::View(QGraphicsScene *scene, QGraphicsWidget *form , QWidget *parent):QGraphicsView(scene,parent), + m_form(form) +{ + setDragMode(QGraphicsView::NoDrag); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +void View::resizeEvent(QResizeEvent *event) +{ + if (scene()) + scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); + if (m_form) + m_form->resize(QSizeF(event->size())); + QGraphicsView::resizeEvent(event); +} + +void View::mouseMoveEvent(QMouseEvent *event) +{ + //BugFix somehow view always eats the mouse move event; + event->setAccepted(false); +} + +void View::mouseReleaseEvent(QMouseEvent *event) +{ + + QGraphicsView::mouseReleaseEvent(event); + //BugFix somehow view always eats the mouse release event; + event->setAccepted(false); +} diff --git a/demos/chartviewer/view.h b/demos/chartviewer/view.h new file mode 100644 index 0000000..7758495 --- /dev/null +++ b/demos/chartviewer/view.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIEW_H_ +#define VIEW_H_ +#include + +class QGraphicsScene; +class QResizeEvent; + +class View: public QGraphicsView +{ +public: + View(QGraphicsScene *scene, QGraphicsWidget *form , QWidget *parent = 0); + +protected: + void resizeEvent(QResizeEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); +private: + QGraphicsWidget *m_form; +}; + +#endif diff --git a/demos/chartviewer/chartwindow.cpp b/demos/chartviewer/window.cpp similarity index 70% rename from demos/chartviewer/chartwindow.cpp rename to demos/chartviewer/window.cpp index d7ecdf7..cafb27a 100644 --- a/demos/chartviewer/chartwindow.cpp +++ b/demos/chartviewer/window.cpp @@ -18,7 +18,8 @@ ** ****************************************************************************/ -#include "chartwindow.h" +#include "window.h" +#include "view.h" #include #include @@ -49,11 +50,27 @@ #include #include -ChartWindow::ChartWindow(QWidget* parent) : - QMainWindow(parent), m_listCount(3), m_valueMax(10), m_valueCount(7), m_scene( - new QGraphicsScene(this)), m_view(0), m_dataTable( - generateRandomData(m_listCount, m_valueMax, m_valueCount)), m_form(0), m_themeComboBox(0), m_antialiasCheckBox( - 0), m_animatedComboBox(0), m_legendComboBox(0), m_openGLCheckBox(0) +Window::Window(QWidget* parent) : + QMainWindow(parent), + m_listCount(3), + m_valueMax(10), + m_valueCount(7), + m_scene(new QGraphicsScene(this)), + m_view(0), + m_dataTable(generateRandomData(m_listCount, m_valueMax, m_valueCount)), + m_form(0), + m_themeComboBox(0), + m_antialiasCheckBox(0), + m_animatedComboBox(0), + m_legendComboBox(0), + m_openGLCheckBox(0), + m_zoomCheckBox(0), + m_scrollCheckBox(0), + m_rubberBand(new QGraphicsRectItem()), + m_isScrolling(false), + m_isZooming(false), + m_scroll(false), + m_zoom(false) { createProxyWidgets(); connectSignals(); @@ -71,6 +88,8 @@ ChartWindow::ChartWindow(QWidget* parent) : settingsLayout->addItem(m_widgetHash["animatedComboBox"]); settingsLayout->addItem(m_widgetHash["legendLabel"]); settingsLayout->addItem(m_widgetHash["legendComboBox"]); + settingsLayout->addItem(m_widgetHash["scrollCheckBox"]); + settingsLayout->addItem(m_widgetHash["zoomCheckBox"]); settingsLayout->addStretch(); baseLayout->addItem(settingsLayout, 0, 3, 2, 1); //create charts @@ -107,34 +126,37 @@ ChartWindow::ChartWindow(QWidget* parent) : baseLayout->addItem(chart, 1, 2); m_chartList << chart; - // Set defaults - //m_antialiasCheckBox->setChecked(true); - m_form = new QGraphicsWidget(); m_form->setLayout(baseLayout); m_scene->addItem(m_form); + m_scene->addItem(m_rubberBand); + m_rubberBand->setVisible(false); - m_view = new GraphicsView(m_scene, m_form); + m_view = new View(m_scene, m_form); m_view->setMinimumSize(m_form->preferredSize().toSize()); + // Set defaults + m_antialiasCheckBox->setChecked(true); updateUI(); setCentralWidget(m_view); } -ChartWindow::~ChartWindow() +Window::~Window() { } -void ChartWindow::connectSignals() +void Window::connectSignals() { connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); connect(m_openGLCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); + connect(m_zoomCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); + connect(m_scrollCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); connect(m_legendComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); } -DataTable ChartWindow::generateRandomData(int listCount, int valueMax, int valueCount) const +DataTable Window::generateRandomData(int listCount, int valueMax, int valueCount) const { DataTable dataTable; @@ -159,13 +181,15 @@ DataTable ChartWindow::generateRandomData(int listCount, int valueMax, int value return dataTable; } -void ChartWindow::createProxyWidgets() +void Window::createProxyWidgets() { m_themeComboBox = createThemeBox(); m_antialiasCheckBox = new QCheckBox(tr("Anti-aliasing")); m_animatedComboBox = createAnimationBox(); m_legendComboBox = createLegendBox(); m_openGLCheckBox = new QCheckBox(tr("OpenGL")); + m_zoomCheckBox = new QCheckBox(tr("Zoom")); + m_scrollCheckBox = new QCheckBox(tr("Scroll")); m_widgetHash["themeComboBox"] = m_scene->addWidget(m_themeComboBox); m_widgetHash["antialiasCheckBox"] = m_scene->addWidget(m_antialiasCheckBox); m_widgetHash["animatedComboBox"] = m_scene->addWidget(m_animatedComboBox); @@ -174,9 +198,11 @@ void ChartWindow::createProxyWidgets() m_widgetHash["themeLabel"] = m_scene->addWidget(new QLabel("Theme")); m_widgetHash["animationsLabel"] = m_scene->addWidget(new QLabel("Animations")); m_widgetHash["legendLabel"] = m_scene->addWidget(new QLabel("Legend")); + m_widgetHash["zoomCheckBox"] = m_scene->addWidget(m_zoomCheckBox); + m_widgetHash["scrollCheckBox"] = m_scene->addWidget(m_scrollCheckBox); } -QComboBox* ChartWindow::createThemeBox() const +QComboBox* Window::createThemeBox() const { // settings layoutQGLWidget’ QComboBox* themeComboBox = new QComboBox(); @@ -190,7 +216,7 @@ QComboBox* ChartWindow::createThemeBox() const return themeComboBox; } -QComboBox* ChartWindow::createAnimationBox() const +QComboBox* Window::createAnimationBox() const { // settings layout QComboBox* animationComboBox = new QComboBox(); @@ -201,7 +227,7 @@ QComboBox* ChartWindow::createAnimationBox() const return animationComboBox; } -QComboBox* ChartWindow::createLegendBox() const +QComboBox* Window::createLegendBox() const { QComboBox* legendComboBox = new QComboBox(); legendComboBox->addItem("No Legend ", 0); @@ -212,7 +238,7 @@ QComboBox* ChartWindow::createLegendBox() const return legendComboBox; } -QChart* ChartWindow::createAreaChart() const +QChart* Window::createAreaChart() const { QChart *chart = new QChart(); // chart->axisX()->setNiceNumbersEnabled(true); @@ -245,7 +271,7 @@ QChart* ChartWindow::createAreaChart() const return chart; } -QChart* ChartWindow::createBarChart(int valueCount) const +QChart* Window::createBarChart(int valueCount) const { Q_UNUSED(valueCount); QChart* chart = new QChart(); @@ -266,7 +292,7 @@ QChart* ChartWindow::createBarChart(int valueCount) const return chart; } -QChart* ChartWindow::createLineChart() const +QChart* Window::createLineChart() const { QChart* chart = new QChart(); //TODO: chart->axisX()->setNiceNumbersEnabled(true); @@ -288,7 +314,7 @@ QChart* ChartWindow::createLineChart() const return chart; } -QChart* ChartWindow::createPieChart() const +QChart* Window::createPieChart() const { QChart* chart = new QChart(); chart->setTitle("Pie chart"); @@ -313,7 +339,7 @@ QChart* ChartWindow::createPieChart() const return chart; } -QChart* ChartWindow::createSplineChart() const +QChart* Window::createSplineChart() const { QChart* chart = new QChart(); //TODO: chart->axisX()->setNiceNumbersEnabled(true); @@ -333,7 +359,7 @@ QChart* ChartWindow::createSplineChart() const return chart; } -QChart* ChartWindow::createScatterChart() const +QChart* Window::createScatterChart() const { QChart* chart = new QChart(); //TODO: chart->axisX()->setNiceNumbersEnabled(true); @@ -353,13 +379,13 @@ QChart* ChartWindow::createScatterChart() const return chart; } -void ChartWindow::updateUI() +void Window::updateUI() { bool opengl = m_openGLCheckBox->isChecked(); bool isOpengl = qobject_cast(m_view->viewport()); if ((isOpengl && !opengl) || (!isOpengl && opengl)) { m_view->deleteLater(); - m_view = new GraphicsView(m_scene, m_form); + m_view = new View(m_scene, m_form); m_view->setViewport(!opengl ? new QWidget() : new QGLWidget()); setCentralWidget(m_view); } @@ -407,6 +433,7 @@ void ChartWindow::updateUI() widget->setPalette(pal); } m_view->setBackgroundBrush(pal.color((QPalette::Window))); + m_rubberBand->setPen(pal.color((QPalette::WindowText))); QChart::AnimationOptions options( m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt()); @@ -429,10 +456,129 @@ void ChartWindow::updateUI() } } - bool checked = m_antialiasCheckBox->isChecked(); + bool antialias = m_antialiasCheckBox->isChecked(); + if (opengl) - m_view->setRenderHint(QPainter::HighQualityAntialiasing, checked); + m_view->setRenderHint(QPainter::HighQualityAntialiasing, antialias); else - m_view->setRenderHint(QPainter::Antialiasing, checked); + m_view->setRenderHint(QPainter::Antialiasing, antialias); + + bool scroll = m_scrollCheckBox->isChecked(); + + if(!m_scroll & scroll){ + m_scroll=true; + m_zoom=false; + m_zoomCheckBox->setChecked(false); + } + + bool zoom = m_zoomCheckBox->isChecked(); + + if(!m_zoom & zoom){ + m_scroll=false; + m_zoom=true; + m_scrollCheckBox->setChecked(false); + } + +} + +void Window::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + + m_origin = event->pos(); + m_isScrolling = false; + m_isZooming = false; + + foreach (QChart *chart, m_chartList) { + + QRectF geometryRect = chart->geometry(); + QRectF plotArea = chart->plotArea(); + plotArea.translate(geometryRect.topLeft()); + if (plotArea.contains(m_origin)) { + m_isScrolling = m_scroll; + m_isZooming = m_zoom; + break; + } + } + + if (m_isZooming) { + m_rubberBand->setRect(QRectF(m_origin, QSize())); + m_rubberBand->setVisible(true); + } + event->accept(); + } + + if (event->button() == Qt::RightButton) { + m_origin = event->pos(); + m_isZooming = m_zoom; + } +} + +void Window::mouseMoveEvent(QMouseEvent *event) +{ + if (m_isScrolling || m_isZooming) { + + foreach (QChart *chart, m_chartList) { + + QRectF geometryRect = chart->geometry(); + QRectF plotArea = chart->plotArea(); + plotArea.translate(geometryRect.topLeft()); + + if (plotArea.contains(m_origin)) { + if (m_isScrolling) { + QPointF delta = m_origin - event->pos(); + chart->scroll(delta.x(), -delta.y()); + } + if (m_isZooming && plotArea.contains(event->pos())) { + m_rubberBand->setRect(QRectF(m_origin, event->pos()).normalized()); + } + break; + } + } + if(m_isScrolling) m_origin = event->pos(); + event->accept(); + } } +void Window::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_isScrolling = false; + if (m_isZooming) { + m_isZooming = false; + m_rubberBand->setVisible(false); + + foreach (QChart *chart, m_chartList) { + + QRectF geometryRect = chart->geometry(); + QRectF plotArea = chart->plotArea(); + plotArea.translate(geometryRect.topLeft()); + + if (plotArea.contains(m_origin)) { + QRectF rect = m_rubberBand->rect(); + chart->zoomIn(rect); + break; + } + } + } + event->accept(); + } + + if (event->button() == Qt::RightButton) { + + if (m_isZooming) { + foreach (QChart *chart, m_chartList) { + + QRectF geometryRect = chart->geometry(); + QRectF plotArea = chart->plotArea(); + plotArea.translate(geometryRect.topLeft()); + + if (plotArea.contains(m_origin)) { + QRectF rect = m_rubberBand->rect(); + chart->zoomOut(); + break; + } + } + } + } +} diff --git a/demos/chartviewer/chartwindow.h b/demos/chartviewer/window.h similarity index 73% rename from demos/chartviewer/chartwindow.h rename to demos/chartviewer/window.h index 6865246..ff83712 100644 --- a/demos/chartviewer/chartwindow.h +++ b/demos/chartviewer/window.h @@ -18,17 +18,18 @@ ** ****************************************************************************/ -#ifndef CHARTWINDOW_H_ -#define CHARTWINDOW_H_ +#ifndef WINDOW_H_ +#define WINDOW_H_ #include #include #include -#include -#include -#include class QComboBox; class QCheckBox; +class QGraphicsRectItem; +class QGraphicsScene; +class QGraphicsWidget; +class View; QTCOMMERCIALCHART_BEGIN_NAMESPACE class QChart; @@ -38,43 +39,19 @@ typedef QPair Data; typedef QList DataList; typedef QList DataTable; -class QGraphicsScene; - QTCOMMERCIALCHART_USE_NAMESPACE - -class GraphicsView: public QGraphicsView -{ -public: - GraphicsView(QGraphicsScene *scene, QGraphicsWidget *form , QWidget *parent = 0):QGraphicsView(scene,parent), m_form(form) - { - setWindowTitle(tr("Charts")); - } - -protected: - void resizeEvent(QResizeEvent *event) - { - if (scene()) - scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); - if (m_form) - m_form->resize(QSizeF(event->size())); - QGraphicsView::resizeEvent(event); - } -private: - QGraphicsWidget *m_form; -}; - - -class ChartWindow: public QMainWindow +class Window: public QMainWindow { Q_OBJECT public: - explicit ChartWindow(QWidget *parent = 0); - ~ChartWindow(); + explicit Window(QWidget *parent = 0); + ~Window(); private Q_SLOTS: void updateUI(); + private: DataTable generateRandomData(int listCount,int valueMax,int valueCount) const; QComboBox* createThemeBox() const; @@ -89,12 +66,18 @@ private: QChart* createScatterChart() const; void createProxyWidgets(); +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + + private: int m_listCount; int m_valueMax; int m_valueCount; QGraphicsScene* m_scene; - GraphicsView* m_view; + View* m_view; QHash m_widgetHash; QList m_chartList; DataTable m_dataTable; @@ -105,6 +88,15 @@ private: QComboBox *m_animatedComboBox; QComboBox *m_legendComboBox; QCheckBox *m_openGLCheckBox; + QCheckBox *m_zoomCheckBox; + QCheckBox *m_scrollCheckBox; + QPoint m_origin; + QGraphicsRectItem* m_rubberBand; + + bool m_isScrolling; + bool m_isZooming; + bool m_scroll; + bool m_zoom; }; #endif