window.cpp
458 lines
| 14.9 KiB
| text/x-c
|
CppLexer
Michal Klocek
|
r1746 | /**************************************************************************** | ||
** | ||||
** 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$ | ||||
** | ||||
****************************************************************************/ | ||||
Michal Klocek
|
r1748 | #include "window.h" | ||
#include "view.h" | ||||
Michal Klocek
|
r1753 | #include "charts.h" | ||
Michal Klocek
|
r1746 | #include <QChartView> | ||
#include <QAreaSeries> | ||||
#include <QLegend> | ||||
#include <QGridLayout> | ||||
#include <QFormLayout> | ||||
#include <QComboBox> | ||||
#include <QSpinBox> | ||||
#include <QCheckBox> | ||||
#include <QGroupBox> | ||||
#include <QLabel> | ||||
#include <QGraphicsScene> | ||||
#include <QGraphicsGridLayout> | ||||
#include <QGraphicsLinearLayout> | ||||
#include <QGraphicsProxyWidget> | ||||
#include <QGLWidget> | ||||
#include <QApplication> | ||||
#include <QDebug> | ||||
Michal Klocek
|
r1840 | #include <QMenu> | ||
Michal Klocek
|
r1746 | |||
Michal Klocek
|
r1748 | Window::Window(QWidget* parent) : | ||
QMainWindow(parent), | ||||
m_listCount(3), | ||||
m_valueMax(10), | ||||
m_valueCount(7), | ||||
m_scene(new QGraphicsScene(this)), | ||||
m_view(0), | ||||
Michal Klocek
|
r1755 | m_dataTable(Model::generateRandomData(m_listCount, m_valueMax, m_valueCount)), | ||
Michal Klocek
|
r1748 | 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()), | ||||
Michal Klocek
|
r1840 | m_baseLayout(new QGraphicsGridLayout()), | ||
m_menu(new QMenu(this)), | ||||
m_state(NoState), | ||||
m_currentState(NoState) | ||||
Michal Klocek
|
r1746 | { | ||
createProxyWidgets(); | ||||
connectSignals(); | ||||
// create layout | ||||
QGraphicsLinearLayout *settingsLayout = new QGraphicsLinearLayout(); | ||||
settingsLayout->setOrientation(Qt::Vertical); | ||||
settingsLayout->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); | ||||
settingsLayout->addItem(m_widgetHash["openGLCheckBox"]); | ||||
settingsLayout->addItem(m_widgetHash["antialiasCheckBox"]); | ||||
settingsLayout->addItem(m_widgetHash["themeLabel"]); | ||||
settingsLayout->addItem(m_widgetHash["themeComboBox"]); | ||||
settingsLayout->addItem(m_widgetHash["animationsLabel"]); | ||||
settingsLayout->addItem(m_widgetHash["animatedComboBox"]); | ||||
settingsLayout->addItem(m_widgetHash["legendLabel"]); | ||||
settingsLayout->addItem(m_widgetHash["legendComboBox"]); | ||||
Michal Klocek
|
r1748 | settingsLayout->addItem(m_widgetHash["scrollCheckBox"]); | ||
settingsLayout->addItem(m_widgetHash["zoomCheckBox"]); | ||||
Michal Klocek
|
r1746 | settingsLayout->addStretch(); | ||
Michal Klocek
|
r1840 | m_baseLayout->addItem(settingsLayout, 0, 3, 2, 1); | ||
Michal Klocek
|
r1746 | //create charts | ||
Michal Klocek
|
r1753 | Charts::ChartList list = Charts::chartList(); | ||
Michal Klocek
|
r1746 | |||
Michal Klocek
|
r1840 | for (int i = 0; i < 9 && i < list.size(); ++i) { | ||
Michal Klocek
|
r1753 | QChart* chart = list.at(i)->createChart(m_dataTable); | ||
Michal Klocek
|
r1840 | m_baseLayout->addItem(chart, i / 3, i % 3); | ||
m_chartHash[chart] = i; | ||||
} | ||||
foreach(Chart* chart, list) { | ||||
createMenuAction(m_menu, QIcon(), chart->name(), qVariantFromValue((void *) chart)); | ||||
Michal Klocek
|
r1753 | } | ||
Michal Klocek
|
r1746 | |||
m_form = new QGraphicsWidget(); | ||||
Michal Klocek
|
r1840 | m_form->setLayout(m_baseLayout); | ||
Michal Klocek
|
r1746 | m_scene->addItem(m_form); | ||
Michal Klocek
|
r1748 | m_scene->addItem(m_rubberBand); | ||
m_rubberBand->setVisible(false); | ||||
Michal Klocek
|
r1746 | |||
Michal Klocek
|
r1748 | m_view = new View(m_scene, m_form); | ||
Michal Klocek
|
r1746 | m_view->setMinimumSize(m_form->preferredSize().toSize()); | ||
Michal Klocek
|
r1748 | // Set defaults | ||
m_antialiasCheckBox->setChecked(true); | ||||
Michal Klocek
|
r1746 | updateUI(); | ||
setCentralWidget(m_view); | ||||
} | ||||
Michal Klocek
|
r1748 | Window::~Window() | ||
Michal Klocek
|
r1746 | { | ||
} | ||||
Michal Klocek
|
r1748 | void Window::connectSignals() | ||
Michal Klocek
|
r1746 | { | ||
Michal Klocek
|
r1754 | QObject::connect(m_themeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); | ||
QObject::connect(m_antialiasCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); | ||||
QObject::connect(m_openGLCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); | ||||
QObject::connect(m_zoomCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); | ||||
QObject::connect(m_scrollCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateUI())); | ||||
QObject::connect(m_animatedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); | ||||
QObject::connect(m_legendComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI())); | ||||
Michal Klocek
|
r1746 | } | ||
Michal Klocek
|
r1748 | void Window::createProxyWidgets() | ||
Michal Klocek
|
r1746 | { | ||
m_themeComboBox = createThemeBox(); | ||||
m_antialiasCheckBox = new QCheckBox(tr("Anti-aliasing")); | ||||
m_animatedComboBox = createAnimationBox(); | ||||
m_legendComboBox = createLegendBox(); | ||||
m_openGLCheckBox = new QCheckBox(tr("OpenGL")); | ||||
Michal Klocek
|
r1748 | m_zoomCheckBox = new QCheckBox(tr("Zoom")); | ||
m_scrollCheckBox = new QCheckBox(tr("Scroll")); | ||||
Michal Klocek
|
r1746 | m_widgetHash["themeComboBox"] = m_scene->addWidget(m_themeComboBox); | ||
m_widgetHash["antialiasCheckBox"] = m_scene->addWidget(m_antialiasCheckBox); | ||||
m_widgetHash["animatedComboBox"] = m_scene->addWidget(m_animatedComboBox); | ||||
m_widgetHash["legendComboBox"] = m_scene->addWidget(m_legendComboBox); | ||||
m_widgetHash["openGLCheckBox"] = m_scene->addWidget(m_openGLCheckBox); | ||||
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")); | ||||
Michal Klocek
|
r1748 | m_widgetHash["zoomCheckBox"] = m_scene->addWidget(m_zoomCheckBox); | ||
m_widgetHash["scrollCheckBox"] = m_scene->addWidget(m_scrollCheckBox); | ||||
Michal Klocek
|
r1746 | } | ||
Michal Klocek
|
r1754 | QComboBox* Window::createThemeBox() | ||
Michal Klocek
|
r1746 | { | ||
Michal Klocek
|
r1754 | QComboBox* themeComboBox = new ComboBox(this); | ||
Michal Klocek
|
r1746 | themeComboBox->addItem("Light", QChart::ChartThemeLight); | ||
themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean); | ||||
themeComboBox->addItem("Dark", QChart::ChartThemeDark); | ||||
themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand); | ||||
themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs); | ||||
themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast); | ||||
themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy); | ||||
return themeComboBox; | ||||
} | ||||
Michal Klocek
|
r1754 | QComboBox* Window::createAnimationBox() | ||
Michal Klocek
|
r1746 | { | ||
Michal Klocek
|
r1754 | QComboBox* animationComboBox = new ComboBox(this); | ||
Michal Klocek
|
r1746 | animationComboBox->addItem("No Animations", QChart::NoAnimation); | ||
animationComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations); | ||||
animationComboBox->addItem("Series Animations", QChart::SeriesAnimations); | ||||
animationComboBox->addItem("All Animations", QChart::AllAnimations); | ||||
return animationComboBox; | ||||
} | ||||
Michal Klocek
|
r1754 | QComboBox* Window::createLegendBox() | ||
Michal Klocek
|
r1746 | { | ||
Michal Klocek
|
r1754 | QComboBox* legendComboBox = new ComboBox(this); | ||
Michal Klocek
|
r1746 | legendComboBox->addItem("No Legend ", 0); | ||
legendComboBox->addItem("Legend Top", Qt::AlignTop); | ||||
legendComboBox->addItem("Legend Bottom", Qt::AlignBottom); | ||||
legendComboBox->addItem("Legend Left", Qt::AlignLeft); | ||||
legendComboBox->addItem("Legend Right", Qt::AlignRight); | ||||
return legendComboBox; | ||||
} | ||||
Michal Klocek
|
r1748 | void Window::updateUI() | ||
Michal Klocek
|
r1840 | { | ||
checkOpenGL(); | ||||
checkTheme(); | ||||
checkAnimationOptions(); | ||||
checkLegend(); | ||||
checkState(); | ||||
} | ||||
void Window::checkLegend() | ||||
{ | ||||
Qt::Alignment alignment(m_legendComboBox->itemData(m_legendComboBox->currentIndex()).toInt()); | ||||
if (!alignment) { | ||||
foreach (QChart *chart, m_chartHash.keys()) { | ||||
chart->legend()->hide(); | ||||
} | ||||
} | ||||
else { | ||||
foreach (QChart *chart, m_chartHash.keys()) { | ||||
chart->legend()->setAlignment(alignment); | ||||
chart->legend()->show(); | ||||
} | ||||
} | ||||
} | ||||
void Window::checkOpenGL() | ||||
Michal Klocek
|
r1746 | { | ||
bool opengl = m_openGLCheckBox->isChecked(); | ||||
bool isOpengl = qobject_cast<QGLWidget*>(m_view->viewport()); | ||||
if ((isOpengl && !opengl) || (!isOpengl && opengl)) { | ||||
m_view->deleteLater(); | ||||
Michal Klocek
|
r1748 | m_view = new View(m_scene, m_form); | ||
Michal Klocek
|
r1746 | m_view->setViewport(!opengl ? new QWidget() : new QGLWidget()); | ||
setCentralWidget(m_view); | ||||
} | ||||
Michal Klocek
|
r1840 | bool antialias = m_antialiasCheckBox->isChecked(); | ||
if (opengl) | ||||
m_view->setRenderHint(QPainter::HighQualityAntialiasing, antialias); | ||||
else | ||||
m_view->setRenderHint(QPainter::Antialiasing, antialias); | ||||
} | ||||
void Window::checkAnimationOptions() | ||||
{ | ||||
QChart::AnimationOptions options( | ||||
m_animatedComboBox->itemData(m_animatedComboBox->currentIndex()).toInt()); | ||||
if (!m_chartHash.isEmpty() && m_chartHash.keys().at(0)->animationOptions() != options) { | ||||
foreach (QChart *chart, m_chartHash.keys()) | ||||
chart->setAnimationOptions(options); | ||||
} | ||||
} | ||||
void Window::checkState() | ||||
{ | ||||
bool scroll = m_scrollCheckBox->isChecked(); | ||||
if (m_state != ScrollState && scroll) { | ||||
m_state = ScrollState; | ||||
m_zoomCheckBox->setChecked(false); | ||||
} | ||||
else if (!scroll && m_state == ScrollState) { | ||||
m_state = NoState; | ||||
} | ||||
bool zoom = m_zoomCheckBox->isChecked(); | ||||
if (m_state != ZoomState && zoom) { | ||||
m_state = ZoomState; | ||||
m_scrollCheckBox->setChecked(false); | ||||
} | ||||
else if (!zoom && m_state == ZoomState) { | ||||
m_state = NoState; | ||||
} | ||||
} | ||||
void Window::checkTheme() | ||||
{ | ||||
Michal Klocek
|
r1746 | QChart::ChartTheme theme = (QChart::ChartTheme) m_themeComboBox->itemData( | ||
m_themeComboBox->currentIndex()).toInt(); | ||||
Michal Klocek
|
r1840 | foreach (QChart *chart, m_chartHash.keys()) | ||
Michal Klocek
|
r1746 | chart->setTheme(theme); | ||
QPalette pal = window()->palette(); | ||||
if (theme == QChart::ChartThemeLight) { | ||||
pal.setColor(QPalette::Window, QRgb(0xf0f0f0)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x404044)); | ||||
} | ||||
else if (theme == QChart::ChartThemeDark) { | ||||
pal.setColor(QPalette::Window, QRgb(0x121218)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6)); | ||||
} | ||||
else if (theme == QChart::ChartThemeBlueCerulean) { | ||||
pal.setColor(QPalette::Window, QRgb(0x40434a)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6)); | ||||
} | ||||
else if (theme == QChart::ChartThemeBrownSand) { | ||||
pal.setColor(QPalette::Window, QRgb(0x9e8965)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x404044)); | ||||
} | ||||
else if (theme == QChart::ChartThemeBlueNcs) { | ||||
pal.setColor(QPalette::Window, QRgb(0x018bba)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x404044)); | ||||
} | ||||
else if (theme == QChart::ChartThemeHighContrast) { | ||||
pal.setColor(QPalette::Window, QRgb(0xffab03)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x181818)); | ||||
} | ||||
else if (theme == QChart::ChartThemeBlueIcy) { | ||||
pal.setColor(QPalette::Window, QRgb(0xcee7f0)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x404044)); | ||||
} | ||||
else { | ||||
pal.setColor(QPalette::Window, QRgb(0xf0f0f0)); | ||||
pal.setColor(QPalette::WindowText, QRgb(0x404044)); | ||||
} | ||||
foreach(QGraphicsProxyWidget* widget , m_widgetHash) { | ||||
widget->setPalette(pal); | ||||
} | ||||
m_view->setBackgroundBrush(pal.color((QPalette::Window))); | ||||
Michal Klocek
|
r1748 | m_rubberBand->setPen(pal.color((QPalette::WindowText))); | ||
} | ||||
void Window::mousePressEvent(QMouseEvent *event) | ||||
{ | ||||
if (event->button() == Qt::LeftButton) { | ||||
m_origin = event->pos(); | ||||
Michal Klocek
|
r1840 | m_currentState = NoState; | ||
Michal Klocek
|
r1748 | |||
Michal Klocek
|
r1840 | foreach (QChart *chart, m_chartHash.keys()) { | ||
Michal Klocek
|
r1748 | |||
QRectF geometryRect = chart->geometry(); | ||||
QRectF plotArea = chart->plotArea(); | ||||
plotArea.translate(geometryRect.topLeft()); | ||||
if (plotArea.contains(m_origin)) { | ||||
Michal Klocek
|
r1840 | m_currentState = m_state; | ||
if (m_currentState == NoState) { | ||||
showMenu(chart); | ||||
} | ||||
Michal Klocek
|
r1748 | break; | ||
} | ||||
} | ||||
Michal Klocek
|
r1840 | if (m_currentState == ZoomState) { | ||
Michal Klocek
|
r1748 | m_rubberBand->setRect(QRectF(m_origin, QSize())); | ||
m_rubberBand->setVisible(true); | ||||
} | ||||
Michal Klocek
|
r1840 | |||
Michal Klocek
|
r1748 | event->accept(); | ||
} | ||||
if (event->button() == Qt::RightButton) { | ||||
m_origin = event->pos(); | ||||
Michal Klocek
|
r1840 | m_currentState = m_state; | ||
Michal Klocek
|
r1748 | } | ||
} | ||||
void Window::mouseMoveEvent(QMouseEvent *event) | ||||
{ | ||||
Michal Klocek
|
r1840 | if ( m_currentState != NoState) { | ||
Michal Klocek
|
r1748 | |||
Michal Klocek
|
r1840 | foreach (QChart *chart, m_chartHash.keys()) { | ||
Michal Klocek
|
r1748 | |||
QRectF geometryRect = chart->geometry(); | ||||
QRectF plotArea = chart->plotArea(); | ||||
plotArea.translate(geometryRect.topLeft()); | ||||
if (plotArea.contains(m_origin)) { | ||||
Michal Klocek
|
r1840 | if (m_currentState == ScrollState) { | ||
Michal Klocek
|
r1748 | QPointF delta = m_origin - event->pos(); | ||
chart->scroll(delta.x(), -delta.y()); | ||||
} | ||||
Michal Klocek
|
r1840 | if (m_currentState == ZoomState && plotArea.contains(event->pos())) { | ||
Michal Klocek
|
r1748 | m_rubberBand->setRect(QRectF(m_origin, event->pos()).normalized()); | ||
} | ||||
break; | ||||
} | ||||
} | ||||
Michal Klocek
|
r1840 | if(m_currentState == ScrollState) m_origin = event->pos(); | ||
Michal Klocek
|
r1748 | event->accept(); | ||
} | ||||
Michal Klocek
|
r1746 | } | ||
Michal Klocek
|
r1748 | void Window::mouseReleaseEvent(QMouseEvent *event) | ||
{ | ||||
if (event->button() == Qt::LeftButton) { | ||||
Michal Klocek
|
r1840 | if (m_currentState == ZoomState) { | ||
Michal Klocek
|
r1748 | m_rubberBand->setVisible(false); | ||
Michal Klocek
|
r1840 | foreach (QChart *chart, m_chartHash.keys()) { | ||
Michal Klocek
|
r1748 | |||
QRectF geometryRect = chart->geometry(); | ||||
QRectF plotArea = chart->plotArea(); | ||||
plotArea.translate(geometryRect.topLeft()); | ||||
if (plotArea.contains(m_origin)) { | ||||
QRectF rect = m_rubberBand->rect(); | ||||
Michal Klocek
|
r1751 | rect.translate(-geometryRect.topLeft()); | ||
Michal Klocek
|
r1748 | chart->zoomIn(rect); | ||
break; | ||||
} | ||||
} | ||||
} | ||||
Michal Klocek
|
r1840 | |||
m_currentState = NoState; | ||||
Michal Klocek
|
r1748 | event->accept(); | ||
} | ||||
if (event->button() == Qt::RightButton) { | ||||
Michal Klocek
|
r1840 | if (m_currentState == ZoomState) { | ||
foreach (QChart *chart, m_chartHash.keys()) { | ||||
Michal Klocek
|
r1748 | |||
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; | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
Michal Klocek
|
r1754 | |||
void Window::comboBoxFocused(QComboBox *combobox) | ||||
{ | ||||
foreach(QGraphicsProxyWidget* widget , m_widgetHash) { | ||||
if(widget->widget()==combobox) | ||||
widget->setZValue(2.0); | ||||
else | ||||
widget->setZValue(0.0); | ||||
} | ||||
} | ||||
Michal Klocek
|
r1840 | |||
void Window::showMenu(QChart* qchart) | ||||
{ | ||||
QAction *chosen = m_menu->exec(QCursor::pos()); | ||||
if (chosen) { | ||||
Chart* chart = (Chart *) chosen->data().value<void *>(); | ||||
int index = m_chartHash[qchart]; | ||||
Michal Klocek
|
r1853 | //not in 4.7.2 m_baseLayout->removeItem(qchart); | ||
for(int i = 0 ; i < m_baseLayout->count();++i) | ||||
{ | ||||
if(m_baseLayout->itemAt(i)==qchart){ | ||||
m_baseLayout->removeAt(i); | ||||
break; | ||||
} | ||||
} | ||||
Michal Klocek
|
r1840 | m_chartHash.remove(qchart); | ||
QChart* newChart = chart->createChart(m_dataTable); | ||||
m_baseLayout->addItem(newChart, index / 3, index % 3); | ||||
m_chartHash[newChart] = index; | ||||
delete qchart; | ||||
updateUI(); | ||||
} | ||||
} | ||||
QAction* Window::createMenuAction(QMenu *menu, const QIcon &icon, const QString &text, | ||||
const QVariant &data) | ||||
{ | ||||
QAction *action = menu->addAction(icon, text); | ||||
action->setCheckable(false); | ||||
action->setData(data); | ||||
return action; | ||||
} | ||||