##// END OF EJS Templates
Fix regression with right click zooming...
Titta Heikkala -
r2656:632e2826c0ad
parent child
Show More
@@ -1,318 +1,317
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qchartview.h"
21 #include "qchartview.h"
22 #include "qchartview_p.h"
22 #include "qchartview_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include <QGraphicsScene>
24 #include <QGraphicsScene>
25 #include <QRubberBand>
25 #include <QRubberBand>
26
26
27 /*!
27 /*!
28 \enum QChartView::RubberBand
28 \enum QChartView::RubberBand
29
29
30 This enum describes the different types of rubber bands that can be used for zoom rect selection
30 This enum describes the different types of rubber bands that can be used for zoom rect selection
31
31
32 \value NoRubberBand
32 \value NoRubberBand
33 \value VerticalRubberBand
33 \value VerticalRubberBand
34 \value HorizonalRubberBand
34 \value HorizonalRubberBand
35 \value RectangleRubberBand
35 \value RectangleRubberBand
36 */
36 */
37
37
38 /*!
38 /*!
39 \class QChartView
39 \class QChartView
40 \inmodule Qt Charts
40 \inmodule Qt Charts
41 \brief Standalone charting widget.
41 \brief Standalone charting widget.
42
42
43 QChartView is a standalone widget that can display charts. It does not require separate
43 QChartView is a standalone widget that can display charts. It does not require separate
44 QGraphicsScene to work. If you want to display a chart in your existing QGraphicsScene,
44 QGraphicsScene to work. If you want to display a chart in your existing QGraphicsScene,
45 you need to use the QChart (or QPolarChart) class instead.
45 you need to use the QChart (or QPolarChart) class instead.
46
46
47 \sa QChart, QPolarChart
47 \sa QChart, QPolarChart
48 */
48 */
49
49
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
51
51
52 /*!
52 /*!
53 Constructs a chartView object with parent \a parent.
53 Constructs a chartView object with parent \a parent.
54 */
54 */
55
55
56 QChartView::QChartView(QWidget *parent)
56 QChartView::QChartView(QWidget *parent)
57 : QGraphicsView(parent),
57 : QGraphicsView(parent),
58 d_ptr(new QChartViewPrivate(this))
58 d_ptr(new QChartViewPrivate(this))
59 {
59 {
60
60
61 }
61 }
62
62
63 /*!
63 /*!
64 Constructs a chartview object with parent \a parent to display a \a chart.
64 Constructs a chartview object with parent \a parent to display a \a chart.
65 Ownership of the \a chart is passed to chartview.
65 Ownership of the \a chart is passed to chartview.
66 */
66 */
67
67
68 QChartView::QChartView(QChart *chart, QWidget *parent)
68 QChartView::QChartView(QChart *chart, QWidget *parent)
69 : QGraphicsView(parent),
69 : QGraphicsView(parent),
70 d_ptr(new QChartViewPrivate(this, chart))
70 d_ptr(new QChartViewPrivate(this, chart))
71 {
71 {
72
72
73 }
73 }
74
74
75
75
76 /*!
76 /*!
77 Destroys the chartview object and the associated chart.
77 Destroys the chartview object and the associated chart.
78 */
78 */
79 QChartView::~QChartView()
79 QChartView::~QChartView()
80 {
80 {
81 }
81 }
82
82
83 /*!
83 /*!
84 Returns the pointer to the associated chart.
84 Returns the pointer to the associated chart.
85 */
85 */
86 QChart *QChartView::chart() const
86 QChart *QChartView::chart() const
87 {
87 {
88 return d_ptr->m_chart;
88 return d_ptr->m_chart;
89 }
89 }
90
90
91 /*!
91 /*!
92 Sets the current chart to \a chart. Ownership of the new chart is passed to chartview
92 Sets the current chart to \a chart. Ownership of the new chart is passed to chartview
93 and ownership of the previous chart is released.
93 and ownership of the previous chart is released.
94
94
95 To avoid memory leaks users need to make sure the previous chart is deleted.
95 To avoid memory leaks users need to make sure the previous chart is deleted.
96 */
96 */
97
97
98 void QChartView::setChart(QChart *chart)
98 void QChartView::setChart(QChart *chart)
99 {
99 {
100 d_ptr->setChart(chart);
100 d_ptr->setChart(chart);
101 }
101 }
102
102
103 /*!
103 /*!
104 Sets the rubber band flags to \a rubberBand.
104 Sets the rubber band flags to \a rubberBand.
105 Selected flags determine the way zooming is performed.
105 Selected flags determine the way zooming is performed.
106
106
107 \note Rubber band zooming is not supported for polar charts.
107 \note Rubber band zooming is not supported for polar charts.
108 */
108 */
109 void QChartView::setRubberBand(const RubberBands &rubberBand)
109 void QChartView::setRubberBand(const RubberBands &rubberBand)
110 {
110 {
111 #ifndef QT_NO_RUBBERBAND
111 #ifndef QT_NO_RUBBERBAND
112 d_ptr->m_rubberBandFlags = rubberBand;
112 d_ptr->m_rubberBandFlags = rubberBand;
113
113
114 if (!d_ptr->m_rubberBandFlags) {
114 if (!d_ptr->m_rubberBandFlags) {
115 delete d_ptr->m_rubberBand;
115 delete d_ptr->m_rubberBand;
116 d_ptr->m_rubberBand = 0;
116 d_ptr->m_rubberBand = 0;
117 return;
117 return;
118 }
118 }
119
119
120 if (!d_ptr->m_rubberBand) {
120 if (!d_ptr->m_rubberBand) {
121 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
121 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
122 d_ptr->m_rubberBand->setEnabled(true);
122 d_ptr->m_rubberBand->setEnabled(true);
123 }
123 }
124 #else
124 #else
125 Q_UNUSED(rubberBand);
125 Q_UNUSED(rubberBand);
126 qWarning("Unable to set rubber band because Qt is configured without it.");
126 qWarning("Unable to set rubber band because Qt is configured without it.");
127 #endif
127 #endif
128 }
128 }
129
129
130 /*!
130 /*!
131 Returns the rubber band flags that are currently being used by the widget.
131 Returns the rubber band flags that are currently being used by the widget.
132 */
132 */
133 QChartView::RubberBands QChartView::rubberBand() const
133 QChartView::RubberBands QChartView::rubberBand() const
134 {
134 {
135 return d_ptr->m_rubberBandFlags;
135 return d_ptr->m_rubberBandFlags;
136 }
136 }
137
137
138 /*!
138 /*!
139 If Left mouse button is pressed and the rubber band is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
139 If Left mouse button is pressed and the rubber band is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
140 If different mouse button is pressed and/or the rubber band is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
140 If different mouse button is pressed and/or the rubber band is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
141 */
141 */
142 void QChartView::mousePressEvent(QMouseEvent *event)
142 void QChartView::mousePressEvent(QMouseEvent *event)
143 {
143 {
144 #ifndef QT_NO_RUBBERBAND
144 #ifndef QT_NO_RUBBERBAND
145 QRectF plotArea = d_ptr->m_chart->plotArea();
145 QRectF plotArea = d_ptr->m_chart->plotArea();
146 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled()
146 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled()
147 && event->button() == Qt::LeftButton && plotArea.contains(event->pos())) {
147 && event->button() == Qt::LeftButton && plotArea.contains(event->pos())) {
148 d_ptr->m_rubberBandOrigin = event->pos();
148 d_ptr->m_rubberBandOrigin = event->pos();
149 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
149 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
150 d_ptr->m_rubberBand->show();
150 d_ptr->m_rubberBand->show();
151 event->accept();
151 event->accept();
152 } else {
152 } else {
153 #endif
153 #endif
154 QGraphicsView::mousePressEvent(event);
154 QGraphicsView::mousePressEvent(event);
155 #ifndef QT_NO_RUBBERBAND
155 #ifndef QT_NO_RUBBERBAND
156 }
156 }
157 #endif
157 #endif
158 }
158 }
159
159
160 /*!
160 /*!
161 If the rubber band rectange has been displayed in pressEvent then \a event data is used to update the rubber band geometry.
161 If the rubber band rectange has been displayed in pressEvent then \a event data is used to update the rubber band geometry.
162 Otherwise the default QGraphicsView::mouseMoveEvent implementation is called.
162 Otherwise the default QGraphicsView::mouseMoveEvent implementation is called.
163 */
163 */
164 void QChartView::mouseMoveEvent(QMouseEvent *event)
164 void QChartView::mouseMoveEvent(QMouseEvent *event)
165 {
165 {
166 #ifndef QT_NO_RUBBERBAND
166 #ifndef QT_NO_RUBBERBAND
167 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
167 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
168 QRect rect = d_ptr->m_chart->plotArea().toRect();
168 QRect rect = d_ptr->m_chart->plotArea().toRect();
169 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
169 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
170 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
170 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
171 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
171 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
172 d_ptr->m_rubberBandOrigin.setY(rect.top());
172 d_ptr->m_rubberBandOrigin.setY(rect.top());
173 height = rect.height();
173 height = rect.height();
174 }
174 }
175 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
175 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
176 d_ptr->m_rubberBandOrigin.setX(rect.left());
176 d_ptr->m_rubberBandOrigin.setX(rect.left());
177 width = rect.width();
177 width = rect.width();
178 }
178 }
179 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(), d_ptr->m_rubberBandOrigin.y(), width, height).normalized());
179 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(), d_ptr->m_rubberBandOrigin.y(), width, height).normalized());
180 } else {
180 } else {
181 #endif
181 #endif
182 QGraphicsView::mouseMoveEvent(event);
182 QGraphicsView::mouseMoveEvent(event);
183 #ifndef QT_NO_RUBBERBAND
183 #ifndef QT_NO_RUBBERBAND
184 }
184 }
185 #endif
185 #endif
186 }
186 }
187
187
188 /*!
188 /*!
189 If left mouse button is released and the rubber band is enabled then \a event is accepted and
189 If left mouse button is released and the rubber band is enabled then \a event is accepted and
190 the view is zoomed into the rect specified by the rubber band.
190 the view is zoomed into the rect specified by the rubber band.
191 If it is a right mouse button \a event then the view is zoomed out.
191 If it is a right mouse button \a event then the view is zoomed out.
192 */
192 */
193 void QChartView::mouseReleaseEvent(QMouseEvent *event)
193 void QChartView::mouseReleaseEvent(QMouseEvent *event)
194 {
194 {
195 #ifndef QT_NO_RUBBERBAND
195 #ifndef QT_NO_RUBBERBAND
196 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
196 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
197 if (event->button() == Qt::LeftButton) {
197 if (event->button() == Qt::LeftButton) {
198 d_ptr->m_rubberBand->hide();
198 d_ptr->m_rubberBand->hide();
199 QRectF rect = d_ptr->m_rubberBand->geometry();
199 QRectF rect = d_ptr->m_rubberBand->geometry();
200 // Since plotArea uses QRectF and rubberband uses QRect, we can't just blindly use
200 // Since plotArea uses QRectF and rubberband uses QRect, we can't just blindly use
201 // rubberband's dimensions for vertical and horizontal rubberbands, where one
201 // rubberband's dimensions for vertical and horizontal rubberbands, where one
202 // dimension must match the corresponding plotArea dimension exactly.
202 // dimension must match the corresponding plotArea dimension exactly.
203 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
203 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
204 rect.setX(d_ptr->m_chart->plotArea().x());
204 rect.setX(d_ptr->m_chart->plotArea().x());
205 rect.setWidth(d_ptr->m_chart->plotArea().width());
205 rect.setWidth(d_ptr->m_chart->plotArea().width());
206 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
206 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
207 rect.setY(d_ptr->m_chart->plotArea().y());
207 rect.setY(d_ptr->m_chart->plotArea().y());
208 rect.setHeight(d_ptr->m_chart->plotArea().height());
208 rect.setHeight(d_ptr->m_chart->plotArea().height());
209 }
209 }
210 d_ptr->m_chart->zoomIn(rect);
210 d_ptr->m_chart->zoomIn(rect);
211 event->accept();
211 event->accept();
212 }
212 }
213
213
214 if (event->button() == Qt::RightButton) {
214 } else if (d_ptr->m_rubberBand && event->button() == Qt::RightButton) {
215 // If vertical or horizontal rubberband mode, restrict zoom out to specified axis.
215 // If vertical or horizontal rubberband mode, restrict zoom out to specified axis.
216 // Since there is no suitable API for that, use zoomIn with rect bigger than the
216 // Since there is no suitable API for that, use zoomIn with rect bigger than the
217 // plot area.
217 // plot area.
218 if (d_ptr->m_rubberBandFlags == VerticalRubberBand
218 if (d_ptr->m_rubberBandFlags == VerticalRubberBand
219 || d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
219 || d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
220 QRectF rect = d_ptr->m_chart->plotArea();
220 QRectF rect = d_ptr->m_chart->plotArea();
221 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
221 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
222 qreal adjustment = rect.height() / 2;
222 qreal adjustment = rect.height() / 2;
223 rect.adjust(0, -adjustment, 0, adjustment);
223 rect.adjust(0, -adjustment, 0, adjustment);
224 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
224 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
225 qreal adjustment = rect.width() / 2;
225 qreal adjustment = rect.width() / 2;
226 rect.adjust(-adjustment, 0, adjustment, 0);
226 rect.adjust(-adjustment, 0, adjustment, 0);
227 }
227 }
228 d_ptr->m_chart->zoomIn(rect);
228 d_ptr->m_chart->zoomIn(rect);
229 } else {
229 } else {
230 d_ptr->m_chart->zoomOut();
230 d_ptr->m_chart->zoomOut();
231 }
231 }
232 event->accept();
232 event->accept();
233 }
234 } else {
233 } else {
235 #endif
234 #endif
236 QGraphicsView::mouseReleaseEvent(event);
235 QGraphicsView::mouseReleaseEvent(event);
237 #ifndef QT_NO_RUBBERBAND
236 #ifndef QT_NO_RUBBERBAND
238 }
237 }
239 #endif
238 #endif
240 }
239 }
241
240
242 /*!
241 /*!
243 Resizes and updates the chart area using the \a event data
242 Resizes and updates the chart area using the \a event data
244 */
243 */
245 void QChartView::resizeEvent(QResizeEvent *event)
244 void QChartView::resizeEvent(QResizeEvent *event)
246 {
245 {
247 QGraphicsView::resizeEvent(event);
246 QGraphicsView::resizeEvent(event);
248 d_ptr->resize();
247 d_ptr->resize();
249 }
248 }
250
249
251 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
250 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
252
251
253 QChartViewPrivate::QChartViewPrivate(QChartView *q, QChart *chart)
252 QChartViewPrivate::QChartViewPrivate(QChartView *q, QChart *chart)
254 : q_ptr(q),
253 : q_ptr(q),
255 m_scene(new QGraphicsScene(q)),
254 m_scene(new QGraphicsScene(q)),
256 m_chart(chart),
255 m_chart(chart),
257 #ifndef QT_NO_RUBBERBAND
256 #ifndef QT_NO_RUBBERBAND
258 m_rubberBand(0),
257 m_rubberBand(0),
259 #endif
258 #endif
260 m_rubberBandFlags(QChartView::NoRubberBand)
259 m_rubberBandFlags(QChartView::NoRubberBand)
261 {
260 {
262 q_ptr->setFrameShape(QFrame::NoFrame);
261 q_ptr->setFrameShape(QFrame::NoFrame);
263 q_ptr->setBackgroundRole(QPalette::Window);
262 q_ptr->setBackgroundRole(QPalette::Window);
264 q_ptr->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
263 q_ptr->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
265 q_ptr->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
264 q_ptr->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
266 q_ptr->setScene(m_scene);
265 q_ptr->setScene(m_scene);
267 q_ptr->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
266 q_ptr->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
268 if (!m_chart)
267 if (!m_chart)
269 m_chart = new QChart();
268 m_chart = new QChart();
270 m_scene->addItem(m_chart);
269 m_scene->addItem(m_chart);
271 }
270 }
272
271
273 QChartViewPrivate::~QChartViewPrivate()
272 QChartViewPrivate::~QChartViewPrivate()
274 {
273 {
275 }
274 }
276
275
277 void QChartViewPrivate::setChart(QChart *chart)
276 void QChartViewPrivate::setChart(QChart *chart)
278 {
277 {
279 Q_ASSERT(chart);
278 Q_ASSERT(chart);
280
279
281 if (m_chart == chart)
280 if (m_chart == chart)
282 return;
281 return;
283
282
284 if (m_chart)
283 if (m_chart)
285 m_scene->removeItem(m_chart);
284 m_scene->removeItem(m_chart);
286
285
287 m_chart = chart;
286 m_chart = chart;
288 m_scene->addItem(m_chart);
287 m_scene->addItem(m_chart);
289
288
290 resize();
289 resize();
291 }
290 }
292
291
293 void QChartViewPrivate::resize()
292 void QChartViewPrivate::resize()
294 {
293 {
295 // Fit the chart into view if it has been rotated
294 // Fit the chart into view if it has been rotated
296 qreal sinA = qAbs(q_ptr->transform().m21());
295 qreal sinA = qAbs(q_ptr->transform().m21());
297 qreal cosA = qAbs(q_ptr->transform().m11());
296 qreal cosA = qAbs(q_ptr->transform().m11());
298 QSize chartSize = q_ptr->size();
297 QSize chartSize = q_ptr->size();
299
298
300 if (sinA == 1.0) {
299 if (sinA == 1.0) {
301 chartSize.setHeight(q_ptr->size().width());
300 chartSize.setHeight(q_ptr->size().width());
302 chartSize.setWidth(q_ptr->size().height());
301 chartSize.setWidth(q_ptr->size().height());
303 } else if (sinA != 0.0) {
302 } else if (sinA != 0.0) {
304 // Non-90 degree rotation, find largest square chart that can fit into the view.
303 // Non-90 degree rotation, find largest square chart that can fit into the view.
305 qreal minDimension = qMin(q_ptr->size().width(), q_ptr->size().height());
304 qreal minDimension = qMin(q_ptr->size().width(), q_ptr->size().height());
306 qreal h = (minDimension - (minDimension / ((sinA / cosA) + 1.0))) / sinA;
305 qreal h = (minDimension - (minDimension / ((sinA / cosA) + 1.0))) / sinA;
307 chartSize.setHeight(h);
306 chartSize.setHeight(h);
308 chartSize.setWidth(h);
307 chartSize.setWidth(h);
309 }
308 }
310
309
311 m_chart->resize(chartSize);
310 m_chart->resize(chartSize);
312 q_ptr->setMinimumSize(m_chart->minimumSize().toSize());
311 q_ptr->setMinimumSize(m_chart->minimumSize().toSize());
313 q_ptr->setSceneRect(m_chart->geometry());
312 q_ptr->setSceneRect(m_chart->geometry());
314 }
313 }
315
314
316 #include "moc_qchartview.cpp"
315 #include "moc_qchartview.cpp"
317
316
318 QTCOMMERCIALCHART_END_NAMESPACE
317 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now