##// END OF EJS Templates
Change the opengl widget to be child of the first view of the scene...
Miikka Heikkinen -
r2841:3448d86fc598
parent child
Show More
@@ -1,572 +1,570
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd
3 ** Copyright (C) 2015 The Qt Company Ltd
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
5 ** For any questions to The Qt Company, please use contact form at http://qt.io
6 **
6 **
7 ** This file is part of the Qt Charts module.
7 ** This file is part of the Qt Charts module.
8 **
8 **
9 ** Licensees holding valid commercial license for Qt may use this file in
9 ** Licensees holding valid commercial license for Qt may use this file in
10 ** accordance with the Qt License Agreement provided with the Software
10 ** accordance with the Qt License Agreement provided with the Software
11 ** or, alternatively, in accordance with the terms contained in a written
11 ** or, alternatively, in accordance with the terms contained in a written
12 ** agreement between you and The Qt Company.
12 ** agreement between you and The Qt Company.
13 **
13 **
14 ** If you have questions regarding the use of this file, please use
14 ** If you have questions regarding the use of this file, please use
15 ** contact form at http://qt.io
15 ** contact form at http://qt.io
16 **
16 **
17 ****************************************************************************/
17 ****************************************************************************/
18 #include <private/chartpresenter_p.h>
18 #include <private/chartpresenter_p.h>
19 #include <QtCharts/QChart>
19 #include <QtCharts/QChart>
20 #include <private/chartitem_p.h>
20 #include <private/chartitem_p.h>
21 #include <private/qchart_p.h>
21 #include <private/qchart_p.h>
22 #include <QtCharts/QAbstractAxis>
22 #include <QtCharts/QAbstractAxis>
23 #include <private/qabstractaxis_p.h>
23 #include <private/qabstractaxis_p.h>
24 #include <private/chartdataset_p.h>
24 #include <private/chartdataset_p.h>
25 #include <private/chartanimation_p.h>
25 #include <private/chartanimation_p.h>
26 #include <private/qabstractseries_p.h>
26 #include <private/qabstractseries_p.h>
27 #include <QtCharts/QAreaSeries>
27 #include <QtCharts/QAreaSeries>
28 #include <private/chartaxiselement_p.h>
28 #include <private/chartaxiselement_p.h>
29 #include <private/chartbackground_p.h>
29 #include <private/chartbackground_p.h>
30 #include <private/cartesianchartlayout_p.h>
30 #include <private/cartesianchartlayout_p.h>
31 #include <private/polarchartlayout_p.h>
31 #include <private/polarchartlayout_p.h>
32 #include <private/charttitle_p.h>
32 #include <private/charttitle_p.h>
33 #include <QtCore/QTimer>
33 #include <QtCore/QTimer>
34 #include <QtGui/QTextDocument>
34 #include <QtGui/QTextDocument>
35 #include <QtWidgets/QGraphicsScene>
35 #include <QtWidgets/QGraphicsScene>
36
36
37 QT_CHARTS_BEGIN_NAMESPACE
37 QT_CHARTS_BEGIN_NAMESPACE
38
38
39 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
39 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
40 : QObject(chart),
40 : QObject(chart),
41 m_chart(chart),
41 m_chart(chart),
42 m_options(QChart::NoAnimation),
42 m_options(QChart::NoAnimation),
43 m_animationDuration(ChartAnimationDuration),
43 m_animationDuration(ChartAnimationDuration),
44 m_animationCurve(QEasingCurve::OutQuart),
44 m_animationCurve(QEasingCurve::OutQuart),
45 m_state(ShowState),
45 m_state(ShowState),
46 m_background(0),
46 m_background(0),
47 m_plotAreaBackground(0),
47 m_plotAreaBackground(0),
48 m_title(0),
48 m_title(0),
49 m_localizeNumbers(false)
49 m_localizeNumbers(false)
50 #ifndef QT_NO_OPENGL
50 #ifndef QT_NO_OPENGL
51 , m_glWidget(0)
51 , m_glWidget(0)
52 , m_glUseWidget(true)
52 , m_glUseWidget(true)
53 #endif
53 #endif
54 {
54 {
55 if (type == QChart::ChartTypeCartesian)
55 if (type == QChart::ChartTypeCartesian)
56 m_layout = new CartesianChartLayout(this);
56 m_layout = new CartesianChartLayout(this);
57 else if (type == QChart::ChartTypePolar)
57 else if (type == QChart::ChartTypePolar)
58 m_layout = new PolarChartLayout(this);
58 m_layout = new PolarChartLayout(this);
59 Q_ASSERT(m_layout);
59 Q_ASSERT(m_layout);
60 }
60 }
61
61
62 ChartPresenter::~ChartPresenter()
62 ChartPresenter::~ChartPresenter()
63 {
63 {
64 #ifndef QT_NO_OPENGL
64 #ifndef QT_NO_OPENGL
65 delete m_glWidget.data();
65 delete m_glWidget.data();
66 #endif
66 #endif
67 }
67 }
68
68
69 void ChartPresenter::setGeometry(const QRectF rect)
69 void ChartPresenter::setGeometry(const QRectF rect)
70 {
70 {
71 if (m_rect != rect) {
71 if (m_rect != rect) {
72 m_rect = rect;
72 m_rect = rect;
73 foreach (ChartItem *chart, m_chartItems) {
73 foreach (ChartItem *chart, m_chartItems) {
74 chart->domain()->setSize(rect.size());
74 chart->domain()->setSize(rect.size());
75 chart->setPos(rect.topLeft());
75 chart->setPos(rect.topLeft());
76 }
76 }
77 #ifndef QT_NO_OPENGL
77 #ifndef QT_NO_OPENGL
78 if (!m_glWidget.isNull())
78 if (!m_glWidget.isNull())
79 m_glWidget->setGeometry(m_rect.toRect());
79 m_glWidget->setGeometry(m_rect.toRect());
80 #endif
80 #endif
81 emit plotAreaChanged(m_rect);
81 emit plotAreaChanged(m_rect);
82 }
82 }
83 }
83 }
84
84
85 QRectF ChartPresenter::geometry() const
85 QRectF ChartPresenter::geometry() const
86 {
86 {
87 return m_rect;
87 return m_rect;
88 }
88 }
89
89
90 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
90 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
91 {
91 {
92 axis->d_ptr->initializeGraphics(rootItem());
92 axis->d_ptr->initializeGraphics(rootItem());
93 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
93 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
94 ChartAxisElement *item = axis->d_ptr->axisItem();
94 ChartAxisElement *item = axis->d_ptr->axisItem();
95 item->setPresenter(this);
95 item->setPresenter(this);
96 item->setThemeManager(m_chart->d_ptr->m_themeManager);
96 item->setThemeManager(m_chart->d_ptr->m_themeManager);
97 m_axisItems<<item;
97 m_axisItems<<item;
98 m_axes<<axis;
98 m_axes<<axis;
99 m_layout->invalidate();
99 m_layout->invalidate();
100 }
100 }
101
101
102 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
102 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
103 {
103 {
104 ChartAxisElement *item = axis->d_ptr->m_item.take();
104 ChartAxisElement *item = axis->d_ptr->m_item.take();
105 if (item->animation())
105 if (item->animation())
106 item->animation()->stopAndDestroyLater();
106 item->animation()->stopAndDestroyLater();
107 item->hide();
107 item->hide();
108 item->disconnect();
108 item->disconnect();
109 item->deleteLater();
109 item->deleteLater();
110 m_axisItems.removeAll(item);
110 m_axisItems.removeAll(item);
111 m_axes.removeAll(axis);
111 m_axes.removeAll(axis);
112 m_layout->invalidate();
112 m_layout->invalidate();
113 }
113 }
114
114
115
115
116 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
116 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
117 {
117 {
118 series->d_ptr->initializeGraphics(rootItem());
118 series->d_ptr->initializeGraphics(rootItem());
119 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
119 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
120 series->d_ptr->setPresenter(this);
120 series->d_ptr->setPresenter(this);
121 ChartItem *chart = series->d_ptr->chartItem();
121 ChartItem *chart = series->d_ptr->chartItem();
122 chart->setPresenter(this);
122 chart->setPresenter(this);
123 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
123 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
124 chart->setDataSet(m_chart->d_ptr->m_dataset);
124 chart->setDataSet(m_chart->d_ptr->m_dataset);
125 chart->domain()->setSize(m_rect.size());
125 chart->domain()->setSize(m_rect.size());
126 chart->setPos(m_rect.topLeft());
126 chart->setPos(m_rect.topLeft());
127 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
127 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
128 m_chartItems<<chart;
128 m_chartItems<<chart;
129 m_series<<series;
129 m_series<<series;
130 m_layout->invalidate();
130 m_layout->invalidate();
131 }
131 }
132
132
133 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
133 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
134 {
134 {
135 ChartItem *chart = series->d_ptr->m_item.take();
135 ChartItem *chart = series->d_ptr->m_item.take();
136 chart->hide();
136 chart->hide();
137 chart->disconnect();
137 chart->disconnect();
138 chart->deleteLater();
138 chart->deleteLater();
139 if (chart->animation())
139 if (chart->animation())
140 chart->animation()->stopAndDestroyLater();
140 chart->animation()->stopAndDestroyLater();
141 m_chartItems.removeAll(chart);
141 m_chartItems.removeAll(chart);
142 m_series.removeAll(series);
142 m_series.removeAll(series);
143 m_layout->invalidate();
143 m_layout->invalidate();
144 }
144 }
145
145
146 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
146 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
147 {
147 {
148 if (m_options != options) {
148 if (m_options != options) {
149 QChart::AnimationOptions oldOptions = m_options;
149 QChart::AnimationOptions oldOptions = m_options;
150 m_options = options;
150 m_options = options;
151 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
151 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
152 foreach (QAbstractSeries *series, m_series)
152 foreach (QAbstractSeries *series, m_series)
153 series->d_ptr->initializeAnimations(m_options, m_animationDuration,
153 series->d_ptr->initializeAnimations(m_options, m_animationDuration,
154 m_animationCurve);
154 m_animationCurve);
155 }
155 }
156 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
156 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
157 foreach (QAbstractAxis *axis, m_axes)
157 foreach (QAbstractAxis *axis, m_axes)
158 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
158 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
159 }
159 }
160 m_layout->invalidate(); // So that existing animations don't just stop halfway
160 m_layout->invalidate(); // So that existing animations don't just stop halfway
161 }
161 }
162 }
162 }
163
163
164 void ChartPresenter::setAnimationDuration(int msecs)
164 void ChartPresenter::setAnimationDuration(int msecs)
165 {
165 {
166 if (m_animationDuration != msecs) {
166 if (m_animationDuration != msecs) {
167 m_animationDuration = msecs;
167 m_animationDuration = msecs;
168 foreach (QAbstractSeries *series, m_series)
168 foreach (QAbstractSeries *series, m_series)
169 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
169 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
170 foreach (QAbstractAxis *axis, m_axes)
170 foreach (QAbstractAxis *axis, m_axes)
171 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
171 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
172 m_layout->invalidate(); // So that existing animations don't just stop halfway
172 m_layout->invalidate(); // So that existing animations don't just stop halfway
173 }
173 }
174 }
174 }
175
175
176 void ChartPresenter::setAnimationEasingCurve(const QEasingCurve &curve)
176 void ChartPresenter::setAnimationEasingCurve(const QEasingCurve &curve)
177 {
177 {
178 if (m_animationCurve != curve) {
178 if (m_animationCurve != curve) {
179 m_animationCurve = curve;
179 m_animationCurve = curve;
180 foreach (QAbstractSeries *series, m_series)
180 foreach (QAbstractSeries *series, m_series)
181 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
181 series->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
182 foreach (QAbstractAxis *axis, m_axes)
182 foreach (QAbstractAxis *axis, m_axes)
183 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
183 axis->d_ptr->initializeAnimations(m_options, m_animationDuration, m_animationCurve);
184 m_layout->invalidate(); // So that existing animations don't just stop halfway
184 m_layout->invalidate(); // So that existing animations don't just stop halfway
185 }
185 }
186 }
186 }
187
187
188 void ChartPresenter::setState(State state,QPointF point)
188 void ChartPresenter::setState(State state,QPointF point)
189 {
189 {
190 m_state=state;
190 m_state=state;
191 m_statePoint=point;
191 m_statePoint=point;
192 }
192 }
193
193
194 QChart::AnimationOptions ChartPresenter::animationOptions() const
194 QChart::AnimationOptions ChartPresenter::animationOptions() const
195 {
195 {
196 return m_options;
196 return m_options;
197 }
197 }
198
198
199 void ChartPresenter::createBackgroundItem()
199 void ChartPresenter::createBackgroundItem()
200 {
200 {
201 if (!m_background) {
201 if (!m_background) {
202 m_background = new ChartBackground(rootItem());
202 m_background = new ChartBackground(rootItem());
203 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
203 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
204 m_background->setBrush(QChartPrivate::defaultBrush());
204 m_background->setBrush(QChartPrivate::defaultBrush());
205 m_background->setZValue(ChartPresenter::BackgroundZValue);
205 m_background->setZValue(ChartPresenter::BackgroundZValue);
206 }
206 }
207 }
207 }
208
208
209 void ChartPresenter::createPlotAreaBackgroundItem()
209 void ChartPresenter::createPlotAreaBackgroundItem()
210 {
210 {
211 if (!m_plotAreaBackground) {
211 if (!m_plotAreaBackground) {
212 if (m_chart->chartType() == QChart::ChartTypeCartesian)
212 if (m_chart->chartType() == QChart::ChartTypeCartesian)
213 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
213 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
214 else
214 else
215 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
215 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
216 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
216 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
217 // antialising artifacts with axis lines for some reason.
217 // antialising artifacts with axis lines for some reason.
218 m_plotAreaBackground->setPen(QPen(Qt::transparent));
218 m_plotAreaBackground->setPen(QPen(Qt::transparent));
219 m_plotAreaBackground->setBrush(Qt::NoBrush);
219 m_plotAreaBackground->setBrush(Qt::NoBrush);
220 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
220 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
221 m_plotAreaBackground->setVisible(false);
221 m_plotAreaBackground->setVisible(false);
222 }
222 }
223 }
223 }
224
224
225 void ChartPresenter::createTitleItem()
225 void ChartPresenter::createTitleItem()
226 {
226 {
227 if (!m_title) {
227 if (!m_title) {
228 m_title = new ChartTitle(rootItem());
228 m_title = new ChartTitle(rootItem());
229 m_title->setZValue(ChartPresenter::BackgroundZValue);
229 m_title->setZValue(ChartPresenter::BackgroundZValue);
230 }
230 }
231 }
231 }
232
232
233 void ChartPresenter::startAnimation(ChartAnimation *animation)
233 void ChartPresenter::startAnimation(ChartAnimation *animation)
234 {
234 {
235 animation->stop();
235 animation->stop();
236 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
236 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
237 }
237 }
238
238
239 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
239 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
240 {
240 {
241 createBackgroundItem();
241 createBackgroundItem();
242 m_background->setBrush(brush);
242 m_background->setBrush(brush);
243 m_layout->invalidate();
243 m_layout->invalidate();
244 }
244 }
245
245
246 QBrush ChartPresenter::backgroundBrush() const
246 QBrush ChartPresenter::backgroundBrush() const
247 {
247 {
248 if (!m_background)
248 if (!m_background)
249 return QBrush();
249 return QBrush();
250 return m_background->brush();
250 return m_background->brush();
251 }
251 }
252
252
253 void ChartPresenter::setBackgroundPen(const QPen &pen)
253 void ChartPresenter::setBackgroundPen(const QPen &pen)
254 {
254 {
255 createBackgroundItem();
255 createBackgroundItem();
256 m_background->setPen(pen);
256 m_background->setPen(pen);
257 m_layout->invalidate();
257 m_layout->invalidate();
258 }
258 }
259
259
260 QPen ChartPresenter::backgroundPen() const
260 QPen ChartPresenter::backgroundPen() const
261 {
261 {
262 if (!m_background)
262 if (!m_background)
263 return QPen();
263 return QPen();
264 return m_background->pen();
264 return m_background->pen();
265 }
265 }
266
266
267 void ChartPresenter::setBackgroundRoundness(qreal diameter)
267 void ChartPresenter::setBackgroundRoundness(qreal diameter)
268 {
268 {
269 createBackgroundItem();
269 createBackgroundItem();
270 m_background->setDiameter(diameter);
270 m_background->setDiameter(diameter);
271 m_layout->invalidate();
271 m_layout->invalidate();
272 }
272 }
273
273
274 qreal ChartPresenter::backgroundRoundness() const
274 qreal ChartPresenter::backgroundRoundness() const
275 {
275 {
276 if (!m_background)
276 if (!m_background)
277 return 0;
277 return 0;
278 return m_background->diameter();
278 return m_background->diameter();
279 }
279 }
280
280
281 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
281 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
282 {
282 {
283 createPlotAreaBackgroundItem();
283 createPlotAreaBackgroundItem();
284 m_plotAreaBackground->setBrush(brush);
284 m_plotAreaBackground->setBrush(brush);
285 m_layout->invalidate();
285 m_layout->invalidate();
286 }
286 }
287
287
288 QBrush ChartPresenter::plotAreaBackgroundBrush() const
288 QBrush ChartPresenter::plotAreaBackgroundBrush() const
289 {
289 {
290 if (!m_plotAreaBackground)
290 if (!m_plotAreaBackground)
291 return QBrush();
291 return QBrush();
292 return m_plotAreaBackground->brush();
292 return m_plotAreaBackground->brush();
293 }
293 }
294
294
295 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
295 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
296 {
296 {
297 createPlotAreaBackgroundItem();
297 createPlotAreaBackgroundItem();
298 m_plotAreaBackground->setPen(pen);
298 m_plotAreaBackground->setPen(pen);
299 m_layout->invalidate();
299 m_layout->invalidate();
300 }
300 }
301
301
302 QPen ChartPresenter::plotAreaBackgroundPen() const
302 QPen ChartPresenter::plotAreaBackgroundPen() const
303 {
303 {
304 if (!m_plotAreaBackground)
304 if (!m_plotAreaBackground)
305 return QPen();
305 return QPen();
306 return m_plotAreaBackground->pen();
306 return m_plotAreaBackground->pen();
307 }
307 }
308
308
309 void ChartPresenter::setTitle(const QString &title)
309 void ChartPresenter::setTitle(const QString &title)
310 {
310 {
311 createTitleItem();
311 createTitleItem();
312 m_title->setText(title);
312 m_title->setText(title);
313 m_layout->invalidate();
313 m_layout->invalidate();
314 }
314 }
315
315
316 QString ChartPresenter::title() const
316 QString ChartPresenter::title() const
317 {
317 {
318 if (!m_title)
318 if (!m_title)
319 return QString();
319 return QString();
320 return m_title->text();
320 return m_title->text();
321 }
321 }
322
322
323 void ChartPresenter::setTitleFont(const QFont &font)
323 void ChartPresenter::setTitleFont(const QFont &font)
324 {
324 {
325 createTitleItem();
325 createTitleItem();
326 m_title->setFont(font);
326 m_title->setFont(font);
327 m_layout->invalidate();
327 m_layout->invalidate();
328 }
328 }
329
329
330 QFont ChartPresenter::titleFont() const
330 QFont ChartPresenter::titleFont() const
331 {
331 {
332 if (!m_title)
332 if (!m_title)
333 return QFont();
333 return QFont();
334 return m_title->font();
334 return m_title->font();
335 }
335 }
336
336
337 void ChartPresenter::setTitleBrush(const QBrush &brush)
337 void ChartPresenter::setTitleBrush(const QBrush &brush)
338 {
338 {
339 createTitleItem();
339 createTitleItem();
340 m_title->setDefaultTextColor(brush.color());
340 m_title->setDefaultTextColor(brush.color());
341 m_layout->invalidate();
341 m_layout->invalidate();
342 }
342 }
343
343
344 QBrush ChartPresenter::titleBrush() const
344 QBrush ChartPresenter::titleBrush() const
345 {
345 {
346 if (!m_title)
346 if (!m_title)
347 return QBrush();
347 return QBrush();
348 return QBrush(m_title->defaultTextColor());
348 return QBrush(m_title->defaultTextColor());
349 }
349 }
350
350
351 void ChartPresenter::setBackgroundVisible(bool visible)
351 void ChartPresenter::setBackgroundVisible(bool visible)
352 {
352 {
353 createBackgroundItem();
353 createBackgroundItem();
354 m_background->setVisible(visible);
354 m_background->setVisible(visible);
355 }
355 }
356
356
357
357
358 bool ChartPresenter::isBackgroundVisible() const
358 bool ChartPresenter::isBackgroundVisible() const
359 {
359 {
360 if (!m_background)
360 if (!m_background)
361 return false;
361 return false;
362 return m_background->isVisible();
362 return m_background->isVisible();
363 }
363 }
364
364
365 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
365 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
366 {
366 {
367 createPlotAreaBackgroundItem();
367 createPlotAreaBackgroundItem();
368 m_plotAreaBackground->setVisible(visible);
368 m_plotAreaBackground->setVisible(visible);
369 }
369 }
370
370
371 bool ChartPresenter::isPlotAreaBackgroundVisible() const
371 bool ChartPresenter::isPlotAreaBackgroundVisible() const
372 {
372 {
373 if (!m_plotAreaBackground)
373 if (!m_plotAreaBackground)
374 return false;
374 return false;
375 return m_plotAreaBackground->isVisible();
375 return m_plotAreaBackground->isVisible();
376 }
376 }
377
377
378 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
378 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
379 {
379 {
380 createBackgroundItem();
380 createBackgroundItem();
381 m_background->setDropShadowEnabled(enabled);
381 m_background->setDropShadowEnabled(enabled);
382 }
382 }
383
383
384 bool ChartPresenter::isBackgroundDropShadowEnabled() const
384 bool ChartPresenter::isBackgroundDropShadowEnabled() const
385 {
385 {
386 if (!m_background)
386 if (!m_background)
387 return false;
387 return false;
388 return m_background->isDropShadowEnabled();
388 return m_background->isDropShadowEnabled();
389 }
389 }
390
390
391 void ChartPresenter::setLocalizeNumbers(bool localize)
391 void ChartPresenter::setLocalizeNumbers(bool localize)
392 {
392 {
393 m_localizeNumbers = localize;
393 m_localizeNumbers = localize;
394 m_layout->invalidate();
394 m_layout->invalidate();
395 }
395 }
396
396
397 void ChartPresenter::setLocale(const QLocale &locale)
397 void ChartPresenter::setLocale(const QLocale &locale)
398 {
398 {
399 m_locale = locale;
399 m_locale = locale;
400 m_layout->invalidate();
400 m_layout->invalidate();
401 }
401 }
402
402
403 AbstractChartLayout *ChartPresenter::layout()
403 AbstractChartLayout *ChartPresenter::layout()
404 {
404 {
405 return m_layout;
405 return m_layout;
406 }
406 }
407
407
408 QLegend *ChartPresenter::legend()
408 QLegend *ChartPresenter::legend()
409 {
409 {
410 return m_chart->legend();
410 return m_chart->legend();
411 }
411 }
412
412
413 void ChartPresenter::setVisible(bool visible)
413 void ChartPresenter::setVisible(bool visible)
414 {
414 {
415 m_chart->setVisible(visible);
415 m_chart->setVisible(visible);
416 }
416 }
417
417
418 ChartBackground *ChartPresenter::backgroundElement()
418 ChartBackground *ChartPresenter::backgroundElement()
419 {
419 {
420 return m_background;
420 return m_background;
421 }
421 }
422
422
423 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
423 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
424 {
424 {
425 return m_plotAreaBackground;
425 return m_plotAreaBackground;
426 }
426 }
427
427
428 QList<ChartAxisElement *> ChartPresenter::axisItems() const
428 QList<ChartAxisElement *> ChartPresenter::axisItems() const
429 {
429 {
430 return m_axisItems;
430 return m_axisItems;
431 }
431 }
432
432
433 QList<ChartItem *> ChartPresenter::chartItems() const
433 QList<ChartItem *> ChartPresenter::chartItems() const
434 {
434 {
435 return m_chartItems;
435 return m_chartItems;
436 }
436 }
437
437
438 ChartTitle *ChartPresenter::titleElement()
438 ChartTitle *ChartPresenter::titleElement()
439 {
439 {
440 return m_title;
440 return m_title;
441 }
441 }
442
442
443 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
443 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
444 {
444 {
445 static QGraphicsTextItem dummyTextItem;
445 static QGraphicsTextItem dummyTextItem;
446 static bool initMargin = true;
446 static bool initMargin = true;
447 if (initMargin) {
447 if (initMargin) {
448 dummyTextItem.document()->setDocumentMargin(textMargin());
448 dummyTextItem.document()->setDocumentMargin(textMargin());
449 initMargin = false;
449 initMargin = false;
450 }
450 }
451
451
452 dummyTextItem.setFont(font);
452 dummyTextItem.setFont(font);
453 dummyTextItem.setHtml(text);
453 dummyTextItem.setHtml(text);
454 QRectF boundingRect = dummyTextItem.boundingRect();
454 QRectF boundingRect = dummyTextItem.boundingRect();
455
455
456 // Take rotation into account
456 // Take rotation into account
457 if (angle) {
457 if (angle) {
458 QTransform transform;
458 QTransform transform;
459 transform.rotate(angle);
459 transform.rotate(angle);
460 boundingRect = transform.mapRect(boundingRect);
460 boundingRect = transform.mapRect(boundingRect);
461 }
461 }
462
462
463 return boundingRect;
463 return boundingRect;
464 }
464 }
465
465
466 // boundingRect parameter returns the rotated bounding rect of the text
466 // boundingRect parameter returns the rotated bounding rect of the text
467 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
467 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
468 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
468 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
469 {
469 {
470 QString truncatedString(text);
470 QString truncatedString(text);
471 boundingRect = textBoundingRect(font, truncatedString, angle);
471 boundingRect = textBoundingRect(font, truncatedString, angle);
472 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
472 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
473 // It can be assumed that almost any amount of string manipulation is faster
473 // It can be assumed that almost any amount of string manipulation is faster
474 // than calculating one bounding rectangle, so first prepare a list of truncated strings
474 // than calculating one bounding rectangle, so first prepare a list of truncated strings
475 // to try.
475 // to try.
476 static QRegExp truncateMatcher(QStringLiteral("&#?[0-9a-zA-Z]*;$"));
476 static QRegExp truncateMatcher(QStringLiteral("&#?[0-9a-zA-Z]*;$"));
477
477
478 QVector<QString> testStrings(text.length());
478 QVector<QString> testStrings(text.length());
479 int count(0);
479 int count(0);
480 static QLatin1Char closeTag('>');
480 static QLatin1Char closeTag('>');
481 static QLatin1Char openTag('<');
481 static QLatin1Char openTag('<');
482 static QLatin1Char semiColon(';');
482 static QLatin1Char semiColon(';');
483 static QLatin1String ellipsis("...");
483 static QLatin1String ellipsis("...");
484 while (truncatedString.length() > 1) {
484 while (truncatedString.length() > 1) {
485 int chopIndex(-1);
485 int chopIndex(-1);
486 int chopCount(1);
486 int chopCount(1);
487 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
487 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
488
488
489 if (lastChar == closeTag)
489 if (lastChar == closeTag)
490 chopIndex = truncatedString.lastIndexOf(openTag);
490 chopIndex = truncatedString.lastIndexOf(openTag);
491 else if (lastChar == semiColon)
491 else if (lastChar == semiColon)
492 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
492 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
493
493
494 if (chopIndex != -1)
494 if (chopIndex != -1)
495 chopCount = truncatedString.length() - chopIndex;
495 chopCount = truncatedString.length() - chopIndex;
496 truncatedString.chop(chopCount);
496 truncatedString.chop(chopCount);
497 testStrings[count] = truncatedString + ellipsis;
497 testStrings[count] = truncatedString + ellipsis;
498 count++;
498 count++;
499 }
499 }
500
500
501 // Binary search for best fit
501 // Binary search for best fit
502 int minIndex(0);
502 int minIndex(0);
503 int maxIndex(count - 1);
503 int maxIndex(count - 1);
504 int bestIndex(count);
504 int bestIndex(count);
505 QRectF checkRect;
505 QRectF checkRect;
506
506
507 while (maxIndex >= minIndex) {
507 while (maxIndex >= minIndex) {
508 int mid = (maxIndex + minIndex) / 2;
508 int mid = (maxIndex + minIndex) / 2;
509 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
509 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
510 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
510 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
511 // Checked index too large, all under this are also too large
511 // Checked index too large, all under this are also too large
512 minIndex = mid + 1;
512 minIndex = mid + 1;
513 } else {
513 } else {
514 // Checked index fits, all over this also fit
514 // Checked index fits, all over this also fit
515 maxIndex = mid - 1;
515 maxIndex = mid - 1;
516 bestIndex = mid;
516 bestIndex = mid;
517 boundingRect = checkRect;
517 boundingRect = checkRect;
518 }
518 }
519 }
519 }
520 // Default to "..." if nothing fits
520 // Default to "..." if nothing fits
521 if (bestIndex == count) {
521 if (bestIndex == count) {
522 boundingRect = textBoundingRect(font, ellipsis, angle);
522 boundingRect = textBoundingRect(font, ellipsis, angle);
523 truncatedString = ellipsis;
523 truncatedString = ellipsis;
524 } else {
524 } else {
525 truncatedString = testStrings.at(bestIndex);
525 truncatedString = testStrings.at(bestIndex);
526 }
526 }
527 }
527 }
528
528
529 return truncatedString;
529 return truncatedString;
530 }
530 }
531
531
532 QString ChartPresenter::numberToString(double value, char f, int prec)
532 QString ChartPresenter::numberToString(double value, char f, int prec)
533 {
533 {
534 if (m_localizeNumbers)
534 if (m_localizeNumbers)
535 return m_locale.toString(value, f, prec);
535 return m_locale.toString(value, f, prec);
536 else
536 else
537 return QString::number(value, f, prec);
537 return QString::number(value, f, prec);
538 }
538 }
539
539
540 QString ChartPresenter::numberToString(int value)
540 QString ChartPresenter::numberToString(int value)
541 {
541 {
542 if (m_localizeNumbers)
542 if (m_localizeNumbers)
543 return m_locale.toString(value);
543 return m_locale.toString(value);
544 else
544 else
545 return QString::number(value);
545 return QString::number(value);
546 }
546 }
547
547
548 void ChartPresenter::ensureGLWidget()
548 void ChartPresenter::ensureGLWidget()
549 {
549 {
550 #ifndef QT_NO_OPENGL
550 #ifndef QT_NO_OPENGL
551 // GLWidget pointer is wrapped in QPointer as its parent is not in our control, and therefore
551 // GLWidget pointer is wrapped in QPointer as its parent is not in our control, and therefore
552 // can potentially get deleted unexpectedly.
552 // can potentially get deleted unexpectedly.
553 if (m_glWidget.isNull() && m_glUseWidget && m_chart->scene()) {
553 if (m_glWidget.isNull() && m_glUseWidget && m_chart->scene()) {
554 QObject *parent = m_chart->scene()->parent();
554 // Find the view of the scene. If the scene has multiple views, only the first view is
555 while (parent) {
555 // chosen.
556 QWidget *parentWidget = qobject_cast<QWidget *>(parent);
556 QList<QGraphicsView *> views = m_chart->scene()->views();
557 if (parentWidget) {
557 if (views.size()) {
558 m_glWidget = new GLWidget(m_chart->d_ptr->m_dataset->glXYSeriesDataManager(),
558 QGraphicsView *firstView = views.at(0);
559 parentWidget);
559 m_glWidget = new GLWidget(m_chart->d_ptr->m_dataset->glXYSeriesDataManager(),
560 m_glWidget->setGeometry(m_rect.toRect());
560 firstView);
561 m_glWidget->show();
561 m_glWidget->setGeometry(m_rect.toRect());
562 break;
562 m_glWidget->show();
563 }
564 parent = parent->parent();
565 }
563 }
566 }
564 }
567 #endif
565 #endif
568 }
566 }
569
567
570 #include "moc_chartpresenter_p.cpp"
568 #include "moc_chartpresenter_p.cpp"
571
569
572 QT_CHARTS_END_NAMESPACE
570 QT_CHARTS_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now