##// END OF EJS Templates
Fix ChartView visibility change drawing...
Titta Heikkala -
r2605:23dc25e6ce18
parent child
Show More
@@ -1,201 +1,203
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "abstractchartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxiselement_p.h"
25 25 #include "charttitle_p.h"
26 26 #include "chartbackground_p.h"
27 27 #include <QDebug>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 static const qreal golden_ratio = 0.4;
32 32
33 33 AbstractChartLayout::AbstractChartLayout(ChartPresenter *presenter)
34 34 : m_presenter(presenter),
35 35 m_margins(20, 20, 20, 20),
36 36 m_minChartRect(0, 0, 200, 200)
37 37 {
38 38 }
39 39
40 40 AbstractChartLayout::~AbstractChartLayout()
41 41 {
42 42 }
43 43
44 44 void AbstractChartLayout::setGeometry(const QRectF &rect)
45 45 {
46 46 if (!rect.isValid())
47 47 return;
48 48
49 QList<ChartAxisElement *> axes = m_presenter->axisItems();
50 ChartTitle *title = m_presenter->titleElement();
51 QLegend *legend = m_presenter->legend();
52 ChartBackground *background = m_presenter->backgroundElement();
49 if (m_presenter->chart()->isVisible()) {
50 QList<ChartAxisElement *> axes = m_presenter->axisItems();
51 ChartTitle *title = m_presenter->titleElement();
52 QLegend *legend = m_presenter->legend();
53 ChartBackground *background = m_presenter->backgroundElement();
53 54
54 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
55 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
55 56
56 contentGeometry = calculateContentGeometry(contentGeometry);
57 contentGeometry = calculateContentGeometry(contentGeometry);
57 58
58 if (title && title->isVisible())
59 contentGeometry = calculateTitleGeometry(contentGeometry, title);
59 if (title && title->isVisible())
60 contentGeometry = calculateTitleGeometry(contentGeometry, title);
60 61
61 if (legend->isAttachedToChart() && legend->isVisible())
62 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
62 if (legend->isAttachedToChart() && legend->isVisible())
63 contentGeometry = calculateLegendGeometry(contentGeometry, legend);
63 64
64 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
65 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
65 66
66 m_presenter->setGeometry(contentGeometry);
67 if (m_presenter->chart()->chartType() == QChart::ChartTypeCartesian)
68 static_cast<QGraphicsRectItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry);
69 else
70 static_cast<QGraphicsEllipseItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry);
67 m_presenter->setGeometry(contentGeometry);
68 if (m_presenter->chart()->chartType() == QChart::ChartTypeCartesian)
69 static_cast<QGraphicsRectItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry);
70 else
71 static_cast<QGraphicsEllipseItem *>(m_presenter->plotAreaElement())->setRect(contentGeometry);
72 }
71 73
72 74 QGraphicsLayout::setGeometry(rect);
73 75 }
74 76
75 77 QRectF AbstractChartLayout::calculateContentGeometry(const QRectF &geometry) const
76 78 {
77 79 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
78 80 }
79 81
80 82 QRectF AbstractChartLayout::calculateContentMinimum(const QRectF &minimum) const
81 83 {
82 84 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
83 85 }
84 86
85 87
86 88 QRectF AbstractChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
87 89 {
88 90 qreal left;
89 91 qreal top;
90 92 qreal right;
91 93 qreal bottom;
92 94 getContentsMargins(&left, &top, &right, &bottom);
93 95 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
94 96 if (background)
95 97 background->setRect(backgroundGeometry);
96 98 return backgroundGeometry;
97 99 }
98 100
99 101 QRectF AbstractChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
100 102 {
101 103 qreal left;
102 104 qreal top;
103 105 qreal right;
104 106 qreal bottom;
105 107 getContentsMargins(&left, &top, &right, &bottom);
106 108 return minimum.adjusted(0, 0, left + right, top + bottom);
107 109 }
108 110
109 111 QRectF AbstractChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
110 112 {
111 113 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
112 114 QRectF legendRect;
113 115 QRectF result;
114 116
115 117 switch (legend->alignment()) {
116 118 case Qt::AlignTop: {
117 119 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
118 120 result = geometry.adjusted(0, legendRect.height(), 0, 0);
119 121 break;
120 122 }
121 123 case Qt::AlignBottom: {
122 124 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
123 125 result = geometry.adjusted(0, 0, 0, -legendRect.height());
124 126 break;
125 127 }
126 128 case Qt::AlignLeft: {
127 129 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
128 130 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
129 131 result = geometry.adjusted(width, 0, 0, 0);
130 132 break;
131 133 }
132 134 case Qt::AlignRight: {
133 135 qreal width = qMin(size.width(), geometry.width() * golden_ratio);
134 136 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
135 137 result = geometry.adjusted(0, 0, -width, 0);
136 138 break;
137 139 }
138 140 default: {
139 141 legendRect = QRectF(0, 0, 0, 0);
140 142 result = geometry;
141 143 break;
142 144 }
143 145 }
144 146
145 147 legend->setGeometry(legendRect);
146 148
147 149 return result;
148 150 }
149 151
150 152 QRectF AbstractChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
151 153 {
152 154 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
153 155 return geometry.adjusted(0, 0, minSize.width(), minSize.height());
154 156 }
155 157
156 158 QRectF AbstractChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
157 159 {
158 160 title->setGeometry(geometry);
159 161 QPointF center = geometry.center() - title->boundingRect().center();
160 162 title->setPos(center.x(), title->pos().y());
161 163 return geometry.adjusted(0, title->boundingRect().height()+1, 0, 0);
162 164 }
163 165
164 166 QRectF AbstractChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
165 167 {
166 168 QSizeF min = title->sizeHint(Qt::MinimumSize);
167 169 return minimum.adjusted(0, 0, min.width(), min.height());
168 170 }
169 171
170 172 QSizeF AbstractChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
171 173 {
172 174 Q_UNUSED(constraint);
173 175 if (which == Qt::MinimumSize) {
174 176 QList<ChartAxisElement *> axes = m_presenter->axisItems();
175 177 ChartTitle *title = m_presenter->titleElement();
176 178 QLegend *legend = m_presenter->legend();
177 179 QRectF minimumRect(0, 0, 0, 0);
178 180 minimumRect = calculateBackgroundMinimum(minimumRect);
179 181 minimumRect = calculateContentMinimum(minimumRect);
180 182 minimumRect = calculateTitleMinimum(minimumRect, title);
181 183 minimumRect = calculateLegendMinimum(minimumRect, legend);
182 184 minimumRect = calculateAxisMinimum(minimumRect, axes);
183 185 return minimumRect.united(m_minChartRect).size().toSize();
184 186 }
185 187 return QSize(-1, -1);
186 188 }
187 189
188 190 void AbstractChartLayout::setMargins(const QMargins &margins)
189 191 {
190 192 if (m_margins != margins) {
191 193 m_margins = margins;
192 194 updateGeometry();
193 195 }
194 196 }
195 197
196 198 QMargins AbstractChartLayout::margins() const
197 199 {
198 200 return m_margins;
199 201 }
200 202
201 203 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,594 +1,596
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Enterprise Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 11 ** accordance with the Qt Enterprise License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qlegend.h"
22 22 #include "qlegend_p.h"
23 23 #include "qabstractseries.h"
24 24 #include "qabstractseries_p.h"
25 25 #include "qchart_p.h"
26 26 #include "legendlayout_p.h"
27 27 #include "chartpresenter_p.h"
28 28 #include "abstractchartlayout_p.h"
29 29 #include "qlegendmarker.h"
30 30 #include "qlegendmarker_p.h"
31 31 #include "legendmarkeritem_p.h"
32 32 #include "chartdataset_p.h"
33 33 #include <QPainter>
34 34 #include <QPen>
35 35 #include <QGraphicsItemGroup>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 /*!
40 40 \class QLegend
41 41 \brief Legend object.
42 42 \mainclass
43 43
44 44 QLegend is a graphical object for displaying the legend of the chart. Legend state is updated by QChart, when
45 45 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
46 46 handle the drawing manually.
47 47 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
48 48
49 49 \image examples_percentbarchart_legend.png
50 50
51 51 \sa QChart
52 52 */
53 53 /*!
54 54 \qmlclass Legend QLegend
55 55 \brief Legend is part of Qt Chart QML API.
56 56
57 57 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
58 58 series have been changed. Legend is used via ChartView class. For example:
59 59 \code
60 60 ChartView {
61 61 legend.visible: true
62 62 legend.alignment: Qt.AlignBottom
63 63 // Add a few series...
64 64 }
65 65 \endcode
66 66
67 67 \image examples_percentbarchart_legend.png
68 68
69 69 Please note that there is no QML API available for modifying legend markers, unlike in the Qt API of Charts.
70 70 The use case of modifying markers can be implemented for example by creating your own custom legend. For an example
71 71 on how to do this, see \l {demos/qmlcustomlegend}{Qml Custom Demo} application.
72 72 */
73 73
74 74 /*!
75 75 \property QLegend::alignment
76 76 \brief The alignment of the legend.
77 77
78 78 Legend paints on the defined position in the chart. The following alignments are supported:
79 79 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
80 80 */
81 81 /*!
82 82 \qmlproperty Qt.Alignment Legend::alignment
83 83 \brief The alignment of the legend.
84 84
85 85 Legend paints on the defined position in the chart. The following alignments are supported:
86 86 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
87 87 */
88 88
89 89 /*!
90 90 \property QLegend::backgroundVisible
91 91 Whether the legend background is visible or not.
92 92 */
93 93 /*!
94 94 \qmlproperty bool Legend::backgroundVisible
95 95 Whether the legend background is visible or not.
96 96 */
97 97
98 98 /*!
99 99 \property QLegend::color
100 100 The color of the legend, i.e. the background (brush) color. Note that if you change the color
101 101 of the legend, the style of the legend brush is set to Qt::SolidPattern.
102 102 */
103 103 /*!
104 104 \qmlproperty color Legend::color
105 105 The color of the legend, i.e. the background (brush) color.
106 106 */
107 107
108 108 /*!
109 109 \property QLegend::borderColor
110 110 The border color of the legend, i.e. the line color.
111 111 */
112 112 /*!
113 113 \qmlproperty color Legend::borderColor
114 114 The border color of the legend, i.e. the line color.
115 115 */
116 116
117 117 /*!
118 118 \property QLegend::font
119 119 The font of markers used by legend
120 120 */
121 121 /*!
122 122 \qmlproperty Font Legend::font
123 123 The font of markers used by legend
124 124 */
125 125
126 126 /*!
127 127 \property QLegend::labelColor
128 128 The color of brush used to draw labels.
129 129 */
130 130 /*!
131 131 \qmlproperty color QLegend::labelColor
132 132 The color of brush used to draw labels.
133 133 */
134 134
135 135 /*!
136 136 \fn void QLegend::backgroundVisibleChanged(bool)
137 137 The visibility of the legend background changed to \a visible.
138 138 */
139 139
140 140 /*!
141 141 \fn void QLegend::colorChanged(QColor)
142 142 The color of the legend background changed to \a color.
143 143 */
144 144
145 145 /*!
146 146 \fn void QLegend::borderColorChanged(QColor)
147 147 The border color of the legend background changed to \a color.
148 148 */
149 149
150 150 /*!
151 151 \fn void QLegend::fontChanged(QFont)
152 152 The font of markers of the legend changed to \a font.
153 153 */
154 154
155 155 /*!
156 156 \fn void QLegend::labelColorChanged(QColor color)
157 157 This signal is emitted when the color of brush used to draw labels has changed to \a color.
158 158 */
159 159
160 160 QLegend::QLegend(QChart *chart): QGraphicsWidget(chart),
161 161 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter, chart, this))
162 162 {
163 163 setZValue(ChartPresenter::LegendZValue);
164 164 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
165 165 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesAdded(QAbstractSeries*)));
166 166 QObject::connect(chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), d_ptr.data(), SLOT(handleSeriesRemoved(QAbstractSeries*)));
167 167 setLayout(d_ptr->m_layout);
168 168 }
169 169
170 170 /*!
171 171 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
172 172 */
173 173 QLegend::~QLegend()
174 174 {
175 175 }
176 176
177 177 /*!
178 178 \internal
179 179 */
180 180 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
181 181 {
182 182 Q_UNUSED(option)
183 183 Q_UNUSED(widget)
184 184
185 185 if (!d_ptr->m_backgroundVisible)
186 186 return;
187 187
188 188 painter->setOpacity(opacity());
189 189 painter->setPen(d_ptr->m_pen);
190 190 painter->setBrush(d_ptr->m_brush);
191 191 painter->drawRoundRect(rect(), d_ptr->roundness(rect().width()), d_ptr->roundness(rect().height()));
192 192 }
193 193
194 194
195 195 /*!
196 196 Sets the \a brush of legend. Brush affects the background of legend.
197 197 */
198 198 void QLegend::setBrush(const QBrush &brush)
199 199 {
200 200 if (d_ptr->m_brush != brush) {
201 201 d_ptr->m_brush = brush;
202 202 update();
203 203 emit colorChanged(brush.color());
204 204 }
205 205 }
206 206
207 207 /*!
208 208 Returns the brush used by legend.
209 209 */
210 210 QBrush QLegend::brush() const
211 211 {
212 212 return d_ptr->m_brush;
213 213 }
214 214
215 215 void QLegend::setColor(QColor color)
216 216 {
217 217 QBrush b = d_ptr->m_brush;
218 218 if (b.style() != Qt::SolidPattern || b.color() != color) {
219 219 b.setStyle(Qt::SolidPattern);
220 220 b.setColor(color);
221 221 setBrush(b);
222 222 }
223 223 }
224 224
225 225 QColor QLegend::color()
226 226 {
227 227 return d_ptr->m_brush.color();
228 228 }
229 229
230 230 /*!
231 231 Sets the \a pen of legend. Pen affects the legend borders.
232 232 */
233 233 void QLegend::setPen(const QPen &pen)
234 234 {
235 235 if (d_ptr->m_pen != pen) {
236 236 d_ptr->m_pen = pen;
237 237 update();
238 238 emit borderColorChanged(pen.color());
239 239 }
240 240 }
241 241
242 242 /*!
243 243 Returns the pen used by legend
244 244 */
245 245
246 246 QPen QLegend::pen() const
247 247 {
248 248 return d_ptr->m_pen;
249 249 }
250 250
251 251 void QLegend::setFont(const QFont &font)
252 252 {
253 253 if (d_ptr->m_font != font) {
254 254 d_ptr->m_font = font;
255 255 foreach (QLegendMarker *marker, d_ptr->markers()) {
256 256 marker->setFont(d_ptr->m_font);
257 257 }
258 258 layout()->invalidate();
259 259 emit fontChanged(font);
260 260 }
261 261 }
262 262
263 263 QFont QLegend::font() const
264 264 {
265 265 return d_ptr->m_font;
266 266 }
267 267
268 268 void QLegend::setBorderColor(QColor color)
269 269 {
270 270 QPen p = d_ptr->m_pen;
271 271 if (p.color() != color) {
272 272 p.setColor(color);
273 273 setPen(p);
274 274 }
275 275 }
276 276
277 277 QColor QLegend::borderColor()
278 278 {
279 279 return d_ptr->m_pen.color();
280 280 }
281 281
282 282 /*!
283 283 Set brush used to draw labels to \a brush.
284 284 */
285 285 void QLegend::setLabelBrush(const QBrush &brush)
286 286 {
287 287 if (d_ptr->m_labelBrush != brush) {
288 288 d_ptr->m_labelBrush = brush;
289 289 foreach (QLegendMarker *marker, d_ptr->markers()) {
290 290 marker->setLabelBrush(d_ptr->m_labelBrush);
291 291 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
292 292 // instead of mapping it from label brush color
293 293 marker->setPen(brush.color());
294 294 }
295 295 emit labelColorChanged(brush.color());
296 296 }
297 297 }
298 298
299 299 /*!
300 300 Brush used to draw labels.
301 301 */
302 302 QBrush QLegend::labelBrush() const
303 303 {
304 304 return d_ptr->m_labelBrush;
305 305 }
306 306
307 307 void QLegend::setLabelColor(QColor color)
308 308 {
309 309 QBrush b = d_ptr->m_labelBrush;
310 310 if (b.style() != Qt::SolidPattern || b.color() != color) {
311 311 b.setStyle(Qt::SolidPattern);
312 312 b.setColor(color);
313 313 setLabelBrush(b);
314 314 }
315 315 }
316 316
317 317 QColor QLegend::labelColor() const
318 318 {
319 319 return d_ptr->m_labelBrush.color();
320 320 }
321 321
322 322
323 323 void QLegend::setAlignment(Qt::Alignment alignment)
324 324 {
325 325 if (d_ptr->m_alignment != alignment) {
326 326 d_ptr->m_alignment = alignment;
327 327 layout()->invalidate();
328 328 }
329 329 }
330 330
331 331 Qt::Alignment QLegend::alignment() const
332 332 {
333 333 return d_ptr->m_alignment;
334 334 }
335 335
336 336 /*!
337 337 Detaches the legend from chart. Chart won't change layout of the legend.
338 338 */
339 339 void QLegend::detachFromChart()
340 340 {
341 341 d_ptr->m_attachedToChart = false;
342 342 // layout()->invalidate();
343 343 d_ptr->m_chart->layout()->invalidate();
344 344 setParent(0);
345 345
346 346 }
347 347
348 348 /*!
349 349 Attaches the legend to chart. Chart may change layout of the legend.
350 350 */
351 351 void QLegend::attachToChart()
352 352 {
353 353 d_ptr->m_attachedToChart = true;
354 354 // layout()->invalidate();
355 355 d_ptr->m_chart->layout()->invalidate();
356 356 setParent(d_ptr->m_chart);
357 357 }
358 358
359 359 /*!
360 360 Returns true, if legend is attached to chart.
361 361 */
362 362 bool QLegend::isAttachedToChart()
363 363 {
364 364 return d_ptr->m_attachedToChart;
365 365 }
366 366
367 367 /*!
368 368 Sets the visibility of legend background to \a visible
369 369 */
370 370 void QLegend::setBackgroundVisible(bool visible)
371 371 {
372 372 if (d_ptr->m_backgroundVisible != visible) {
373 373 d_ptr->m_backgroundVisible = visible;
374 374 update();
375 375 emit backgroundVisibleChanged(visible);
376 376 }
377 377 }
378 378
379 379 /*!
380 380 Returns the visibility of legend background
381 381 */
382 382 bool QLegend::isBackgroundVisible() const
383 383 {
384 384 return d_ptr->m_backgroundVisible;
385 385 }
386 386
387 387 /*!
388 388 Returns the list of markers in legend. The list can be filtered with \a series parameter.
389 389 If \a series is given, only markers related to that series are returned.
390 390 */
391 391 QList<QLegendMarker*> QLegend::markers(QAbstractSeries *series) const
392 392 {
393 393 return d_ptr->markers(series);
394 394 }
395 395
396 396 /*!
397 397 \internal \a event see QGraphicsWidget for details
398 398 */
399 399 void QLegend::hideEvent(QHideEvent *event)
400 400 {
401 401 if (isAttachedToChart())
402 402 d_ptr->m_presenter->layout()->invalidate();
403 403 QGraphicsWidget::hideEvent(event);
404 404 }
405 405 /*!
406 406 \internal \a event see QGraphicsWidget for details
407 407 */
408 408 void QLegend::showEvent(QShowEvent *event)
409 409 {
410 410 if (isAttachedToChart())
411 411 layout()->invalidate();
412 412 QGraphicsWidget::showEvent(event);
413 413 //layout activation will show the items
414 414 }
415 415
416 416 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
417 417
418 418 QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q)
419 419 : q_ptr(q),
420 420 m_presenter(presenter),
421 421 m_layout(new LegendLayout(q)),
422 422 m_chart(chart),
423 423 m_items(new QGraphicsItemGroup(q)),
424 424 m_alignment(Qt::AlignTop),
425 425 m_brush(QBrush()),
426 426 m_pen(QPen()),
427 427 m_labelBrush(QBrush()),
428 428 m_diameter(5),
429 429 m_attachedToChart(true),
430 430 m_backgroundVisible(false)
431 431 {
432 432 m_items->setHandlesChildEvents(false);
433 433 }
434 434
435 435 QLegendPrivate::~QLegendPrivate()
436 436 {
437 437
438 438 }
439 439
440 440 void QLegendPrivate::setOffset(const QPointF &offset)
441 441 {
442 442 m_layout->setOffset(offset.x(), offset.y());
443 443 }
444 444
445 445 QPointF QLegendPrivate::offset() const
446 446 {
447 447 return m_layout->offset();
448 448 }
449 449
450 450 int QLegendPrivate::roundness(qreal size)
451 451 {
452 452 return 100 * m_diameter / int(size);
453 453 }
454 454
455 455 QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series)
456 456 {
457 457 // Return all markers
458 458 if (!series) {
459 459 return m_markers;
460 460 }
461 461
462 462 // Create filtered list
463 463 QList<QLegendMarker *> markers;
464 464 foreach (QLegendMarker *marker, m_markers) {
465 465 if (marker->series() == series) {
466 466 markers.append(marker);
467 467 }
468 468 }
469 469 return markers;
470 470 }
471 471
472 472 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series)
473 473 {
474 474 if (m_series.contains(series)) {
475 475 return;
476 476 }
477 477
478 478 QList<QLegendMarker*> newMarkers = series->d_ptr->createLegendMarkers(q_ptr);
479 479 decorateMarkers(newMarkers);
480 480 addMarkers(newMarkers);
481 481
482 482 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
483 483 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
484 484
485 485 m_series.append(series);
486 486 m_items->setVisible(false);
487 487 m_layout->invalidate();
488 488 }
489 489
490 490 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
491 491 {
492 492 if (m_series.contains(series)) {
493 493 m_series.removeOne(series);
494 494 }
495 495
496 496 // Find out, which markers to remove
497 497 QList<QLegendMarker *> removed;
498 498 foreach (QLegendMarker *m, m_markers) {
499 499 if (m->series() == series) {
500 500 removed << m;
501 501 }
502 502 }
503 503 removeMarkers(removed);
504 504
505 505 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
506 506 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
507 507
508 508 m_layout->invalidate();
509 509 }
510 510
511 511 void QLegendPrivate::handleSeriesVisibleChanged()
512 512 {
513 513 QAbstractSeries *series = qobject_cast<QAbstractSeries *> (sender());
514 514 Q_ASSERT(series);
515 515
516 516 foreach (QLegendMarker *marker, m_markers) {
517 517 if (marker->series() == series) {
518 518 marker->setVisible(series->isVisible());
519 519 }
520 520 }
521 m_layout->invalidate();
521
522 if (m_chart->isVisible())
523 m_layout->invalidate();
522 524 }
523 525
524 526 void QLegendPrivate::handleCountChanged()
525 527 {
526 528 // Here we handle the changes in marker count.
527 529 // Can happen for example when pieslice(s) have been added to or removed from pieseries.
528 530
529 531 QAbstractSeriesPrivate *series = qobject_cast<QAbstractSeriesPrivate *> (sender());
530 532 QList<QLegendMarker *> createdMarkers = series->createLegendMarkers(q_ptr);
531 533
532 534 // Find out removed markers and created markers
533 535 QList<QLegendMarker *> removedMarkers;
534 536 foreach (QLegendMarker *oldMarker, m_markers) {
535 537 // we have marker, which is related to sender.
536 538 if (oldMarker->series() == series->q_ptr) {
537 539 bool found = false;
538 540 foreach(QLegendMarker *newMarker, createdMarkers) {
539 541 // New marker considered existing if:
540 542 // - d_ptr->relatedObject() is same for both markers.
541 543 if (newMarker->d_ptr->relatedObject() == oldMarker->d_ptr->relatedObject()) {
542 544 // Delete the new marker, since we already have existing marker, that might be connected on user side.
543 545 found = true;
544 546 createdMarkers.removeOne(newMarker);
545 547 delete newMarker;
546 548 }
547 549 }
548 550 if (!found) {
549 551 // No related object found for marker, add to removedMarkers list
550 552 removedMarkers << oldMarker;
551 553 }
552 554 }
553 555 }
554 556
555 557 removeMarkers(removedMarkers);
556 558 decorateMarkers(createdMarkers);
557 559 addMarkers(createdMarkers);
558 560
559 561 q_ptr->layout()->invalidate();
560 562 }
561 563
562 564 void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers)
563 565 {
564 566 foreach (QLegendMarker *marker, markers) {
565 567 m_items->addToGroup(marker->d_ptr.data()->item());
566 568 m_markers << marker;
567 569 m_markerHash.insert(marker->d_ptr->item(), marker);
568 570 }
569 571 }
570 572
571 573 void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers)
572 574 {
573 575 foreach (QLegendMarker *marker, markers) {
574 576 marker->d_ptr->item()->setVisible(false);
575 577 m_items->removeFromGroup(marker->d_ptr->item());
576 578 m_markers.removeOne(marker);
577 579 m_markerHash.remove(marker->d_ptr->item());
578 580 delete marker;
579 581 }
580 582 }
581 583
582 584 void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers)
583 585 {
584 586 foreach (QLegendMarker *marker, markers) {
585 587 marker->setFont(m_font);
586 588 marker->setLabelBrush(m_labelBrush);
587 589 }
588 590 }
589 591
590 592
591 593 #include "moc_qlegend.cpp"
592 594 #include "moc_qlegend_p.cpp"
593 595
594 596 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now