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