##// END OF EJS Templates
Adds ScrolledQLegend...
Michal Klocek -
r859:e87be6f0a1e1
parent child
Show More
@@ -1,351 +1,351
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include <QGraphicsScene>
23 #include <QGraphicsScene>
24 #include <QGraphicsSceneResizeEvent>
24 #include <QGraphicsSceneResizeEvent>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 /*!
28 /*!
29 \enum QChart::ChartTheme
29 \enum QChart::ChartTheme
30
30
31 This enum describes the theme used by the chart.
31 This enum describes the theme used by the chart.
32
32
33 \value ChartThemeLight The default theme
33 \value ChartThemeLight The default theme
34 \value ChartThemeBlueCerulean
34 \value ChartThemeBlueCerulean
35 \value ChartThemeDark
35 \value ChartThemeDark
36 \value ChartThemeBrownSand
36 \value ChartThemeBrownSand
37 \value ChartThemeBlueNcs
37 \value ChartThemeBlueNcs
38 \value ChartThemeHighContrast
38 \value ChartThemeHighContrast
39 \value ChartThemeBlueIcy
39 \value ChartThemeBlueIcy
40 \value ChartThemeCount Not really a theme; the total count of themes.
40 \value ChartThemeCount Not really a theme; the total count of themes.
41 */
41 */
42
42
43 /*!
43 /*!
44 \enum QChart::AnimationOption
44 \enum QChart::AnimationOption
45
45
46 For enabling/disabling animations. Defaults to NoAnimation.
46 For enabling/disabling animations. Defaults to NoAnimation.
47
47
48 \value NoAnimation
48 \value NoAnimation
49 \value GridAxisAnimations
49 \value GridAxisAnimations
50 \value SeriesAnimations
50 \value SeriesAnimations
51 \value AllAnimations
51 \value AllAnimations
52 */
52 */
53
53
54 /*!
54 /*!
55 \class QChart
55 \class QChart
56 \brief QtCommercial chart API.
56 \brief QtCommercial chart API.
57
57
58 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
58 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
59 representation of different types of QChartSeries and other chart related objects like
59 representation of different types of QChartSeries and other chart related objects like
60 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
60 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
61 convenience class QChartView instead of QChart.
61 convenience class QChartView instead of QChart.
62 \sa QChartView
62 \sa QChartView
63 */
63 */
64
64
65 /*!
65 /*!
66 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
66 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
67 */
67 */
68 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
68 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
69 d_ptr(new QChartPrivate())
69 d_ptr(new QChartPrivate())
70 {
70 {
71 d_ptr->m_legend = new QLegend(this);
71 d_ptr->m_legend = new ScrolledQLegend(this);
72 d_ptr->m_dataset = new ChartDataSet(this);
72 d_ptr->m_dataset = new ChartDataSet(this);
73 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
73 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
74 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
74 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
75 //TODO:fix me setMinimumSize(d_ptr->m_padding.left() * 3, d_ptr->m_padding.top() * 3);
75 //TODO:fix me setMinimumSize(d_ptr->m_padding.left() * 3, d_ptr->m_padding.top() * 3);
76 connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
76 connect(d_ptr->m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),d_ptr->m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
77 connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
77 connect(d_ptr->m_dataset,SIGNAL(seriesRemoved(QSeries*)),d_ptr->m_legend,SLOT(handleSeriesRemoved(QSeries*)));
78 }
78 }
79
79
80 /*!
80 /*!
81 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
81 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
82 */
82 */
83 QChart::~QChart()
83 QChart::~QChart()
84 {
84 {
85 //delete first presenter , since this is a root of all the graphical items
85 //delete first presenter , since this is a root of all the graphical items
86 delete d_ptr->m_presenter;
86 delete d_ptr->m_presenter;
87 d_ptr->m_presenter=0;
87 d_ptr->m_presenter=0;
88 }
88 }
89
89
90 /*!
90 /*!
91 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
91 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
92 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
92 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
93 the y axis).
93 the y axis).
94 */
94 */
95 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
95 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
96 {
96 {
97 d_ptr->m_dataset->addSeries(series, axisY);
97 d_ptr->m_dataset->addSeries(series, axisY);
98 }
98 }
99
99
100 /*!
100 /*!
101 Removes the \a series specified in a perameter from the QChartView.
101 Removes the \a series specified in a perameter from the QChartView.
102 It releses its ownership of the specified QChartSeries object.
102 It releses its ownership of the specified QChartSeries object.
103 It does not delete the pointed QChartSeries data object
103 It does not delete the pointed QChartSeries data object
104 \sa addSeries(), removeAllSeries()
104 \sa addSeries(), removeAllSeries()
105 */
105 */
106 void QChart::removeSeries(QSeries* series)
106 void QChart::removeSeries(QSeries* series)
107 {
107 {
108 d_ptr->m_dataset->removeSeries(series);
108 d_ptr->m_dataset->removeSeries(series);
109 }
109 }
110
110
111 /*!
111 /*!
112 Removes all the QChartSeries that have been added to the QChartView
112 Removes all the QChartSeries that have been added to the QChartView
113 It also deletes the pointed QChartSeries data objects
113 It also deletes the pointed QChartSeries data objects
114 \sa addSeries(), removeSeries()
114 \sa addSeries(), removeSeries()
115 */
115 */
116 void QChart::removeAllSeries()
116 void QChart::removeAllSeries()
117 {
117 {
118 d_ptr->m_dataset->removeAllSeries();
118 d_ptr->m_dataset->removeAllSeries();
119 }
119 }
120
120
121 /*!
121 /*!
122 Sets the \a brush that is used for painting the background of the chart area.
122 Sets the \a brush that is used for painting the background of the chart area.
123 */
123 */
124 void QChart::setBackgroundBrush(const QBrush& brush)
124 void QChart::setBackgroundBrush(const QBrush& brush)
125 {
125 {
126 d_ptr->m_presenter->createChartBackgroundItem();
126 d_ptr->m_presenter->createChartBackgroundItem();
127 d_ptr->m_presenter->m_backgroundItem->setBrush(brush);
127 d_ptr->m_presenter->m_backgroundItem->setBrush(brush);
128 d_ptr->m_presenter->m_backgroundItem->update();
128 d_ptr->m_presenter->m_backgroundItem->update();
129 }
129 }
130
130
131 QBrush QChart::backgroundBrush() const
131 QBrush QChart::backgroundBrush() const
132 {
132 {
133 if (!d_ptr->m_presenter->m_backgroundItem) return QBrush();
133 if (!d_ptr->m_presenter->m_backgroundItem) return QBrush();
134 return (d_ptr->m_presenter->m_backgroundItem)->brush();
134 return (d_ptr->m_presenter->m_backgroundItem)->brush();
135 }
135 }
136
136
137 /*!
137 /*!
138 Sets the \a pen that is used for painting the background of the chart area.
138 Sets the \a pen that is used for painting the background of the chart area.
139 */
139 */
140 void QChart::setBackgroundPen(const QPen& pen)
140 void QChart::setBackgroundPen(const QPen& pen)
141 {
141 {
142 d_ptr->m_presenter->createChartBackgroundItem();
142 d_ptr->m_presenter->createChartBackgroundItem();
143 d_ptr->m_presenter->m_backgroundItem->setPen(pen);
143 d_ptr->m_presenter->m_backgroundItem->setPen(pen);
144 d_ptr->m_presenter->m_backgroundItem->update();
144 d_ptr->m_presenter->m_backgroundItem->update();
145 }
145 }
146
146
147 QPen QChart::backgroundPen() const
147 QPen QChart::backgroundPen() const
148 {
148 {
149 if (!d_ptr->m_presenter->m_backgroundItem) return QPen();
149 if (!d_ptr->m_presenter->m_backgroundItem) return QPen();
150 return d_ptr->m_presenter->m_backgroundItem->pen();
150 return d_ptr->m_presenter->m_backgroundItem->pen();
151 }
151 }
152
152
153 /*!
153 /*!
154 Sets the chart \a title. The description text that is drawn above the chart.
154 Sets the chart \a title. The description text that is drawn above the chart.
155 */
155 */
156 void QChart::setTitle(const QString& title)
156 void QChart::setTitle(const QString& title)
157 {
157 {
158 d_ptr->m_presenter->createChartTitleItem();
158 d_ptr->m_presenter->createChartTitleItem();
159 d_ptr->m_presenter->m_titleItem->setText(title);
159 d_ptr->m_presenter->m_titleItem->setText(title);
160 d_ptr->m_presenter->updateLayout();
160 d_ptr->m_presenter->updateLayout();
161 }
161 }
162
162
163 /*!
163 /*!
164 Returns the chart title. The description text that is drawn above the chart.
164 Returns the chart title. The description text that is drawn above the chart.
165 */
165 */
166 QString QChart::title() const
166 QString QChart::title() const
167 {
167 {
168 if (d_ptr->m_presenter->m_titleItem)
168 if (d_ptr->m_presenter->m_titleItem)
169 return d_ptr->m_presenter->m_titleItem->text();
169 return d_ptr->m_presenter->m_titleItem->text();
170 else
170 else
171 return QString();
171 return QString();
172 }
172 }
173
173
174 /*!
174 /*!
175 Sets the \a font that is used for rendering the description text that is rendered above the chart.
175 Sets the \a font that is used for rendering the description text that is rendered above the chart.
176 */
176 */
177 void QChart::setTitleFont(const QFont& font)
177 void QChart::setTitleFont(const QFont& font)
178 {
178 {
179 d_ptr->m_presenter->createChartTitleItem();
179 d_ptr->m_presenter->createChartTitleItem();
180 d_ptr->m_presenter->m_titleItem->setFont(font);
180 d_ptr->m_presenter->m_titleItem->setFont(font);
181 d_ptr->m_presenter->updateLayout();
181 d_ptr->m_presenter->updateLayout();
182 }
182 }
183
183
184 /*!
184 /*!
185 Sets the \a brush used for rendering the title text.
185 Sets the \a brush used for rendering the title text.
186 */
186 */
187 void QChart::setTitleBrush(const QBrush &brush)
187 void QChart::setTitleBrush(const QBrush &brush)
188 {
188 {
189 d_ptr->m_presenter->createChartTitleItem();
189 d_ptr->m_presenter->createChartTitleItem();
190 d_ptr->m_presenter->m_titleItem->setBrush(brush);
190 d_ptr->m_presenter->m_titleItem->setBrush(brush);
191 d_ptr->m_presenter->updateLayout();
191 d_ptr->m_presenter->updateLayout();
192 }
192 }
193
193
194 /*!
194 /*!
195 Returns the brush used for rendering the title text.
195 Returns the brush used for rendering the title text.
196 */
196 */
197 QBrush QChart::titleBrush() const
197 QBrush QChart::titleBrush() const
198 {
198 {
199 if (!d_ptr->m_presenter->m_titleItem) return QBrush();
199 if (!d_ptr->m_presenter->m_titleItem) return QBrush();
200 return d_ptr->m_presenter->m_titleItem->brush();
200 return d_ptr->m_presenter->m_titleItem->brush();
201 }
201 }
202
202
203 /*!
203 /*!
204 Sets the \a theme used by the chart for rendering the graphical representation of the data
204 Sets the \a theme used by the chart for rendering the graphical representation of the data
205 \sa ChartTheme, chartTheme()
205 \sa ChartTheme, chartTheme()
206 */
206 */
207 void QChart::setTheme(QChart::ChartTheme theme)
207 void QChart::setTheme(QChart::ChartTheme theme)
208 {
208 {
209 d_ptr->m_presenter->setTheme(theme);
209 d_ptr->m_presenter->setTheme(theme);
210 }
210 }
211
211
212 /*!
212 /*!
213 Returns the theme enum used by the chart.
213 Returns the theme enum used by the chart.
214 \sa ChartTheme, setChartTheme()
214 \sa ChartTheme, setChartTheme()
215 */
215 */
216 QChart::ChartTheme QChart::theme() const
216 QChart::ChartTheme QChart::theme() const
217 {
217 {
218 return d_ptr->m_presenter->theme();
218 return d_ptr->m_presenter->theme();
219 }
219 }
220
220
221 /*!
221 /*!
222 Zooms in the view by a factor of 2
222 Zooms in the view by a factor of 2
223 */
223 */
224 void QChart::zoomIn()
224 void QChart::zoomIn()
225 {
225 {
226 d_ptr->m_presenter->zoomIn();
226 d_ptr->m_presenter->zoomIn();
227 }
227 }
228
228
229 /*!
229 /*!
230 Zooms in the view to a maximum level at which \a rect is still fully visible.
230 Zooms in the view to a maximum level at which \a rect is still fully visible.
231 */
231 */
232 void QChart::zoomIn(const QRectF& rect)
232 void QChart::zoomIn(const QRectF& rect)
233 {
233 {
234 if (!rect.isValid()) return;
234 if (!rect.isValid()) return;
235 d_ptr->m_presenter->zoomIn(rect);
235 d_ptr->m_presenter->zoomIn(rect);
236 }
236 }
237
237
238 /*!
238 /*!
239 Restores the view zoom level to the previous one.
239 Restores the view zoom level to the previous one.
240 */
240 */
241 void QChart::zoomOut()
241 void QChart::zoomOut()
242 {
242 {
243 d_ptr->m_presenter->zoomOut();
243 d_ptr->m_presenter->zoomOut();
244 }
244 }
245
245
246 /*!
246 /*!
247 Returns the pointer to the x axis object of the chart
247 Returns the pointer to the x axis object of the chart
248 */
248 */
249 QChartAxis* QChart::axisX() const
249 QChartAxis* QChart::axisX() const
250 {
250 {
251 return d_ptr->m_dataset->axisX();
251 return d_ptr->m_dataset->axisX();
252 }
252 }
253
253
254 /*!
254 /*!
255 Returns the pointer to the y axis object of the chart
255 Returns the pointer to the y axis object of the chart
256 */
256 */
257 QChartAxis* QChart::axisY() const
257 QChartAxis* QChart::axisY() const
258 {
258 {
259 return d_ptr->m_dataset->axisY();
259 return d_ptr->m_dataset->axisY();
260 }
260 }
261
261
262 /*!
262 /*!
263 Returns the legend object of the chart. Ownership stays in chart.
263 Returns the legend object of the chart. Ownership stays in chart.
264 */
264 */
265 QLegend* QChart::legend() const
265 QLegend* QChart::legend() const
266 {
266 {
267 return d_ptr->m_legend;
267 return d_ptr->m_legend;
268 }
268 }
269
269
270 QRect QChart::margins() const
270 QRect QChart::margins() const
271 {
271 {
272 return d_ptr->m_presenter->margins();
272 return d_ptr->m_presenter->margins();
273 }
273 }
274
274
275
275
276 /*!
276 /*!
277 Resizes and updates the chart area using the \a event data
277 Resizes and updates the chart area using the \a event data
278 */
278 */
279 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
279 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
280 {
280 {
281 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
281 d_ptr->m_rect = QRectF(QPoint(0,0),event->newSize());
282 QGraphicsWidget::resizeEvent(event);
282 QGraphicsWidget::resizeEvent(event);
283 d_ptr->m_presenter->setGeometry(d_ptr->m_rect);
283 d_ptr->m_presenter->setGeometry(d_ptr->m_rect);
284 }
284 }
285
285
286 /*!
286 /*!
287 Sets animation \a options for the chart
287 Sets animation \a options for the chart
288 */
288 */
289 void QChart::setAnimationOptions(AnimationOptions options)
289 void QChart::setAnimationOptions(AnimationOptions options)
290 {
290 {
291 d_ptr->m_presenter->setAnimationOptions(options);
291 d_ptr->m_presenter->setAnimationOptions(options);
292 }
292 }
293
293
294 /*!
294 /*!
295 Returns animation options for the chart
295 Returns animation options for the chart
296 */
296 */
297 QChart::AnimationOptions QChart::animationOptions() const
297 QChart::AnimationOptions QChart::animationOptions() const
298 {
298 {
299 return d_ptr->m_presenter->animationOptions();
299 return d_ptr->m_presenter->animationOptions();
300 }
300 }
301
301
302 void QChart::scrollLeft()
302 void QChart::scrollLeft()
303 {
303 {
304 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
304 d_ptr->m_presenter->scroll(-d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
305 }
305 }
306
306
307 void QChart::scrollRight()
307 void QChart::scrollRight()
308 {
308 {
309 d_ptr->m_presenter->scroll(d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
309 d_ptr->m_presenter->scroll(d_ptr->m_presenter->chartGeometry().width()/(axisX()->ticksCount()-1),0);
310 }
310 }
311
311
312 void QChart::scrollUp()
312 void QChart::scrollUp()
313 {
313 {
314 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
314 d_ptr->m_presenter->scroll(0,d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
315 }
315 }
316
316
317 void QChart::scrollDown()
317 void QChart::scrollDown()
318 {
318 {
319 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
319 d_ptr->m_presenter->scroll(0,-d_ptr->m_presenter->chartGeometry().width()/(axisY()->ticksCount()-1));
320 }
320 }
321
321
322 void QChart::setBackgroundVisible(bool visible)
322 void QChart::setBackgroundVisible(bool visible)
323 {
323 {
324 d_ptr->m_presenter->createChartBackgroundItem();
324 d_ptr->m_presenter->createChartBackgroundItem();
325 d_ptr->m_presenter->m_backgroundItem->setVisible(visible);
325 d_ptr->m_presenter->m_backgroundItem->setVisible(visible);
326 }
326 }
327
327
328 bool QChart::isBackgroundVisible() const
328 bool QChart::isBackgroundVisible() const
329 {
329 {
330 if (!d_ptr->m_presenter->m_backgroundItem) return false;
330 if (!d_ptr->m_presenter->m_backgroundItem) return false;
331 return d_ptr->m_presenter->m_backgroundItem->isVisible();
331 return d_ptr->m_presenter->m_backgroundItem->isVisible();
332 }
332 }
333
333
334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
335
335
336 QChartPrivate::QChartPrivate():
336 QChartPrivate::QChartPrivate():
337 m_legend(0),
337 m_legend(0),
338 m_dataset(0),
338 m_dataset(0),
339 m_presenter(0)
339 m_presenter(0)
340 {
340 {
341
341
342 }
342 }
343
343
344 QChartPrivate::~QChartPrivate()
344 QChartPrivate::~QChartPrivate()
345 {
345 {
346
346
347 }
347 }
348
348
349 #include "moc_qchart.cpp"
349 #include "moc_qchart.cpp"
350
350
351 QTCOMMERCIALCHART_END_NAMESPACE
351 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,563 +1,546
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "qlegend.h"
21 #include "qlegend.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "qseries.h"
23 #include "qseries.h"
24 #include "legendmarker_p.h"
24 #include "legendmarker_p.h"
25 #include "qxyseries.h"
25 #include "qxyseries.h"
26 #include "qlineseries.h"
26 #include "qlineseries.h"
27 #include "qareaseries.h"
27 #include "qareaseries.h"
28 #include "qscatterseries.h"
28 #include "qscatterseries.h"
29 #include "qsplineseries.h"
29 #include "qsplineseries.h"
30 #include "qbarseries.h"
30 #include "qbarseries.h"
31 #include "qstackedbarseries.h"
31 #include "qstackedbarseries.h"
32 #include "qpercentbarseries.h"
32 #include "qpercentbarseries.h"
33 #include "qbarset.h"
33 #include "qbarset.h"
34 #include "qpieseries.h"
34 #include "qpieseries.h"
35 #include "qpieslice.h"
35 #include "qpieslice.h"
36 #include "chartpresenter_p.h"
36 #include "chartpresenter_p.h"
37 #include "scroller_p.h"
37 #include "scroller_p.h"
38 #include <QPainter>
38 #include <QPainter>
39 #include <QPen>
39 #include <QPen>
40 #include <QTimer>
40 #include <QTimer>
41
41
42 #include <QGraphicsSceneEvent>
42 #include <QGraphicsSceneEvent>
43
43
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
45
45
46 /*!
46 /*!
47 \class QLegend
47 \class QLegend
48 \brief part of QtCommercial chart API.
48 \brief part of QtCommercial chart API.
49
49
50 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
50 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
51 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
51 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
52 handle the drawing manually.
52 handle the drawing manually.
53 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
53 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
54
54
55 \mainclass
55 \mainclass
56
56
57 \sa QChart, QSeries
57 \sa QChart, QSeries
58 */
58 */
59
59
60 /*!
60 /*!
61 \enum QLegend::Layout
61 \enum QLegend::Layout
62
62
63 This enum describes the possible position for legend inside chart.
63 This enum describes the possible position for legend inside chart.
64
64
65 \value LayoutTop
65 \value LayoutTop
66 \value LayoutBottom
66 \value LayoutBottom
67 \value LayoutLeft
67 \value LayoutLeft
68 \value LayoutRight
68 \value LayoutRight
69 */
69 */
70
70
71
71
72 /*!
72 /*!
73 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
73 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
74 \brief Notifies when series has been clicked on legend \a series \a button
74 \brief Notifies when series has been clicked on legend \a series \a button
75 */
75 */
76
76
77 /*!
77 /*!
78 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
78 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
79 \brief Notifies when barset has been clicked on legend \a barset \a button
79 \brief Notifies when barset has been clicked on legend \a barset \a button
80 */
80 */
81
81
82 /*!
82 /*!
83 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
83 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
84 \brief Notifies when pie slice has been clicked on legend \a slice \a button
84 \brief Notifies when pie slice has been clicked on legend \a slice \a button
85 */
85 */
86
86
87 /*!
87 /*!
88 Constructs the legend object and sets the parent to \a parent
88 Constructs the legend object and sets the parent to \a parent
89 */
89 */
90
90
91 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
91 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
92 m_margin(5),
92 m_margin(5),
93 m_offsetX(0),
93 m_offsetX(0),
94 m_offsetY(0),
94 m_offsetY(0),
95 m_brush(Qt::darkGray), // TODO: default should come from theme
95 m_brush(Qt::darkGray), // TODO: default should come from theme
96 m_alignment(QLegend::AlignmentTop),
96 m_alignment(QLegend::AlignmentTop),
97 m_markers(new QGraphicsItemGroup(this)),
97 m_markers(new QGraphicsItemGroup(this)),
98 m_attachedToChart(true),
98 m_attachedToChart(true),
99 m_chart(chart),
99 m_chart(chart),
100 m_minWidth(0),
100 m_minWidth(0),
101 m_minHeight(0),
101 m_minHeight(0),
102 m_width(0),
102 m_width(0),
103 m_height(0),
103 m_height(0),
104 m_visible(false),
104 m_visible(false),
105 m_dirty(false),
105 m_dirty(false)
106 m_scroller(new Scroller(this))
107 {
106 {
108 setZValue(ChartPresenter::LegendZValue);
107 setZValue(ChartPresenter::LegendZValue);
109 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
108 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
110 }
109 }
111
110
112 /*!
111 /*!
113 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
112 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
114 */
113 */
115
114
116 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
115 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
117 {
116 {
118 Q_UNUSED(option)
117 Q_UNUSED(option)
119 Q_UNUSED(widget)
118 Q_UNUSED(widget)
120 if(!m_visible) return;
119 if(!m_visible) return;
121
120
122 painter->setOpacity(opacity());
121 painter->setOpacity(opacity());
123 painter->setPen(m_pen);
122 painter->setPen(m_pen);
124 painter->setBrush(m_brush);
123 painter->setBrush(m_brush);
125 painter->drawRect(boundingRect());
124 painter->drawRect(boundingRect());
126 }
125 }
127
126
128 /*!
127 /*!
129 Bounding rect of legend.
128 Bounding rect of legend.
130 */
129 */
131
130
132 QRectF QLegend::boundingRect() const
131 QRectF QLegend::boundingRect() const
133 {
132 {
134 return m_rect;
133 return m_rect;
135 }
134 }
136
135
137 /*!
136 /*!
138 Sets the \a brush of legend. Brush affects the background of legend.
137 Sets the \a brush of legend. Brush affects the background of legend.
139 */
138 */
140 void QLegend::setBrush(const QBrush &brush)
139 void QLegend::setBrush(const QBrush &brush)
141 {
140 {
142 if (m_brush != brush) {
141 if (m_brush != brush) {
143 m_brush = brush;
142 m_brush = brush;
144 update();
143 update();
145 }
144 }
146 }
145 }
147
146
148 /*!
147 /*!
149 Returns the brush used by legend.
148 Returns the brush used by legend.
150 */
149 */
151 QBrush QLegend::brush() const
150 QBrush QLegend::brush() const
152 {
151 {
153 return m_brush;
152 return m_brush;
154 }
153 }
155
154
156 /*!
155 /*!
157 Sets the \a pen of legend. Pen affects the legend borders.
156 Sets the \a pen of legend. Pen affects the legend borders.
158 */
157 */
159 void QLegend::setPen(const QPen &pen)
158 void QLegend::setPen(const QPen &pen)
160 {
159 {
161 if (m_pen != pen) {
160 if (m_pen != pen) {
162 m_pen = pen;
161 m_pen = pen;
163 update();
162 update();
164 }
163 }
165 }
164 }
166
165
167 /*!
166 /*!
168 Returns the pen used by legend
167 Returns the pen used by legend
169 */
168 */
170
169
171 QPen QLegend::pen() const
170 QPen QLegend::pen() const
172 {
171 {
173 return m_pen;
172 return m_pen;
174 }
173 }
175
174
176 /*!
175 /*!
177 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
176 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
178 \sa QLegend::Layout
177 \sa QLegend::Layout
179 */
178 */
180 void QLegend::setAlignmnent(QLegend::Alignments alignment)
179 void QLegend::setAlignmnent(QLegend::Alignments alignment)
181 {
180 {
182 if(m_alignment!=alignment && m_attachedToChart) {
181 if(m_alignment!=alignment && m_attachedToChart) {
183 m_alignment = alignment;
182 m_alignment = alignment;
184 updateLayout();
183 updateLayout();
185 }
184 }
186 }
185 }
187
186
188 /*!
187 /*!
189 Returns the preferred layout for legend
188 Returns the preferred layout for legend
190 */
189 */
191 QLegend::Alignments QLegend::alignment() const
190 QLegend::Alignments QLegend::alignment() const
192 {
191 {
193 return m_alignment;
192 return m_alignment;
194 }
193 }
195
194
196 /*!
195 /*!
197 \internal \a series \a domain Should be called when series is added to chart.
196 \internal \a series \a domain Should be called when series is added to chart.
198 */
197 */
199 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
198 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
200 {
199 {
201 Q_UNUSED(domain)
200 Q_UNUSED(domain)
202
201
203 switch (series->type())
202 switch (series->type())
204 {
203 {
205 case QSeries::SeriesTypeLine: {
204 case QSeries::SeriesTypeLine: {
206 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
205 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
207 appendMarkers(lineSeries);
206 appendMarkers(lineSeries);
208 break;
207 break;
209 }
208 }
210 case QSeries::SeriesTypeArea: {
209 case QSeries::SeriesTypeArea: {
211 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
210 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
212 appendMarkers(areaSeries);
211 appendMarkers(areaSeries);
213 break;
212 break;
214 }
213 }
215 case QSeries::SeriesTypeBar: {
214 case QSeries::SeriesTypeBar: {
216 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
215 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
217 appendMarkers(barSeries);
216 appendMarkers(barSeries);
218 break;
217 break;
219 }
218 }
220 case QSeries::SeriesTypeStackedBar: {
219 case QSeries::SeriesTypeStackedBar: {
221 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
220 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
222 appendMarkers(stackedBarSeries);
221 appendMarkers(stackedBarSeries);
223 break;
222 break;
224 }
223 }
225 case QSeries::SeriesTypePercentBar: {
224 case QSeries::SeriesTypePercentBar: {
226 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
225 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
227 appendMarkers(percentBarSeries);
226 appendMarkers(percentBarSeries);
228 break;
227 break;
229 }
228 }
230 case QSeries::SeriesTypeScatter: {
229 case QSeries::SeriesTypeScatter: {
231 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
230 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
232 appendMarkers(scatterSeries);
231 appendMarkers(scatterSeries);
233 break;
232 break;
234 }
233 }
235 case QSeries::SeriesTypePie: {
234 case QSeries::SeriesTypePie: {
236 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
235 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
237 appendMarkers(pieSeries);
236 appendMarkers(pieSeries);
238 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
237 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
239 break;
238 break;
240 }
239 }
241 case QSeries::SeriesTypeSpline: {
240 case QSeries::SeriesTypeSpline: {
242 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
241 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
243 appendMarkers(splineSeries);
242 appendMarkers(splineSeries);
244 break;
243 break;
245 }
244 }
246 default: {
245 default: {
247 qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type.";
246 qWarning()<< "QLegend::handleSeriesAdded" << series->type() << "unknown series type.";
248 break;
247 break;
249 }
248 }
250 }
249 }
251
250
252 // wait for all series added
251 // wait for all series added
253 if(!m_dirty){
252 if(!m_dirty){
254 QTimer::singleShot(0,this,SLOT(updateLayout()));
253 QTimer::singleShot(0,this,SLOT(updateLayout()));
255 m_dirty=true;
254 m_dirty=true;
256 }
255 }
257 }
256 }
258
257
259 /*!
258 /*!
260 \internal \a series Should be called when series is removed from chart.
259 \internal \a series Should be called when series is removed from chart.
261 */
260 */
262 void QLegend::handleSeriesRemoved(QSeries *series)
261 void QLegend::handleSeriesRemoved(QSeries *series)
263 {
262 {
264 switch (series->type())
263 switch (series->type())
265 {
264 {
266 case QSeries::SeriesTypeArea: {
265 case QSeries::SeriesTypeArea: {
267 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
266 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
268 deleteMarkers(areaSeries);
267 deleteMarkers(areaSeries);
269 break;
268 break;
270 }
269 }
271 case QSeries::SeriesTypePie: {
270 case QSeries::SeriesTypePie: {
272 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
271 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
273 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
272 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
274 deleteMarkers(series);
273 deleteMarkers(series);
275 break;
274 break;
276 }
275 }
277 default: {
276 default: {
278 // All other types
277 // All other types
279 deleteMarkers(series);
278 deleteMarkers(series);
280 break;
279 break;
281 }
280 }
282 }
281 }
283
282
284 updateLayout();
283 updateLayout();
285 }
284 }
286
285
287 /*!
286 /*!
288 \internal \a slices Should be called when slices are added to pie chart.
287 \internal \a slices Should be called when slices are added to pie chart.
289 */
288 */
290 void QLegend::handleAdded(QList<QPieSlice *> slices)
289 void QLegend::handleAdded(QList<QPieSlice *> slices)
291 {
290 {
292 QPieSeries* series = static_cast<QPieSeries *> (sender());
291 QPieSeries* series = static_cast<QPieSeries *> (sender());
293 foreach(QPieSlice* slice, slices) {
292 foreach(QPieSlice* slice, slices) {
294 PieLegendMarker* marker = new PieLegendMarker(series,slice, this);
293 PieLegendMarker* marker = new PieLegendMarker(series,slice, this);
295 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
294 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
296 m_markers->addToGroup(marker);
295 m_markers->addToGroup(marker);
297 }
296 }
298 updateLayout();
297 updateLayout();
299 }
298 }
300
299
301 /*!
300 /*!
302 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
301 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
303 because removed slices are also deleted and we listen destroyed signal
302 because removed slices are also deleted and we listen destroyed signal
304 */
303 */
305 void QLegend::handleRemoved(QList<QPieSlice *> slices)
304 void QLegend::handleRemoved(QList<QPieSlice *> slices)
306 {
305 {
307 Q_UNUSED(slices)
306 Q_UNUSED(slices)
308 }
307 }
309
308
310
309
311 /*!
310 /*!
312 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
311 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
313 */
312 */
314 void QLegend::handleMarkerDestroyed()
313 void QLegend::handleMarkerDestroyed()
315 {
314 {
316 LegendMarker* m = static_cast<LegendMarker *> (sender());
315 LegendMarker* m = static_cast<LegendMarker *> (sender());
317 delete m;
316 delete m;
318 // updateLayout();
317 // updateLayout();
319 }
318 }
320
319
321 /*!
320 /*!
322 Detaches the legend from chart. Chart won't change layout of the legend.
321 Detaches the legend from chart. Chart won't change layout of the legend.
323 */
322 */
324 void QLegend::detachFromChart()
323 void QLegend::detachFromChart()
325 {
324 {
326 m_attachedToChart = false;
325 m_attachedToChart = false;
327 }
326 }
328
327
329 /*!
328 /*!
330 Attaches the legend to chart. Chart may change layout of the legend.
329 Attaches the legend to chart. Chart may change layout of the legend.
331 */
330 */
332 void QLegend::attachToChart()
331 void QLegend::attachToChart()
333 {
332 {
334 m_attachedToChart = true;
333 m_attachedToChart = true;
335 }
334 }
336
335
337 /*!
336 /*!
338 Returns true, if legend is attached to chart.
337 Returns true, if legend is attached to chart.
339 */
338 */
340 bool QLegend::isAttachedToChart()
339 bool QLegend::isAttachedToChart()
341 {
340 {
342 return m_attachedToChart;
341 return m_attachedToChart;
343 }
342 }
344
343
345 /*!
344 /*!
346 \internal Helper function. Appends markers from \a series to legend.
345 \internal Helper function. Appends markers from \a series to legend.
347 */
346 */
348 void QLegend::appendMarkers(QAreaSeries* series)
347 void QLegend::appendMarkers(QAreaSeries* series)
349 {
348 {
350 AreaLegendMarker* marker = new AreaLegendMarker(series,this);
349 AreaLegendMarker* marker = new AreaLegendMarker(series,this);
351 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
350 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
352 m_markers->addToGroup(marker);
351 m_markers->addToGroup(marker);
353 }
352 }
354
353
355 /*!
354 /*!
356 \internal Helper function. Appends markers from \a series to legend.
355 \internal Helper function. Appends markers from \a series to legend.
357 */
356 */
358 void QLegend::appendMarkers(QXYSeries* series)
357 void QLegend::appendMarkers(QXYSeries* series)
359 {
358 {
360 XYLegendMarker* marker = new XYLegendMarker(series,this);
359 XYLegendMarker* marker = new XYLegendMarker(series,this);
361 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
360 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
362 m_markers->addToGroup(marker);
361 m_markers->addToGroup(marker);
363 }
362 }
364
363
365 /*!
364 /*!
366 \internal Helper function. Appends markers from \a series to legend.
365 \internal Helper function. Appends markers from \a series to legend.
367 */
366 */
368 void QLegend::appendMarkers(QBarSeries *series)
367 void QLegend::appendMarkers(QBarSeries *series)
369 {
368 {
370 foreach(QBarSet* set, series->barSets()) {
369 foreach(QBarSet* set, series->barSets()) {
371 BarLegendMarker* marker = new BarLegendMarker(series,set, this);
370 BarLegendMarker* marker = new BarLegendMarker(series,set, this);
372 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
371 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
373 m_markers->addToGroup(marker);
372 m_markers->addToGroup(marker);
374 }
373 }
375 }
374 }
376
375
377 /*!
376 /*!
378 \internal Helper function. Appends markers from \a series to legend.
377 \internal Helper function. Appends markers from \a series to legend.
379 */
378 */
380 void QLegend::appendMarkers(QPieSeries *series)
379 void QLegend::appendMarkers(QPieSeries *series)
381 {
380 {
382 foreach(QPieSlice* slice, series->slices()) {
381 foreach(QPieSlice* slice, series->slices()) {
383 PieLegendMarker* marker = new PieLegendMarker(series,slice, this);
382 PieLegendMarker* marker = new PieLegendMarker(series,slice, this);
384 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
383 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
385 m_markers->addToGroup(marker);
384 m_markers->addToGroup(marker);
386 }
385 }
387 }
386 }
388
387
389 /*!
388 /*!
390 \internal Deletes all markers that are created from \a series
389 \internal Deletes all markers that are created from \a series
391 */
390 */
392 void QLegend::deleteMarkers(QSeries *series)
391 void QLegend::deleteMarkers(QSeries *series)
393 {
392 {
394 // Search all markers that belong to given series and delete them.
393 // Search all markers that belong to given series and delete them.
395
394
396 QList<QGraphicsItem *> items = m_markers->childItems();
395 QList<QGraphicsItem *> items = m_markers->childItems();
397
396
398 foreach (QGraphicsItem *m, items) {
397 foreach (QGraphicsItem *m, items) {
399 LegendMarker *marker = static_cast<LegendMarker*>(m);
398 LegendMarker *marker = static_cast<LegendMarker*>(m);
400 if (marker->series() == series) {
399 if (marker->series() == series) {
401 delete marker;
400 delete marker;
402 }
401 }
403 }
402 }
404 }
403 }
405
404
406 /*!
405 /*!
407 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
406 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
408 If items don't fit, sets the visibility of scroll buttons accordingly.
407 If items don't fit, sets the visibility of scroll buttons accordingly.
409 Causes legend to be resized.
408 Causes legend to be resized.
410 */
409 */
411
410
412 void QLegend::setOffset(const QPointF& point)
411 void QLegend::setOffset(const QPointF& point)
413 {
412 {
414
413
415 switch(m_alignment) {
414 switch(m_alignment) {
416
415
417 case AlignmentTop:
416 case AlignmentTop:
418 case AlignmentBottom: {
417 case AlignmentBottom: {
419 if(m_width<=m_rect.width()) return;
418 if(m_width<=m_rect.width()) return;
420
419
421 if (point.x() != m_offsetX) {
420 if (point.x() != m_offsetX) {
422 m_offsetX = qBound(0.0, point.x(), m_width - m_rect.width());
421 m_offsetX = qBound(0.0, point.x(), m_width - m_rect.width());
423 m_markers->setPos(-m_offsetX,m_rect.top());
422 m_markers->setPos(-m_offsetX,m_rect.top());
424 }
423 }
425 break;
424 break;
426 }
425 }
427 case AlignmentLeft:
426 case AlignmentLeft:
428 case AlignmentRight: {
427 case AlignmentRight: {
429
428
430 if(m_height<=m_rect.height()) return;
429 if(m_height<=m_rect.height()) return;
431
430
432 if (point.y() != m_offsetY) {
431 if (point.y() != m_offsetY) {
433 m_offsetY = qBound(0.0, point.y(), m_height - m_rect.height());
432 m_offsetY = qBound(0.0, point.y(), m_height - m_rect.height());
434 m_markers->setPos(m_rect.left(),-m_offsetY);
433 m_markers->setPos(m_rect.left(),-m_offsetY);
435 }
434 }
436 break;
435 break;
437 }
436 }
438 }
437 }
439 }
438 }
440
439
441 QPointF QLegend::offset() const
440 QPointF QLegend::offset() const
442 {
441 {
443 return QPointF(m_offsetX,m_offsetY);
442 return QPointF(m_offsetX,m_offsetY);
444 }
443 }
445
444
446 // this function runs first to set min max values
445 // this function runs first to set min max values
447 void QLegend::updateLayout()
446 void QLegend::updateLayout()
448 {
447 {
449 m_dirty=false;
448 m_dirty=false;
450 m_offsetX=0;
449 m_offsetX=0;
451 QList<QGraphicsItem *> items = m_markers->childItems();
450 QList<QGraphicsItem *> items = m_markers->childItems();
452
451
453 if(items.isEmpty()) return;
452 if(items.isEmpty()) return;
454
453
455 m_minWidth=0;
454 m_minWidth=0;
456 m_minHeight=0;
455 m_minHeight=0;
457
456
458 switch(m_alignment) {
457 switch(m_alignment) {
459
458
460 case AlignmentTop:
459 case AlignmentTop:
461 case AlignmentBottom: {
460 case AlignmentBottom: {
462 QPointF point = m_rect.topLeft();
461 QPointF point = m_rect.topLeft();
463 m_width = 0;
462 m_width = 0;
464 foreach (QGraphicsItem *item, items) {
463 foreach (QGraphicsItem *item, items) {
465 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
464 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
466 const QRectF& rect = item->boundingRect();
465 const QRectF& rect = item->boundingRect();
467 qreal w = rect.width();
466 qreal w = rect.width();
468 m_minWidth=qMax(m_minWidth,w);
467 m_minWidth=qMax(m_minWidth,w);
469 m_minHeight=qMax(m_minHeight,rect.height());
468 m_minHeight=qMax(m_minHeight,rect.height());
470 m_width+=w;
469 m_width+=w;
471 point.setX(point.x() + w);
470 point.setX(point.x() + w);
472 }
471 }
473 if(m_width<m_rect.width()){
472 if(m_width<m_rect.width()){
474 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
473 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
475 }else{
474 }else{
476 m_markers->setPos(m_rect.topLeft());
475 m_markers->setPos(m_rect.topLeft());
477 }
476 }
478 m_height=m_minHeight;
477 m_height=m_minHeight;
479 }
478 }
480 break;
479 break;
481 case AlignmentLeft:
480 case AlignmentLeft:
482 case AlignmentRight:{
481 case AlignmentRight:{
483 QPointF point = m_rect.topLeft();
482 QPointF point = m_rect.topLeft();
484 m_height = 0;
483 m_height = 0;
485 foreach (QGraphicsItem *item, items) {
484 foreach (QGraphicsItem *item, items) {
486 item->setPos(point);
485 item->setPos(point);
487 const QRectF& rect = item->boundingRect();
486 const QRectF& rect = item->boundingRect();
488 qreal h = rect.height();
487 qreal h = rect.height();
489 m_minWidth=qMax(m_minWidth,rect.width());
488 m_minWidth=qMax(m_minWidth,rect.width());
490 m_minHeight=qMax(m_minHeight,h);
489 m_minHeight=qMax(m_minHeight,h);
491 m_height+=h;
490 m_height+=h;
492 point.setY(point.y() + h);
491 point.setY(point.y() + h);
493 }
492 }
494 if(m_height<m_rect.height()){
493 if(m_height<m_rect.height()){
495 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
494 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
496 }else{
495 }else{
497 m_markers->setPos(m_rect.topLeft());
496 m_markers->setPos(m_rect.topLeft());
498 }
497 }
499 m_width=m_minWidth;
498 m_width=m_minWidth;
500 }
499 }
501 break;
500 break;
502 }
501 }
503
502
504 m_chart->d_ptr->m_presenter->updateLayout(); //TODO fixme;
503 m_chart->d_ptr->m_presenter->updateLayout(); //TODO fixme;
505 }
504 }
506
505
507 void QLegend::setBackgroundVisible(bool visible)
506 void QLegend::setBackgroundVisible(bool visible)
508 {
507 {
509 if(m_visible!=visible)
508 if(m_visible!=visible)
510 {
509 {
511 m_visible=visible;
510 m_visible=visible;
512 update();
511 update();
513 }
512 }
514 }
513 }
515
514
516 bool QLegend::isBackgroundVisible() const
515 bool QLegend::isBackgroundVisible() const
517 {
516 {
518 return m_visible;
517 return m_visible;
519 }
518 }
520
519
521 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
520 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
522 {
521 {
523 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
522 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
524 QGraphicsWidget::resizeEvent(event);
523 QGraphicsWidget::resizeEvent(event);
525 if(m_rect != rect){
524 if(m_rect != rect){
526 m_rect = rect;
525 m_rect = rect;
527 updateLayout();
526 updateLayout();
528 }
527 }
529 }
528 }
530
529
531 void QLegend::hideEvent(QHideEvent *event)
530 void QLegend::hideEvent(QHideEvent *event)
532 {
531 {
533 QGraphicsWidget::hideEvent(event);
532 QGraphicsWidget::hideEvent(event);
534 setEnabled(false);
533 setEnabled(false);
535 updateLayout();
534 updateLayout();
536 }
535 }
537
536
538 void QLegend::showEvent(QShowEvent *event)
537 void QLegend::showEvent(QShowEvent *event)
539 {
538 {
540 QGraphicsWidget::showEvent(event);
539 QGraphicsWidget::showEvent(event);
541 setEnabled(true);
540 setEnabled(true);
542 updateLayout();
541 updateLayout();
543 }
542 }
544
543
545 void QLegend::mousePressEvent(QGraphicsSceneMouseEvent* event)
546 {
547 //Q_UNUSED(event);
548 m_scroller->mousePressEvent(event);
549 }
550 void QLegend::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
551 {
552 //Q_UNUSED(event);
553 m_scroller->mouseMoveEvent(event);
554 }
555 void QLegend::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
556 {
557 //Q_UNUSED(event);
558 m_scroller->mouseReleaseEvent(event);
559 }
560
561 #include "moc_qlegend.cpp"
544 #include "moc_qlegend.cpp"
562
545
563 QTCOMMERCIALCHART_END_NAMESPACE
546 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,152 +1,179
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 #ifndef QLEGEND_H
21 #ifndef QLEGEND_H
22 #define QLEGEND_H
22 #define QLEGEND_H
23
23
24 #include <QChartGlobal>
24 #include <QChartGlobal>
25 #include <QGraphicsWidget>
25 #include <QGraphicsWidget>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28 #include "scroller_p.h"
28
29
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
31
31 class Domain;
32 class Domain;
32 class LegendMarker;
33 class LegendMarker;
33 class QPieSlice;
34 class QPieSlice;
34 class QXYSeries;
35 class QXYSeries;
35 class QBarSet;
36 class QBarSet;
36 class QBarSeries;
37 class QBarSeries;
37 class QPieSeries;
38 class QPieSeries;
38 class QAreaSeries;
39 class QAreaSeries;
39 class LegendScrollButton;
40 class LegendScrollButton;
40 class QSeries;
41 class QSeries;
41 class QChart;
42 class QChart;
42 class Scroller;
43
43
44 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
44 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsWidget
45 {
45 {
46 Q_OBJECT
46 Q_OBJECT
47 public:
47 public:
48
48
49 // We only support these alignments (for now)
49 // We only support these alignments (for now)
50 enum Alignment {
50 enum Alignment {
51 AlignmentTop = Qt::AlignTop,
51 AlignmentTop = Qt::AlignTop,
52 AlignmentBottom = Qt::AlignBottom,
52 AlignmentBottom = Qt::AlignBottom,
53 AlignmentLeft = Qt::AlignLeft,
53 AlignmentLeft = Qt::AlignLeft,
54 AlignmentRight = Qt::AlignRight
54 AlignmentRight = Qt::AlignRight
55 };
55 };
56
56
57 Q_DECLARE_FLAGS(Alignments, Alignment)
57 Q_DECLARE_FLAGS(Alignments, Alignment)
58
58
59 private:
59 private:
60 explicit QLegend(QChart *chart);
60 explicit QLegend(QChart *chart);
61
61
62 public:
62 public:
63 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
63 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
64 QRectF boundingRect() const;
64 QRectF boundingRect() const;
65
65
66 void setBrush(const QBrush &brush);
66 void setBrush(const QBrush &brush);
67 QBrush brush() const;
67 QBrush brush() const;
68
68
69 void setPen(const QPen &pen);
69 void setPen(const QPen &pen);
70 QPen pen() const;
70 QPen pen() const;
71
71
72 void setAlignmnent(QLegend::Alignments alignment);
72 void setAlignmnent(QLegend::Alignments alignment);
73 QLegend::Alignments alignment() const;
73 QLegend::Alignments alignment() const;
74
74
75
75
76 void detachFromChart();
76 void detachFromChart();
77 void attachToChart();
77 void attachToChart();
78 bool isAttachedToChart();
78 bool isAttachedToChart();
79
79
80 qreal minWidht() const { return m_minWidth;}
80 qreal minWidht() const { return m_minWidth;}
81 qreal minHeight() const { return m_minHeight;}
81 qreal minHeight() const { return m_minHeight;}
82
82
83 void setBackgroundVisible(bool visible);
83 void setBackgroundVisible(bool visible);
84 bool isBackgroundVisible() const;
84 bool isBackgroundVisible() const;
85
85
86 void setOffset(const QPointF& point);
86 void setOffset(const QPointF& point);
87 QPointF offset() const;
87 QPointF offset() const;
88
88
89 protected:
89 protected:
90 void resizeEvent(QGraphicsSceneResizeEvent *event);
90 void resizeEvent(QGraphicsSceneResizeEvent *event);
91 void hideEvent(QHideEvent *event);
91 void hideEvent(QHideEvent *event);
92 void showEvent(QShowEvent *event);
92 void showEvent(QShowEvent *event);
93 void mousePressEvent(QGraphicsSceneMouseEvent* event);
94 void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
95 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
96
93
97 public Q_SLOTS:
94 public Q_SLOTS:
98 // PIMPL --->
95 // PIMPL --->
99 void handleSeriesAdded(QSeries *series, Domain *domain);
96 void handleSeriesAdded(QSeries *series, Domain *domain);
100 void handleSeriesRemoved(QSeries *series);
97 void handleSeriesRemoved(QSeries *series);
101 void handleAdded(QList<QPieSlice *> slices);
98 void handleAdded(QList<QPieSlice *> slices);
102 void handleRemoved(QList<QPieSlice *> slices);
99 void handleRemoved(QList<QPieSlice *> slices);
103 void handleMarkerDestroyed();
100 void handleMarkerDestroyed();
104
101
105 // PIMPL <---
102 // PIMPL <---
106
103
107 private:
104 private:
108 // PIMPL --->
105 // PIMPL --->
109 void appendMarkers(QAreaSeries *series);
106 void appendMarkers(QAreaSeries *series);
110 void appendMarkers(QXYSeries *series);
107 void appendMarkers(QXYSeries *series);
111 void appendMarkers(QBarSeries *series);
108 void appendMarkers(QBarSeries *series);
112 void appendMarkers(QPieSeries *series);
109 void appendMarkers(QPieSeries *series);
113 void deleteMarkers(QSeries *series);
110 void deleteMarkers(QSeries *series);
114
111
115
112
116
113
117
114
118 private Q_SLOTS:
115 private Q_SLOTS:
119 void updateLayout();
116 void updateLayout();
120
117
121 private:
118 private:
122 qreal m_margin;
119 qreal m_margin;
123
120
124 QRectF m_rect;
121 QRectF m_rect;
125 qreal m_offsetX;
122 qreal m_offsetX;
126 qreal m_offsetY;
123 qreal m_offsetY;
127
124
128 //QList<LegendMarker *> m_markers;
125 //QList<LegendMarker *> m_markers;
129
126
130 QBrush m_brush;
127 QBrush m_brush;
131 QPen m_pen;
128 QPen m_pen;
132 QLegend::Alignments m_alignment;
129 QLegend::Alignments m_alignment;
133 QGraphicsItemGroup* m_markers;
130 QGraphicsItemGroup* m_markers;
134
131
135
132
136 bool m_attachedToChart;
133 bool m_attachedToChart;
137
134
138 QChart *m_chart;
135 QChart *m_chart;
139 qreal m_minWidth;
136 qreal m_minWidth;
140 qreal m_minHeight;
137 qreal m_minHeight;
141 qreal m_width;
138 qreal m_width;
142 qreal m_height;
139 qreal m_height;
143 bool m_visible;
140 bool m_visible;
144 bool m_dirty;
141 bool m_dirty;
145 Scroller* m_scroller;
142 friend class ScrolledQLegend;
146 friend class QChart;
147 // <--- PIMPL
143 // <--- PIMPL
148 };
144 };
149
145
146 class ScrolledQLegend: public QLegend, public Scroller
147 {
148
149 public:
150 ScrolledQLegend(QChart *chart):QLegend(chart)
151 {
152 }
153
154 void setOffset(const QPointF& point)
155 {
156 QLegend::setOffset(point);
157 }
158 QPointF offset() const
159 {
160 return QLegend::offset();
161 }
162
163 void mousePressEvent(QGraphicsSceneMouseEvent* event){
164 Scroller::mousePressEvent(event);
165 //QLegend::mousePressEvent(event);
166 }
167 void mouseMoveEvent(QGraphicsSceneMouseEvent* event){
168 Scroller::mouseMoveEvent(event);
169 //QLegend::mouseMoveEvent(event);
170 }
171 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event){
172 Scroller::mouseReleaseEvent(event);
173 //QLegend::mouseReleaseEvent(event);
174 }
175 };
176
150 QTCOMMERCIALCHART_END_NAMESPACE
177 QTCOMMERCIALCHART_END_NAMESPACE
151
178
152 #endif // QLEGEND_H
179 #endif // QLEGEND_H
@@ -1,259 +1,248
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "scroller_p.h"
21 #include "scroller_p.h"
22 #include "qlegend.h"
22 #include "qlegend.h"
23 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsSceneMouseEvent>
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 Scroller::Scroller(QLegend* legend):
27 Scroller::Scroller():
28 m_ticker(this),
28 m_ticker(this),
29 m_state(Idle),
29 m_state(Idle),
30 m_moveThreshold(10),
30 m_moveThreshold(10),
31 m_timeTreshold(50),
31 m_timeTreshold(50)
32 m_legend(legend)
33 {
32 {
34
33
35 }
34 }
36
35
37 Scroller::~Scroller()
36 Scroller::~Scroller()
38 {
37 {
39 }
38 }
40
39
41 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
40 void Scroller::mousePressEvent(QGraphicsSceneMouseEvent* event)
42 {
41 {
43 if (event->button() == Qt::LeftButton) {
42 if (event->button() == Qt::LeftButton) {
44
43
45 switch (m_state) {
44 switch (m_state) {
46 case Idle:
45 case Idle:
47 {
46 {
48 m_state = Pressed;
47 m_state = Pressed;
49 m_offset = offset();
48 m_offset = offset();
50 m_press = event->pos();
49 m_press = event->pos();
51 m_timeStamp = QTime::currentTime();
50 m_timeStamp = QTime::currentTime();
52 event->accept();
51 event->accept();
53 break;
52 break;
54 }
53 }
55 case Scroll:
54 case Scroll:
56 {
55 {
57 m_state = Stop;
56 m_state = Stop;
58 m_speed = QPoint(0, 0);
57 m_speed = QPoint(0, 0);
59 m_offset = offset();
58 m_offset = offset();
60 m_press = event->pos();
59 m_press = event->pos();
61 event->accept();
60 event->accept();
62 break;
61 break;
63 }
62 }
64 case Pressed:
63 case Pressed:
65 case Move:
64 case Move:
66 case Stop:
65 case Stop:
67 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
66 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
68 event->ignore();
67 event->ignore();
69 break;
68 break;
70 }
69 }
71 }
70 }
72 }
71 }
73
72
74 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
73 void Scroller::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
75 {
74 {
76 QPointF delta = event->pos() - m_press;
75 QPointF delta = event->pos() - m_press;
77
76
78 switch (m_state) {
77 switch (m_state) {
79 case Pressed:
78 case Pressed:
80 case Stop:
79 case Stop:
81 {
80 {
82 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
81 if (qAbs(delta.x()) > m_moveThreshold || qAbs(delta.y()) > m_moveThreshold) {
83 m_state = Move;
82 m_state = Move;
84 m_timeStamp = QTime::currentTime();
83 m_timeStamp = QTime::currentTime();
85 m_distance = QPointF(0, 0);
84 m_distance = QPointF(0, 0);
86 m_press = event->pos();
85 m_press = event->pos();
87 event->accept();
86 event->accept();
88 break;
87 break;
89 }
88 }
90 else {
89 else {
91 event->ignore();
90 event->ignore();
92 break;
91 break;
93 }
92 }
94 }
93 }
95 case Move:
94 case Move:
96 {
95 {
97 setOffset(m_offset - delta);
96 setOffset(m_offset - delta);
98 calculateSpeed(event->pos());
97 calculateSpeed(event->pos());
99 event->accept();
98 event->accept();
100 break;
99 break;
101 }
100 }
102 case Idle:
101 case Idle:
103 case Scroll:
102 case Scroll:
104 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
103 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
105 event->ignore();
104 event->ignore();
106 break;
105 break;
107 }
106 }
108
107
109 }
108 }
110
109
111 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
110 void Scroller::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
112 {
111 {
113 if (event->button() == Qt::LeftButton) {
112 if (event->button() == Qt::LeftButton) {
114
113
115 switch (m_state) {
114 switch (m_state) {
116
115
117 case Scroll:
116 case Scroll:
118 m_state = Stop;
117 m_state = Stop;
119 m_speed = QPointF(0, 0);
118 m_speed = QPointF(0, 0);
120 m_offset = offset();
119 m_offset = offset();
121 event->accept();
120 event->accept();
122 break;
121 break;
123 case Pressed:
122 case Pressed:
124 {
123 {
125 m_state = Idle;
124 m_state = Idle;
126 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
125 //if (m_timeStamp.elapsed() < m_clickedPressDelay) {
127
126
128 //emit clicked(m_offset.toPoint());
127 //emit clicked(m_offset.toPoint());
129 //}
128 //}
130 event->accept();
129 event->accept();
131 break;
130 break;
132 }
131 }
133 case Move:
132 case Move:
134 {
133 {
135 calculateSpeed(event->pos());
134 calculateSpeed(event->pos());
136 m_offset = offset();
135 m_offset = offset();
137 m_press = event->pos();
136 m_press = event->pos();
138 if (m_speed == QPointF(0, 0)) {
137 if (m_speed == QPointF(0, 0)) {
139 m_state = Idle;
138 m_state = Idle;
140 }
139 }
141 else {
140 else {
142 m_speed /= 4;
141 m_speed /= 4;
143 m_state = Scroll;
142 m_state = Scroll;
144 m_ticker.start(20);
143 m_ticker.start(20);
145 }
144 }
146 event->accept();
145 event->accept();
147 break;
146 break;
148 }
147 }
149
148
150 case Stop:
149 case Stop:
151 case Idle:
150 case Idle:
152 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
151 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
153 event->ignore();
152 event->ignore();
154 break;
153 break;
155
154
156 }
155 }
157 }
156 }
158 }
157 }
159
158
160 void Scroller::scrollTick()
159 void Scroller::scrollTick()
161 {
160 {
162 switch (m_state) {
161 switch (m_state) {
163 case Scroll:
162 case Scroll:
164 {
163 {
165 lowerSpeed(m_speed);
164 lowerSpeed(m_speed);
166 setOffset(m_offset - m_speed);
165 setOffset(m_offset - m_speed);
167 m_offset = offset();
166 m_offset = offset();
168 if (m_speed == QPointF(0, 0)) {
167 if (m_speed == QPointF(0, 0)) {
169 m_state = Idle;
168 m_state = Idle;
170 m_ticker.stop();
169 m_ticker.stop();
171 }
170 }
172 break;
171 break;
173 }
172 }
174 case Stop:
173 case Stop:
175 m_ticker.stop();
174 m_ticker.stop();
176 break;
175 break;
177 case Idle:
176 case Idle:
178 case Move:
177 case Move:
179 case Pressed:
178 case Pressed:
180 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
179 qWarning() << __FUNCTION__<<"Scroller unexpected state" << m_state;
181 m_ticker.stop();
180 m_ticker.stop();
182 break;
181 break;
183
182
184 }
183 }
185 }
184 }
186
185
187 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
186 void Scroller::lowerSpeed(QPointF& speed, qreal maxSpeed)
188 {
187 {
189 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
188 qreal x = qBound(-maxSpeed, speed.x(), maxSpeed);
190 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
189 qreal y = qBound(-maxSpeed, speed.y(), maxSpeed);
191
190
192 x = (x == 0) ? x :
191 x = (x == 0) ? x :
193 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
192 (x > 0) ? qMax(qreal(0), x - m_fraction.x()) : qMin(qreal(0), x + m_fraction.x());
194 y = (y == 0) ? y :
193 y = (y == 0) ? y :
195 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
194 (y > 0) ? qMax(qreal(0), y - m_fraction.y()) : qMin(qreal(0), y + m_fraction.y());
196 speed.setX(x);
195 speed.setX(x);
197 speed.setY(y);
196 speed.setY(y);
198 }
197 }
199
198
200 void Scroller::calculateSpeed(const QPointF& position)
199 void Scroller::calculateSpeed(const QPointF& position)
201 {
200 {
202 if (m_timeStamp.elapsed() > m_timeTreshold) {
201 if (m_timeStamp.elapsed() > m_timeTreshold) {
203
202
204 QPointF distance = position - m_press;
203 QPointF distance = position - m_press;
205
204
206 m_timeStamp = QTime::currentTime();
205 m_timeStamp = QTime::currentTime();
207 m_speed = distance - m_distance;
206 m_speed = distance - m_distance;
208 m_distance = distance;
207 m_distance = distance;
209
208
210 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
209 qreal fraction = qMax(qAbs(m_speed.x()), qAbs(m_speed.y()));
211
210
212 if (fraction != 0) {
211 if (fraction != 0) {
213 m_fraction.setX(qAbs(m_speed.x() / fraction));
212 m_fraction.setX(qAbs(m_speed.x() / fraction));
214 m_fraction.setY(qAbs(m_speed.y() / fraction));
213 m_fraction.setY(qAbs(m_speed.y() / fraction));
215 }
214 }
216 else {
215 else {
217 m_fraction.setX(1);
216 m_fraction.setX(1);
218 m_fraction.setY(1);
217 m_fraction.setY(1);
219 }
218 }
220 }
219 }
221 }
220 }
222
221
223 void Scroller::setOffset(const QPointF& point)
224 {
225 m_legend->setOffset(point);
226 }
227
228 QPointF Scroller::offset() const
229 {
230 return m_legend->offset();
231 }
232
233 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
222 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
234
223
235 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
224 ScrollTicker::ScrollTicker(Scroller *scroller,QObject* parent):QObject(parent),
236 m_scroller(scroller)
225 m_scroller(scroller)
237 {
226 {
238
227
239 }
228 }
240
229
241 void ScrollTicker::start(int interval)
230 void ScrollTicker::start(int interval)
242 {
231 {
243 if (!m_timer.isActive()){
232 if (!m_timer.isActive()){
244 m_timer.start(interval, this);
233 m_timer.start(interval, this);
245 }
234 }
246 }
235 }
247
236
248 void ScrollTicker::stop()
237 void ScrollTicker::stop()
249 {
238 {
250 m_timer.stop();
239 m_timer.stop();
251 }
240 }
252
241
253 void ScrollTicker::timerEvent(QTimerEvent *event)
242 void ScrollTicker::timerEvent(QTimerEvent *event)
254 {
243 {
255 Q_UNUSED(event);
244 Q_UNUSED(event);
256 m_scroller->scrollTick();
245 m_scroller->scrollTick();
257 }
246 }
258
247
259 QTCOMMERCIALCHART_END_NAMESPACE
248 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,107 +1,106
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef SCROLLER_P_H_
30 #ifndef SCROLLER_P_H_
31 #define SCROLLER_P_H_
31 #define SCROLLER_P_H_
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include <QBasicTimer>
34 #include <QBasicTimer>
35 #include <QTime>
35 #include <QTime>
36 #include <QPointF>
36 #include <QPointF>
37
37
38 class QGraphicsSceneMouseEvent;
38 class QGraphicsSceneMouseEvent;
39
39
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41
41
42 class Scroller;
42 class Scroller;
43 class QLegend;
43 class QLegend;
44
44
45 class ScrollTicker : public QObject
45 class ScrollTicker : public QObject
46 {
46 {
47 public:
47 public:
48 ScrollTicker(Scroller *scroller,QObject *parent=0);
48 ScrollTicker(Scroller *scroller,QObject *parent=0);
49 void start(int interval);
49 void start(int interval);
50 void stop();
50 void stop();
51 protected:
51 protected:
52 void timerEvent(QTimerEvent *event);
52 void timerEvent(QTimerEvent *event);
53
53
54 private:
54 private:
55 QBasicTimer m_timer;
55 QBasicTimer m_timer;
56 Scroller *m_scroller;
56 Scroller *m_scroller;
57 };
57 };
58
58
59 class Scroller
59 class Scroller
60 {
60 {
61 public:
61 public:
62 enum State {
62 enum State {
63 Idle,
63 Idle,
64 Pressed,
64 Pressed,
65 Move,
65 Move,
66 Scroll,
66 Scroll,
67 Stop
67 Stop
68 };
68 };
69
69
70 explicit Scroller(QLegend* legend);
70 Scroller();
71 virtual ~Scroller();
71 virtual ~Scroller();
72
72
73 virtual void setOffset(const QPointF& point);
73 virtual void setOffset(const QPointF& point) = 0;
74 virtual QPointF offset() const;
74 virtual QPointF offset() const = 0;
75
75
76 public:
76 public:
77 void scrollTick();
77 void scrollTick();
78
78
79
79
80 public:
80 public:
81 void mousePressEvent(QGraphicsSceneMouseEvent* event);
81 void mousePressEvent(QGraphicsSceneMouseEvent* event);
82 void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
82 void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
83 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
83 void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
84
84
85 private:
85 private:
86 void calculateSpeed(const QPointF& position);
86 void calculateSpeed(const QPointF& position);
87 void lowerSpeed(QPointF& speed,qreal maxSpeed=100);
87 void lowerSpeed(QPointF& speed,qreal maxSpeed=100);
88
88
89 private:
89 private:
90 ScrollTicker m_ticker;
90 ScrollTicker m_ticker;
91 State m_state;
91 State m_state;
92 QTime m_timeStamp;
92 QTime m_timeStamp;
93 QPointF m_press;
93 QPointF m_press;
94 QPointF m_offset;
94 QPointF m_offset;
95 QPointF m_speed;
95 QPointF m_speed;
96 QPointF m_distance;
96 QPointF m_distance;
97 QPointF m_fraction;
97 QPointF m_fraction;
98 int m_moveThreshold;
98 int m_moveThreshold;
99 int m_timeTreshold;
99 int m_timeTreshold;
100 QLegend* m_legend;
101
100
102
101
103 };
102 };
104
103
105 QTCOMMERCIALCHART_END_NAMESPACE
104 QTCOMMERCIALCHART_END_NAMESPACE
106
105
107 #endif /* SCROLLER_P_H_ */
106 #endif /* SCROLLER_P_H_ */
General Comments 0
You need to be logged in to leave comments. Login now