##// END OF EJS Templates
added roundness to legend background
sauimone -
r1453:f60a3095bd58
parent child
Show More
@@ -1,223 +1,224
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial 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 "mainwidget.h"
22 22 #include <QChart>
23 23 #include <QChartView>
24 24 #include <QPushButton>
25 25 #include <QLabel>
26 26 #include <QDebug>
27 27 #include <QBarSet>
28 28 #include <QBarSeries>
29 29 #include <QLegend>
30 30 #include <QFormLayout>
31 31
32 32 QTCOMMERCIALCHART_USE_NAMESPACE
33 33
34 34 MainWidget::MainWidget(QWidget *parent) :
35 35 QWidget(parent)
36 36 {
37 37 // Create buttons for ui
38 38 m_buttonLayout = new QGridLayout();
39 39 QPushButton *detachLegendButton = new QPushButton("detach legend");
40 40 connect(detachLegendButton, SIGNAL(clicked()), this, SLOT(detachLegend()));
41 41 m_buttonLayout->addWidget(detachLegendButton, 0, 0);
42 42 QPushButton *attachLegendButton = new QPushButton("attach legend");
43 43 connect(attachLegendButton, SIGNAL(clicked()), this, SLOT(attachLegend()));
44 44 m_buttonLayout->addWidget(attachLegendButton, 1, 0);
45 45
46 46 QPushButton *addSetButton = new QPushButton("add barset");
47 47 connect(addSetButton, SIGNAL(clicked()), this, SLOT(addBarset()));
48 48 m_buttonLayout->addWidget(addSetButton, 2, 0);
49 49 QPushButton *removeBarsetButton = new QPushButton("remove barset");
50 50 connect(removeBarsetButton, SIGNAL(clicked()), this, SLOT(removeBarset()));
51 51 m_buttonLayout->addWidget(removeBarsetButton, 3, 0);
52 52
53 53 QPushButton *leftButton = new QPushButton("Align legend left");
54 54 connect(leftButton, SIGNAL(clicked()), this, SLOT(setLegendLeft()));
55 55 m_buttonLayout->addWidget(leftButton, 4, 0);
56 56
57 57 QPushButton *rightButton = new QPushButton("Align legend right");
58 58 connect(rightButton, SIGNAL(clicked()), this, SLOT(setLegendRight()));
59 59 m_buttonLayout->addWidget(rightButton, 5, 0);
60 60
61 61 QPushButton *topButton = new QPushButton("Align legend top");
62 62 connect(topButton, SIGNAL(clicked()), this, SLOT(setLegendTop()));
63 63 m_buttonLayout->addWidget(topButton, 6, 0);
64 64
65 65 QPushButton *bottomButton = new QPushButton("Align legend bottom");
66 66 connect(bottomButton, SIGNAL(clicked()), this, SLOT(setLegendBottom()));
67 67 m_buttonLayout->addWidget(bottomButton, 7, 0);
68 68
69 69 m_legendPosX = new QDoubleSpinBox();
70 70 m_legendPosY = new QDoubleSpinBox();
71 71 m_legendWidth = new QDoubleSpinBox();
72 72 m_legendHeight = new QDoubleSpinBox();
73 73
74 74 connect(m_legendPosX, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
75 75 connect(m_legendPosY, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
76 76 connect(m_legendWidth, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
77 77 connect(m_legendHeight, SIGNAL(valueChanged(double)), this, SLOT(updateLegendLayout()));
78 78
79 79 QFormLayout* legendLayout = new QFormLayout();
80 80 legendLayout->addRow("Horizontal position", m_legendPosX);
81 81 legendLayout->addRow("Vertical position", m_legendPosY);
82 82 legendLayout->addRow("Width", m_legendWidth);
83 83 legendLayout->addRow("Height", m_legendHeight);
84 84 m_legendSettings = new QGroupBox("Detached legend");
85 85 m_legendSettings->setLayout(legendLayout);
86 86 m_buttonLayout->addWidget(m_legendSettings);
87 87 m_legendSettings->setVisible(false);
88 88
89 89 // Create chart view with the chart
90 90 m_chart = new QChart();
91 91 m_chartView = new QChartView(m_chart, this);
92 92
93 93 // Create layout for grid and detached legend
94 94 m_mainLayout = new QGridLayout();
95 95 m_mainLayout->addLayout(m_buttonLayout, 0, 0);
96 96 m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
97 97 setLayout(m_mainLayout);
98 98
99 99 createSeries();
100 100 }
101 101
102 102 void MainWidget::createSeries()
103 103 {
104 104 m_series = new QBarSeries();
105 105 addBarset();
106 106 addBarset();
107 107 addBarset();
108 108 addBarset();
109 109
110 110 m_chart->addSeries(m_series);
111 111 m_chart->setTitle("Legend detach example");
112 112 //![1]
113 113 m_chart->legend()->setVisible(true);
114 114 m_chart->legend()->setAlignment(Qt::AlignBottom);
115 115 //![1]
116 116
117 117 m_chart->axisY()->setNiceNumbersEnabled(true);
118 118 m_chartView->setRenderHint(QPainter::Antialiasing);
119 119 }
120 120
121 121 void MainWidget::showLegendSpinbox()
122 122 {
123 123 m_legendSettings->setVisible(true);
124 124 QRectF chartViewRect = m_chartView->rect();
125 125 QRectF legendRect = m_chart->legend()->boundingRect();
126 126
127 127 m_legendPosX->setMinimum(0);
128 128 m_legendPosX->setMaximum(chartViewRect.width());
129 129 m_legendPosX->setValue(150);
130 130
131 131 m_legendPosY->setMinimum(0);
132 132 m_legendPosY->setMaximum(chartViewRect.height());
133 133 m_legendPosY->setValue(150);
134 134
135 135 m_legendWidth->setMinimum(0);
136 136 m_legendWidth->setMaximum(chartViewRect.width());
137 137 m_legendWidth->setValue(150);
138 138
139 139 m_legendHeight->setMinimum(0);
140 140 m_legendHeight->setMaximum(chartViewRect.height());
141 141 m_legendHeight->setValue(75);
142 142 }
143 143
144 144 void MainWidget::hideLegendSpinbox()
145 145 {
146 146 m_legendSettings->setVisible(false);
147 147 }
148 148
149 149
150 150 void MainWidget::detachLegend()
151 151 {
152 152 //![2]
153 153 QLegend *legend = m_chart->legend();
154 154 legend->detachFromChart();
155 155
156 156 m_chart->legend()->setBackgroundVisible(true);
157 157 m_chart->legend()->setBrush(QBrush(QColor(128,128,128,128)));
158 m_chart->legend()->setPen(QPen(QColor(192,192,192,192)));
158 159 //![2]
159 160
160 161 showLegendSpinbox();
161 162 updateLegendLayout();
162 163 update();
163 164 }
164 165
165 166
166 167 void MainWidget::attachLegend()
167 168 {
168 169 //![3]
169 170 QLegend *legend = m_chart->legend();
170 171 legend->attachToChart();
171 172 m_chart->legend()->setBackgroundVisible(false);
172 173 //![3]
173 174
174 175 hideLegendSpinbox();
175 176 update();
176 177 }
177 178
178 179 void MainWidget::addBarset()
179 180 {
180 181 QBarSet *barSet = new QBarSet(QString("set ") + QString::number(m_series->barsetCount()));
181 182 qreal delta = m_series->barsetCount() * 0.1;
182 183 *barSet << QPointF(0.0 + delta, 1 + delta) << QPointF(1.0 + delta, 2 + delta) << QPointF(2.0 + delta, 3 + delta) << QPointF(3.0 + delta, 4 + delta);
183 184 m_series->append(barSet);
184 185 }
185 186
186 187 void MainWidget::removeBarset()
187 188 {
188 189 QList<QBarSet*> sets = m_series->barSets();
189 190 if (sets.count() > 0) {
190 191 m_series->remove(sets.at(sets.count()-1));
191 192 }
192 193 }
193 194
194 195 void MainWidget::setLegendLeft()
195 196 {
196 197 m_chart->legend()->setAlignment(Qt::AlignLeft);
197 198 }
198 199
199 200 void MainWidget::setLegendRight()
200 201 {
201 202 m_chart->legend()->setAlignment(Qt::AlignRight);
202 203 }
203 204
204 205 void MainWidget::setLegendTop()
205 206 {
206 207 m_chart->legend()->setAlignment(Qt::AlignTop);
207 208 }
208 209
209 210 void MainWidget::setLegendBottom()
210 211 {
211 212 m_chart->legend()->setAlignment(Qt::AlignBottom);
212 213 }
213 214
214 215 void MainWidget::updateLegendLayout()
215 216 {
216 217 //![4]
217 218 m_chart->legend()->setGeometry(m_legendPosX->value()
218 219 ,m_legendPosY->value()
219 220 ,m_legendWidth->value()
220 221 ,m_legendHeight->value());
221 222 m_chart->legend()->update();
222 223 //![4]
223 224 }
@@ -1,740 +1,746
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial 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
27 27 #include "legendmarker_p.h"
28 28 #include "qxyseries.h"
29 29 #include "qlineseries.h"
30 30 #include "qareaseries.h"
31 31 #include "qscatterseries.h"
32 32 #include "qsplineseries.h"
33 33 #include "qbarseries.h"
34 34 #include "qstackedbarseries.h"
35 35 #include "qpercentbarseries.h"
36 36 #include "qbarset.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieseries_p.h"
39 39 #include "qpieslice.h"
40 40 #include "chartpresenter_p.h"
41 41 #include <QPainter>
42 42 #include <QPen>
43 43 #include <QTimer>
44 44
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 48
49 49 /*!
50 50 \class QLegend
51 51 \brief part of QtCommercial chart API.
52 52 \mainclass
53 53
54 54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 56 handle the drawing manually.
57 57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58 58
59 59 \image examples_percentbarchart_legend.png
60 60
61 61 \sa QChart
62 62 */
63 63 /*!
64 64 \qmlclass Legend QLegend
65 65 \brief Legend is part of QtCommercial Chart QML API.
66 66
67 67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
68 68 series have been changed. Legend is referenced via ChartView class. For example:
69 69 \code
70 70 ChartView {
71 71 legend.visible: true
72 72 legend.alignment: Qt.AlignBottom
73 73 // Add a few series...
74 74 }
75 75 \endcode
76 76
77 77 \image examples_percentbarchart_legend.png
78 78 */
79 79
80 80 /*!
81 81 \property QLegend::alignment
82 82 \brief The alignment of the legend.
83 83
84 84 Legend paints on the defined position in the chart. The following alignments are supported:
85 85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
86 86 */
87 87 /*!
88 88 \qmlproperty Qt.Alignment Legend::alignment
89 89 \brief The alignment of the legend.
90 90
91 91 Legend paints on the defined position in the chart. The following alignments are supported:
92 92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
93 93 */
94 94
95 95 /*!
96 96 \property QLegend::backgroundVisible
97 97 Whether the legend background is visible or not.
98 98 */
99 99 /*!
100 100 \qmlproperty bool Legend::backgroundVisible
101 101 Whether the legend background is visible or not.
102 102 */
103 103
104 104 /*!
105 105 \property QLegend::color
106 106 The color of the legend, i.e. the background color.
107 107 */
108 108 /*!
109 109 \qmlproperty color Legend::color
110 110 The color of the legend, i.e. the background color.
111 111 */
112 112
113 113 /*!
114 114 \property QLegend::borderColor
115 115 The border color of the legend, i.e. the line color.
116 116 */
117 117 /*!
118 118 \qmlproperty color Legend::borderColor
119 119 The border color of the legend, i.e. the line color.
120 120 */
121 121
122 122 /*!
123 123 \fn void QLegend::alignmentChanged(Qt::Alignment)
124 124 Emitted when the \a alignment of the legend changes.
125 125 */
126 126
127 127 /*!
128 128 \fn void QLegend::backgroundVisibleChanged(bool)
129 129 The visibility of the legend background changed to \a visible.
130 130 */
131 131
132 132 /*!
133 133 \fn void QLegend::colorChanged(QColor)
134 134 The color of the legend background changed to \a color.
135 135 */
136 136
137 137 /*!
138 138 \fn void QLegend::borderColorChanged(QColor)
139 139 The border color of the legend background changed to \a color.
140 140 */
141 141
142 142 /*!
143 143 \fn qreal QLegend::minWidth() const
144 144 Returns minimum width of the legend
145 145 */
146 146
147 147 /*!
148 148 \fn qreal QLegend::minHeight() const
149 149 Returns minimum height of the legend
150 150 */
151 151
152 152 /*!
153 153 Constructs the legend object and sets the parent to \a parent
154 154 */
155 155
156 156 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
157 157 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
158 158 {
159 159 setZValue(ChartPresenter::LegendZValue);
160 160 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
161 161 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
162 162 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
163 163 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
164 164 }
165 165
166 166 /*!
167 167 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
168 168 */
169 169 QLegend::~QLegend()
170 170 {
171 171 }
172 172
173 173 /*!
174 174 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
175 175 */
176 176
177 177 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
178 178 {
179 179 Q_UNUSED(option)
180 180 Q_UNUSED(widget)
181 181 if(!d_ptr->m_backgroundVisible) return;
182 182
183 183 painter->setOpacity(opacity());
184 184 painter->setPen(d_ptr->m_pen);
185 185 painter->setBrush(d_ptr->m_brush);
186 painter->drawRect(boundingRect());
186 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
187 187 }
188 188
189 189 /*!
190 190 Bounding rect of legend.
191 191 */
192 192
193 193 QRectF QLegend::boundingRect() const
194 194 {
195 195 return d_ptr->m_rect;
196 196 }
197 197
198 198 /*!
199 199 Sets the \a brush of legend. Brush affects the background of legend.
200 200 */
201 201 void QLegend::setBrush(const QBrush &brush)
202 202 {
203 203 if (d_ptr->m_brush != brush) {
204 204 d_ptr->m_brush = brush;
205 205 update();
206 206 }
207 207 }
208 208
209 209 /*!
210 210 Returns the brush used by legend.
211 211 */
212 212 QBrush QLegend::brush() const
213 213 {
214 214 return d_ptr->m_brush;
215 215 }
216 216
217 217 void QLegend::setColor(QColor color)
218 218 {
219 219 QBrush b = d_ptr->m_brush;
220 220 if (b.color() != color) {
221 221 b.setColor(color);
222 222 setBrush(b);
223 223 emit colorChanged(color);
224 224 }
225 225 }
226 226
227 227 QColor QLegend::color()
228 228 {
229 229 return d_ptr->m_brush.color();
230 230 }
231 231
232 232 /*!
233 233 Sets the \a pen of legend. Pen affects the legend borders.
234 234 */
235 235 void QLegend::setPen(const QPen &pen)
236 236 {
237 237 if (d_ptr->m_pen != pen) {
238 238 d_ptr->m_pen = pen;
239 239 update();
240 240 }
241 241 }
242 242
243 243 /*!
244 244 Returns the pen used by legend
245 245 */
246 246
247 247 QPen QLegend::pen() const
248 248 {
249 249 return d_ptr->m_pen;
250 250 }
251 251
252 252 void QLegend::setBorderColor(QColor color)
253 253 {
254 254 QPen p = d_ptr->m_pen;
255 255 if (p.color() != color) {
256 256 p.setColor(color);
257 257 setPen(p);
258 258 emit borderColorChanged(color);
259 259 }
260 260 }
261 261
262 262 QColor QLegend::borderColor()
263 263 {
264 264 return d_ptr->m_pen.color();
265 265 }
266 266
267 267 void QLegend::setAlignment(Qt::Alignment alignment)
268 268 {
269 269 if(d_ptr->m_alignment!=alignment) {
270 270 d_ptr->m_alignment = alignment;
271 271 d_ptr->updateLayout();
272 272 alignmentChanged(alignment);
273 273 }
274 274 }
275 275
276 276 Qt::Alignment QLegend::alignment() const
277 277 {
278 278 return d_ptr->m_alignment;
279 279 }
280 280
281 281 /*!
282 282 Detaches the legend from chart. Chart won't change layout of the legend.
283 283 */
284 284 void QLegend::detachFromChart()
285 285 {
286 286 d_ptr->m_attachedToChart = false;
287 287 }
288 288
289 289 /*!
290 290 Attaches the legend to chart. Chart may change layout of the legend.
291 291 */
292 292 void QLegend::attachToChart()
293 293 {
294 294 d_ptr->attachToChart();
295 295 }
296 296
297 297 /*!
298 298 Returns true, if legend is attached to chart.
299 299 */
300 300 bool QLegend::isAttachedToChart()
301 301 {
302 302 return d_ptr->m_attachedToChart;
303 303 }
304 304
305 305 /*!
306 306 Sets the legend's scrolling offset to value defined by \a point.
307 307 */
308 308 void QLegend::setOffset(const QPointF& point)
309 309 {
310 310 d_ptr->setOffset(point.x(),point.y());
311 311 }
312 312
313 313 /*!
314 314 Returns the legend's scrolling offset.
315 315 */
316 316 QPointF QLegend::offset() const
317 317 {
318 318 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
319 319 }
320 320
321 321 /*!
322 322 Sets the visibility of legend background to \a visible
323 323 */
324 324 void QLegend::setBackgroundVisible(bool visible)
325 325 {
326 326 if(d_ptr->m_backgroundVisible != visible) {
327 327 d_ptr->m_backgroundVisible = visible;
328 328 update();
329 329 emit backgroundVisibleChanged(visible);
330 330 }
331 331 }
332 332
333 333 /*!
334 334 Returns the visibility of legend background
335 335 */
336 336 bool QLegend::isBackgroundVisible() const
337 337 {
338 338 return d_ptr->m_backgroundVisible;
339 339 }
340 340
341 341 /*!
342 342 \internal \a event see QGraphicsWidget for details
343 343 */
344 344 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
345 345 {
346 346 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
347 347 QGraphicsWidget::resizeEvent(event);
348 348 if(d_ptr->m_rect != rect) {
349 349 d_ptr->m_rect = rect;
350 350 d_ptr->updateLayout();
351 351 }
352 352 }
353 353
354 354 /*!
355 355 \internal \a event see QGraphicsWidget for details
356 356 */
357 357 void QLegend::hideEvent(QHideEvent *event)
358 358 {
359 359 QGraphicsWidget::hideEvent(event);
360 360 setEnabled(false);
361 361 d_ptr->updateLayout();
362 362 }
363 363
364 364 /*!
365 365 \internal \a event see QGraphicsWidget for details
366 366 */
367 367 void QLegend::showEvent(QShowEvent *event)
368 368 {
369 369 QGraphicsWidget::showEvent(event);
370 370 setEnabled(true);
371 371 d_ptr->updateLayout();
372 372 }
373 373
374 374 qreal QLegend::minWidth() const
375 375 {
376 376 return d_ptr->m_minWidth;
377 377 }
378 378
379 379 qreal QLegend::minHeight() const
380 380 {
381 381 return d_ptr->m_minHeight;
382 382 }
383 383
384 384 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
385 385
386 386 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
387 387 q_ptr(q),
388 388 m_presenter(presenter),
389 389 m_chart(chart),
390 390 m_markers(new QGraphicsItemGroup(q)),
391 391 m_alignment(Qt::AlignTop),
392 392 m_offsetX(0),
393 393 m_offsetY(0),
394 394 m_minWidth(0),
395 395 m_minHeight(0),
396 396 m_width(0),
397 397 m_height(0),
398 m_diameter(5),
398 399 m_attachedToChart(true),
399 400 m_backgroundVisible(false)
400 401 {
401 402
402 403 }
403 404
404 405 QLegendPrivate::~QLegendPrivate()
405 406 {
406 407
407 408 }
408 409
409 410 void QLegendPrivate::setOffset(qreal x, qreal y)
410 411 {
411 412 bool scrollHorizontal = true;
412 413 switch(m_alignment) {
413 414 case Qt::AlignTop:
414 415 case Qt::AlignBottom: {
415 416 scrollHorizontal = true;
416 417 break;
417 418 }
418 419 case Qt::AlignLeft:
419 420 case Qt::AlignRight: {
420 421 scrollHorizontal = false;
421 422 break;
422 423 }
423 424 }
424 425
425 426 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
426 427 if (!m_attachedToChart) {
427 428 scrollHorizontal = !scrollHorizontal;
428 429 }
429 430
430 431 // Limit offset between m_minOffset and m_maxOffset
431 432 if (scrollHorizontal) {
432 433 if(m_width<=m_rect.width()) return;
433 434
434 435 if (x != m_offsetX) {
435 436 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
436 437 m_markers->setPos(-m_offsetX,m_rect.top());
437 438 }
438 439 } else {
439 440 if(m_height<=m_rect.height()) return;
440 441
441 442 if (y != m_offsetY) {
442 443 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
443 444 m_markers->setPos(m_rect.left(),-m_offsetY);
444 445 }
445 446 }
446 447 }
447 448
448 449
449 450 void QLegendPrivate::updateLayout()
450 451 {
451 452 if (!m_attachedToChart) {
452 453 updateDetachedLayout();
453 454 return;
454 455 }
455 456
456 457 m_offsetX=0;
457 458 QList<QGraphicsItem *> items = m_markers->childItems();
458 459
459 460 if(items.isEmpty()) return;
460 461
461 462 m_minWidth=0;
462 463 m_minHeight=0;
463 464
464 465 switch(m_alignment) {
465 466
466 467 case Qt::AlignTop:
467 468 case Qt::AlignBottom: {
468 469 QPointF point = m_rect.topLeft();
469 470 m_width = 0;
470 471 foreach (QGraphicsItem *item, items) {
471 472 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
472 473 const QRectF& rect = item->boundingRect();
473 474 qreal w = rect.width();
474 475 m_minWidth=qMax(m_minWidth,w);
475 476 m_minHeight=qMax(m_minHeight,rect.height());
476 477 m_width+=w;
477 478 point.setX(point.x() + w);
478 479 }
479 480 if(m_width<m_rect.width()) {
480 481 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
481 482 }
482 483 else {
483 484 m_markers->setPos(m_rect.topLeft());
484 485 }
485 486 m_height=m_minHeight;
486 487 }
487 488 break;
488 489 case Qt::AlignLeft:
489 490 case Qt::AlignRight: {
490 491 QPointF point = m_rect.topLeft();
491 492 m_height = 0;
492 493 foreach (QGraphicsItem *item, items) {
493 494 item->setPos(point);
494 495 const QRectF& rect = item->boundingRect();
495 496 qreal h = rect.height();
496 497 m_minWidth=qMax(m_minWidth,rect.width());
497 498 m_minHeight=qMax(m_minHeight,h);
498 499 m_height+=h;
499 500 point.setY(point.y() + h);
500 501 }
501 502 if(m_height<m_rect.height()) {
502 503 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
503 504 }
504 505 else {
505 506 m_markers->setPos(m_rect.topLeft());
506 507 }
507 508 m_width=m_minWidth;
508 509 }
509 510 break;
510 511 }
511 512
512 513 m_minOffsetX = 0;
513 514 m_minOffsetY = 0;
514 515 m_maxOffsetX = m_width - m_rect.width();
515 516 m_maxOffsetY = m_height - m_rect.height();
516 517
517 518 m_presenter->updateLayout();
518 519 }
519 520
520 521 void QLegendPrivate::updateDetachedLayout()
521 522 {
522 523 // Detached layout is different.
523 524 // In detached mode legend may have multiple rows and columns, so layout calculations
524 525 // differ a log from attached mode.
525 526 // Also the scrolling logic is bit different.
526 527 m_offsetX=0;
527 528 m_offsetY=0;
528 529 QList<QGraphicsItem *> items = m_markers->childItems();
529 530
530 531 if(items.isEmpty()) return;
531 532
532 533 m_minWidth = 0;
533 534 m_minHeight = 0;
534 535
535 536 switch (m_alignment) {
536 537 case Qt::AlignTop: {
537 538 QPointF point = m_rect.topLeft();
538 539 m_width = 0;
539 540 m_height = 0;
540 541 for (int i=0; i<items.count(); i++) {
541 542 QGraphicsItem *item = items.at(i);
542 543 const QRectF& rect = item->boundingRect();
543 544 qreal w = rect.width();
544 545 qreal h = rect.height();
545 546 m_minWidth = qMax(m_minWidth,w);
546 547 m_minHeight = qMax(m_minHeight,rect.height());
547 548 m_height = qMax(m_height,h);
548 549 item->setPos(point.x(),point.y());
549 550 point.setX(point.x() + w);
550 551 if (point.x() + w > m_rect.topLeft().x() + m_rect.width()) {
551 552 // Next item would go off rect.
552 553 point.setX(m_rect.topLeft().x());
553 554 point.setY(point.y() + h);
554 555 if (i+1 < items.count()) {
555 556 m_height += h;
556 557 }
557 558 }
558 559 }
559 560 m_markers->setPos(m_rect.topLeft());
560 561 m_width = m_minWidth;
561 562
562 563 m_minOffsetX = 0;
563 564 m_minOffsetY = 0;
564 565 m_maxOffsetX = m_width - m_rect.width();
565 566 m_maxOffsetY = m_height - m_rect.height();
566 567 }
567 568 break;
568 569 case Qt::AlignBottom: {
569 570 QPointF point = m_rect.bottomLeft();
570 571 m_width = 0;
571 572 m_height = 0;
572 573 for (int i=0; i<items.count(); i++) {
573 574 QGraphicsItem *item = items.at(i);
574 575 const QRectF& rect = item->boundingRect();
575 576 qreal w = rect.width();
576 577 qreal h = rect.height();
577 578 m_minWidth = qMax(m_minWidth,w);
578 579 m_minHeight = qMax(m_minHeight,rect.height());
579 580 m_height = qMax(m_height,h);
580 581 item->setPos(point.x(),point.y() - h);
581 582 point.setX(point.x() + w);
582 583 if (point.x() + w > m_rect.bottomLeft().x() + m_rect.width()) {
583 584 // Next item would go off rect.
584 585 point.setX(m_rect.bottomLeft().x());
585 586 point.setY(point.y() - h);
586 587 if (i+1 < items.count()) {
587 588 m_height += h;
588 589 }
589 590 }
590 591 }
591 592 m_markers->setPos(m_rect.topLeft());
592 593 m_width = m_minWidth;
593 594
594 595 m_minOffsetX = 0;
595 596 m_minOffsetY = qMin(m_rect.topLeft().y(), m_rect.topLeft().y() - m_height + m_rect.height());
596 597 m_maxOffsetX = m_width - m_rect.width();
597 598 m_maxOffsetY = 0;
598 599 }
599 600 break;
600 601 case Qt::AlignLeft: {
601 602 QPointF point = m_rect.topLeft();
602 603 m_width = 0;
603 604 m_height = 0;
604 605 qreal maxWidth = 0;
605 606 for (int i=0; i<items.count(); i++) {
606 607 QGraphicsItem *item = items.at(i);
607 608 const QRectF& rect = item->boundingRect();
608 609 qreal w = rect.width();
609 610 qreal h = rect.height();
610 611 m_minWidth = qMax(m_minWidth,rect.width());
611 612 m_minHeight = qMax(m_minHeight,h);
612 613 maxWidth = qMax(maxWidth,w);
613 614 item->setPos(point.x(),point.y());
614 615 point.setY(point.y() + h);
615 616 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
616 617 // Next item would go off rect.
617 618 point.setX(point.x() + maxWidth);
618 619 point.setY(m_rect.topLeft().y());
619 620 if (i+1 < items.count()) {
620 621 m_width += maxWidth;
621 622 maxWidth = 0;
622 623 }
623 624 }
624 625 }
625 626 m_width += maxWidth;
626 627 m_markers->setPos(m_rect.topLeft());
627 628 m_height = m_minHeight;
628 629
629 630 m_minOffsetX = 0;
630 631 m_minOffsetY = 0;
631 632 m_maxOffsetX = m_width - m_rect.width();
632 633 m_maxOffsetY = m_height - m_rect.height();
633 634 }
634 635 break;
635 636 case Qt::AlignRight: {
636 637 QPointF point = m_rect.topRight();
637 638 m_width = 0;
638 639 m_height = 0;
639 640 qreal maxWidth = 0;
640 641 for (int i=0; i<items.count(); i++) {
641 642 QGraphicsItem *item = items.at(i);
642 643 const QRectF& rect = item->boundingRect();
643 644 qreal w = rect.width();
644 645 qreal h = rect.height();
645 646 m_minWidth = qMax(m_minWidth,rect.width());
646 647 m_minHeight = qMax(m_minHeight,h);
647 648 maxWidth = qMax(maxWidth,w);
648 649 item->setPos(point.x() - w,point.y());
649 650 point.setY(point.y() + h);
650 651 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
651 652 // Next item would go off rect.
652 653 point.setX(point.x() - maxWidth);
653 654 point.setY(m_rect.topLeft().y());
654 655 if (i+1 < items.count()) {
655 656 m_width += maxWidth;
656 657 maxWidth = 0;
657 658 }
658 659 }
659 660 }
660 661 m_width += maxWidth;
661 662 m_markers->setPos(m_rect.topLeft());
662 663 m_height = m_minHeight;
663 664
664 665 m_minOffsetX = qMin(m_rect.topLeft().x(), m_rect.topLeft().x() - m_width + m_rect.width());
665 666 m_minOffsetY = 0;
666 667 m_maxOffsetX = 0;
667 668 m_maxOffsetY = m_height - m_rect.height();
668 669 }
669 670 break;
670 671 default:
671 672 break;
672 673 }
673 674 }
674 675
675 676 void QLegendPrivate::attachToChart()
676 677 {
677 678 m_attachedToChart = true;
678 679 q_ptr->setParent(m_chart);
679 680 }
680 681
682 int QLegendPrivate::roundness(qreal size)
683 {
684 return 100*m_diameter/int(size);
685 }
686
681 687 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
682 688 {
683 689 Q_UNUSED(domain)
684 690
685 691 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
686 692 foreach(LegendMarker* marker, markers)
687 693 m_markers->addToGroup(marker);
688 694
689 695 if(series->type() == QAbstractSeries::SeriesTypePie) {
690 696 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
691 697 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
692 698 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
693 699 }
694 700
695 701 updateLayout();
696 702 }
697 703
698 704 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
699 705 {
700 706 QList<QGraphicsItem *> items = m_markers->childItems();
701 707
702 708 foreach (QGraphicsItem *markers, items) {
703 709 LegendMarker *marker = static_cast<LegendMarker*>(markers);
704 710 if (marker->series() == series) {
705 711 delete marker;
706 712 }
707 713 }
708 714
709 715 if(series->type() == QAbstractSeries::SeriesTypePie)
710 716 {
711 717 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
712 718 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
713 719 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
714 720 }
715 721
716 722 updateLayout();
717 723 }
718 724
719 725 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
720 726 {
721 727 // TODO: find out which markers are are added or removed. Update them
722 728 // TODO: better implementation
723 729 handleSeriesRemoved(series);
724 730 Domain domain;
725 731 handleSeriesAdded(series, &domain);
726 732 }
727 733
728 734 void QLegendPrivate::handleUpdatePieSeries()
729 735 {
730 736 //TODO: reimplement to be optimal
731 737 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
732 738 Q_ASSERT(series);
733 739 handleSeriesRemoved(series);
734 740 handleSeriesAdded(series, 0);
735 741 }
736 742
737 743 #include "moc_qlegend.cpp"
738 744 #include "moc_qlegend_p.cpp"
739 745
740 746 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,87 +1,89
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial 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 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QLEGEND_P_H
31 31 #define QLEGEND_P_H
32 32
33 33 #include "qlegend.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class QChart;
38 38 class ChartPresenter;
39 39 class QAbstractSeries;
40 40
41 41 class QLegendPrivate : public QObject
42 42 {
43 43 Q_OBJECT
44 44 public:
45 45 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
46 46 ~QLegendPrivate();
47 47
48 48 void setOffset(qreal x, qreal y);
49 49 void updateLayout();
50 50 void updateDetachedLayout();
51 51 void attachToChart();
52 int roundness(qreal size);
52 53
53 54 public Q_SLOTS:
54 55 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
55 56 void handleSeriesRemoved(QAbstractSeries *series);
56 57 void handleSeriesUpdated(QAbstractSeries *series);
57 58 void handleUpdatePieSeries(); //TODO remove this function
58 59
59 60 private:
60 61 QLegend *q_ptr;
61 62 ChartPresenter *m_presenter;
62 63 QChart* m_chart;
63 64 QGraphicsItemGroup* m_markers;
64 65 Qt::Alignment m_alignment;
65 66 QBrush m_brush;
66 67 QPen m_pen;
67 68 QRectF m_rect;
68 69 qreal m_offsetX;
69 70 qreal m_offsetY;
70 71 qreal m_minOffsetX;
71 72 qreal m_minOffsetY;
72 73 qreal m_maxOffsetX;
73 74 qreal m_maxOffsetY;
74 75 qreal m_minWidth;
75 76 qreal m_minHeight;
76 77 qreal m_width;
77 78 qreal m_height;
79 qreal m_diameter;
78 80 bool m_attachedToChart;
79 81 bool m_backgroundVisible;
80 82
81 83 friend class QLegend;
82 84
83 85 };
84 86
85 87 QTCOMMERCIALCHART_END_NAMESPACE
86 88
87 89 #endif
General Comments 0
You need to be logged in to leave comments. Login now