##// END OF EJS Templates
Fix title font resize does not invalidate layout
Michal Klocek -
r2088:5149de44ec86
parent child
Show More
@@ -1,261 +1,260
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 "chartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxis_p.h"
25 25 #include "charttitle_p.h"
26 26 #include "chartbackground_p.h"
27 27 #include "legendmarker_p.h"
28 #include <QDebug>
29 28
30 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 30
32 31 static const qreal golden_ratio = 0.25;
33 32
34 33 ChartLayout::ChartLayout(ChartPresenter* presenter):
35 34 m_presenter(presenter),
36 35 m_margins(20,20,20,20),
37 36 m_minChartRect(0,0,200,200)
38 37 {
39 38
40 39 }
41 40
42 41 ChartLayout::~ChartLayout()
43 42 {
44 43
45 44 }
46 45
47 46 void ChartLayout::setGeometry(const QRectF& rect)
48 47 {
49 48 if (!rect.isValid())
50 49 return;
51 50
52 51 QList<ChartAxis*> axes = m_presenter->axisItems();
53 52 ChartTitle* title = m_presenter->titleElement();
54 53 QLegend* legend = m_presenter->legend();
55 54 ChartBackground* background = m_presenter->backgroundElement();
56 55
57 56 QRectF contentGeometry = calculateBackgroundGeometry(rect,background);
58 57
59 58 contentGeometry = calculateContentGeometry(contentGeometry);
60 59
61 60 if (title && title->isVisible()) {
62 61 contentGeometry = calculateTitleGeometry(contentGeometry,title);
63 62 }
64 63
65 64 if (legend->isAttachedToChart() && legend->isVisible()) {
66 65 contentGeometry = calculateLegendGeometry(contentGeometry,legend);
67 66 }
68 67
69 68 calculateChartGeometry(contentGeometry,axes);
70 69
71 70 //TODO remove me
72 71 #ifdef SHOW_LAYOUT
73 72 LayoutDebuger* debuger = LayoutDebuger::instance();
74 73 debuger->reset();
75 74 debuger->setPen(QPen(Qt::red));
76 75 debuger->add(backgroundGeometry,m_presenter->rootItem());
77 76 debuger->add(titleGeometry,m_presenter->rootItem());
78 77 debuger->add(legendGeometry ,m_presenter->rootItem());
79 78 debuger->add(axisGeometry ,m_presenter->rootItem());
80 79 debuger->add(geometry,m_presenter->rootItem());
81 80 foreach(LegendMarker* marker,legend->d_ptr->markers()){
82 81 debuger->add(marker->mapRectToScene(marker->boundingRect()),m_presenter->rootItem());
83 82 }
84 83 #endif
85 84
86 85 QGraphicsLayout::setGeometry(rect);
87 86 }
88 87
89 88 QRectF ChartLayout::calculateContentGeometry(const QRectF& geometry) const
90 89 {
91 90 return geometry.adjusted(m_margins.left(),m_margins.top(),-m_margins.right(),-m_margins.bottom());
92 91 }
93 92
94 93 QRectF ChartLayout::calculateContentMinimum(const QRectF& minimum) const
95 94 {
96 95 return minimum.adjusted(0,0,m_margins.left()+m_margins.right(),m_margins.top() + m_margins.bottom());
97 96 }
98 97
99 98
100 99 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const
101 100 {
102 101 qreal left, top, right, bottom;
103 102 getContentsMargins(&left, &top, &right, &bottom);
104 103 QRectF backgroundGeometry = geometry.adjusted(left,top,-right,-bottom);
105 104 if(background) background->setRect(backgroundGeometry);
106 105 return backgroundGeometry;
107 106 }
108 107
109 108 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF& minimum) const
110 109 {
111 110 qreal left, top, right, bottom;
112 111 getContentsMargins(&left, &top, &right, &bottom);
113 112 return minimum.adjusted(0,0,left + right,top+bottom);
114 113 }
115 114
116 115 QRectF ChartLayout::calculateChartGeometry(const QRectF& geometry, const QList<ChartAxis*>& axes) const
117 116 {
118 117
119 118 QSizeF vertical(0,0);
120 119 QSizeF horizontal(0,0);
121 120
122 121 // check axis size
123 122 foreach(ChartAxis* axis , axes) {
124 123 if(axis->orientation()==Qt::Vertical && axis->isVisible()) {
125 124 vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
126 125 }
127 126 else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
128 127 horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
129 128 }
130 129
131 130 }
132 131
133 132 qreal width = qMin(vertical.width(),geometry.width() * golden_ratio);
134 133
135 134 QRectF rect = geometry.adjusted(width,vertical.height()/2,-horizontal.width()/2,-horizontal.height());
136 135
137 136 m_presenter->setChartsGeometry(rect);
138 137
139 138 foreach(ChartAxis* axis , axes) {
140 139 axis->setGeometry(geometry);
141 140 }
142 141
143 142 return rect;
144 143 }
145 144
146 145 QRectF ChartLayout::calculateAxisMinimum(const QRectF& minimum, const QList<ChartAxis*>& axes) const
147 146 {
148 147 QSizeF vertical(0,0);
149 148 QSizeF horizontal(0,0);
150 149
151 150 // check axis size
152 151 foreach(ChartAxis* axis , axes) {
153 152 if(axis->orientation()==Qt::Vertical && axis->isVisible()){
154 153 vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
155 154 }else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
156 155 horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
157 156 }
158 157 }
159 158 return minimum.adjusted(0,0,horizontal.width()+vertical.width(),horizontal.height() + vertical.height());
160 159 }
161 160
162 161 QRectF ChartLayout::calculateLegendGeometry(const QRectF& geometry,QLegend* legend) const
163 162 {
164 163 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,-1));
165 164 QRectF legendRect;
166 165 QRectF result;
167 166
168 167 switch (legend->alignment()) {
169 168
170 169 case Qt::AlignTop: {
171 170 legendRect = QRectF(geometry.topLeft(),QSizeF(geometry.width(),size.height()));
172 171 result = geometry.adjusted(0,legendRect.height(),0,0);
173 172 break;
174 173 }
175 174 case Qt::AlignBottom: {
176 175 legendRect = QRectF(QPointF(geometry.left(),geometry.bottom()-size.height()),QSizeF(geometry.width(),size.height()));
177 176 result = geometry.adjusted(0,0,0,-legendRect.height());
178 177 break;
179 178 }
180 179 case Qt::AlignLeft: {
181 180 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
182 181 legendRect = QRectF(geometry.topLeft(),QSizeF(width,geometry.height()));
183 182 result = geometry.adjusted(width,0,0,0);
184 183 break;
185 184 }
186 185 case Qt::AlignRight: {
187 186 qreal width = qMin(size.width(),geometry.width()*golden_ratio);
188 187 legendRect = QRectF(QPointF(geometry.right()-width,geometry.top()),QSizeF(width,geometry.height()));
189 188 result = geometry.adjusted(0,0,-width,0);
190 189 break;
191 190 }
192 191 default: {
193 192 legendRect = QRectF(0,0,0,0);
194 193 result = geometry;
195 194 break;
196 195 }
197 196 }
198 197
199 198 legend->setGeometry(legendRect);
200 199
201 200 return result;
202 201 }
203 202
204 203 QRectF ChartLayout::calculateLegendMinimum(const QRectF& geometry,QLegend* legend) const
205 204 {
206 205 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize,QSizeF(-1,-1));
207 206 return geometry.adjusted(0,0,minSize.width(),minSize.height());
208 207 }
209 208
210 209 QRectF ChartLayout::calculateTitleGeometry(const QRectF& geometry,ChartTitle* title) const
211 210 {
212 211 title->setGeometry(geometry);
213 212 QPointF center = geometry.center() - title->boundingRect().center();
214 213 title->setPos(center.x(),title->pos().y());
215 214 return geometry.adjusted(0,title->boundingRect().height(),0,0);
216 215 }
217 216
218 217 QRectF ChartLayout::calculateTitleMinimum(const QRectF& minimum,ChartTitle* title) const
219 218 {
220 219 QSizeF min = title->sizeHint(Qt::MinimumSize);
221 220 return minimum.adjusted(0,0,min.width(),min.height());
222 221 }
223 222
224 223 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
225 224 {
226 225 Q_UNUSED(constraint);
227 226 if(which == Qt::MinimumSize){
228 227 QList<ChartAxis*> axes = m_presenter->axisItems();
229 228 ChartTitle* title = m_presenter->titleElement();
230 229 QLegend* legend = m_presenter->legend();
231 230 QRectF minimumRect(0,0,0,0);
232 231 minimumRect = calculateBackgroundMinimum(minimumRect);
233 232 minimumRect = calculateContentMinimum(minimumRect);
234 233 minimumRect = calculateTitleMinimum(minimumRect,title);
235 234 minimumRect = calculateLegendMinimum(minimumRect,legend);
236 235 minimumRect = calculateAxisMinimum(minimumRect,axes);
237 236 return minimumRect.united(m_minChartRect).size().toSize();
238 237 }else
239 238 return QSize(-1,-1);
240 239 }
241 240
242 241 void ChartLayout::setMargins(const QMargins& margins)
243 242 {
244 243
245 244 if(m_margins != margins){
246 245 m_margins = margins;
247 246 updateGeometry();
248 247 }
249 248 }
250 249
251 250 QMargins ChartLayout::margins() const
252 251 {
253 252 return m_margins;
254 253 }
255 254
256 255 void ChartLayout::adjustChartGeometry()
257 256 {
258 257 setGeometry(geometry());
259 258 }
260 259
261 260 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,387 +1,395
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 "legendlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "legendmarker_p.h"
24 24 #include "qlegend_p.h"
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 LegendLayout::LegendLayout(QLegend* legend):
30 30 m_legend(legend)
31 31 {
32 32
33 33 }
34 34
35 35 LegendLayout::~LegendLayout()
36 36 {
37 37
38 38 }
39 39
40 40 void LegendLayout::setOffset(qreal x, qreal y)
41 41 {
42 42 bool scrollHorizontal = true;
43 43 switch(m_legend->alignment()) {
44 44 case Qt::AlignTop:
45 45 case Qt::AlignBottom: {
46 46 scrollHorizontal = true;
47 47 break;
48 48 }
49 49 case Qt::AlignLeft:
50 50 case Qt::AlignRight: {
51 51 scrollHorizontal = false;
52 52 break;
53 53 }
54 54 }
55 55
56 56 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
57 57 if (!m_legend->isAttachedToChart()) {
58 58 scrollHorizontal = !scrollHorizontal;
59 59 }
60 60
61 61 QRectF boundingRect = geometry();
62 62 qreal left, top, right, bottom;
63 63 getContentsMargins(&left, &top, &right, &bottom);
64 64 boundingRect.adjust(left,top,-right,-bottom);
65 65
66 66 // Limit offset between m_minOffset and m_maxOffset
67 67 if (scrollHorizontal) {
68 68 if(m_width<=boundingRect.width()) return;
69 69
70 70 if (x != m_offsetX) {
71 71 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
72 72 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
73 73 }
74 74 }
75 75 else {
76 76 if(m_height<=boundingRect.height()) return;
77 77
78 78 if (y != m_offsetY) {
79 79 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
80 80 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
81 81 }
82 82 }
83 83 }
84 84
85 85 QPointF LegendLayout::offset() const
86 86 {
87 87 return QPointF(m_offsetX,m_offsetY);
88 88 }
89 89
90 void LegendLayout::invalidate()
91 {
92 QGraphicsLayout::invalidate();
93 if(m_legend->isAttachedToChart()){
94 m_legend->d_ptr->m_presenter->layout()->invalidate();
95 }
96 }
97
90 98 void LegendLayout::setGeometry(const QRectF& rect)
91 99 {
92 100 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
93 101
94 102 QGraphicsLayout::setGeometry(rect);
95 103
96 104 if(m_legend->isAttachedToChart()) {
97 105 setAttachedGeometry(rect);
98 106 } else {
99 107 setDettachedGeometry(rect);
100 108 }
101 109
102 110 }
103 111
104 112 void LegendLayout::setAttachedGeometry(const QRectF& rect)
105 113 {
106 114 if (!rect.isValid()) return;
107 115 m_offsetX=0;
108 116 m_offsetY=0;
109 117
110 118 QSizeF size(0,0);
111 119
112 120 if( m_legend->d_ptr->markers().isEmpty()) return;
113 121
114 122 m_width=0;
115 123 m_height=0;
116 124
117 125 qreal left, top, right, bottom;
118 126 getContentsMargins(&left, &top, &right, &bottom);
119 127
120 128 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
121 129
122 130 switch(m_legend->alignment()) {
123 131
124 132 case Qt::AlignTop:
125 133 case Qt::AlignBottom: {
126 134 QPointF point(0,0);
127 135 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
128 136 if (marker->isVisible()) {
129 137 marker->setGeometry(geometry);
130 138 marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
131 139 const QRectF& rect = marker->boundingRect();
132 140 size = size.expandedTo(rect.size());
133 141 qreal w = rect.width();
134 142 m_width+=w;
135 143 point.setX(point.x() + w);
136 144 }
137 145 }
138 146 if(m_width<geometry.width()) {
139 147 m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
140 148
141 149 }
142 150 else {
143 151 m_legend->d_ptr->items()->setPos(geometry.topLeft());
144 152 }
145 153 m_height=size.height();
146 154 }
147 155 break;
148 156 case Qt::AlignLeft:
149 157 case Qt::AlignRight: {
150 158 QPointF point(0,0);
151 159 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
152 160 if (marker->isVisible()) {
153 161 marker->setGeometry(geometry);
154 162 marker->setPos(point);
155 163 const QRectF& rect = marker->boundingRect();
156 164 qreal h = rect.height();
157 165 size = size.expandedTo(rect.size());
158 166 m_height+=h;
159 167 point.setY(point.y() + h);
160 168 }
161 169 }
162 170 if(m_height<geometry.height()) {
163 171 m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
164 172 }
165 173 else {
166 174 m_legend->d_ptr->items()->setPos(geometry.topLeft());
167 175 }
168 176 m_width=size.width();
169 177 }
170 178 break;
171 179 }
172 180
173 181
174 182 m_minOffsetX = -left;
175 183 m_minOffsetY = - top;
176 184 m_maxOffsetX = m_width - geometry.width() - right;
177 185 m_maxOffsetY = m_height - geometry.height() - bottom;
178 186 }
179 187
180 188 void LegendLayout::setDettachedGeometry(const QRectF& rect)
181 189 {
182 190 if (!rect.isValid()) return;
183 191
184 192 // Detached layout is different.
185 193 // In detached mode legend may have multiple rows and columns, so layout calculations
186 194 // differ a log from attached mode.
187 195 // Also the scrolling logic is bit different.
188 196
189 197 m_offsetX=0;
190 198 m_offsetY=0;
191 199
192 200 qreal left, top, right, bottom;
193 201 getContentsMargins(&left, &top, &right, &bottom);
194 202 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
195 203
196 204 QSizeF size(0,0);
197 205
198 206 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
199 207
200 208 if(markers.isEmpty()) return;
201 209
202 210 switch (m_legend->alignment()) {
203 211 case Qt::AlignTop: {
204 212 QPointF point(0,0);
205 213 m_width = 0;
206 214 m_height = 0;
207 215 for (int i=0; i<markers.count(); i++) {
208 216 LegendMarker *marker = markers.at(i);
209 217 if (marker->isVisible()) {
210 218 marker->setGeometry(geometry);
211 219 marker->setPos(point.x(),point.y());
212 220 const QRectF& boundingRect = marker->boundingRect();
213 221 qreal w = boundingRect.width();
214 222 qreal h = boundingRect.height();
215 223 m_width = qMax(m_width,w);
216 224 m_height = qMax(m_height,h);
217 225 point.setX(point.x() + w);
218 226 if (point.x() + w > geometry.left() + geometry.width() - right) {
219 227 // Next item would go off rect.
220 228 point.setX(0);
221 229 point.setY(point.y() + h);
222 230 if (i+1 < markers.count()) {
223 231 m_height += h;
224 232 }
225 233 }
226 234 }
227 235 }
228 236 m_legend->d_ptr->items()->setPos(geometry.topLeft());
229 237
230 238 m_minOffsetX = -left;
231 239 m_minOffsetY = -top;
232 240 m_maxOffsetX = m_width - geometry.width() - right;
233 241 m_maxOffsetY = m_height - geometry.height() - bottom;
234 242 }
235 243 break;
236 244 case Qt::AlignBottom: {
237 245 QPointF point(0,geometry.height());
238 246 m_width = 0;
239 247 m_height = 0;
240 248 for (int i=0; i<markers.count(); i++) {
241 249 LegendMarker *marker = markers.at(i);
242 250 if (marker->isVisible()) {
243 251 marker->setGeometry(geometry);
244 252 const QRectF& boundingRect = marker->boundingRect();
245 253 qreal w = boundingRect.width();
246 254 qreal h = boundingRect.height();
247 255 m_width = qMax(m_width,w);
248 256 m_height = qMax(m_height,h);
249 257 marker->setPos(point.x(),point.y() - h);
250 258 point.setX(point.x() + w);
251 259 if (point.x() + w > geometry.left() + geometry.width() - right) {
252 260 // Next item would go off rect.
253 261 point.setX(0);
254 262 point.setY(point.y() - h);
255 263 if (i+1 < markers.count()) {
256 264 m_height += h;
257 265 }
258 266 }
259 267 }
260 268 }
261 269 m_legend->d_ptr->items()->setPos(geometry.topLeft());
262 270
263 271 m_minOffsetX = -left;
264 272 m_minOffsetY = -m_height + geometry.height() - top;
265 273 m_maxOffsetX = m_width - geometry.width() - right;
266 274 m_maxOffsetY = -bottom;
267 275 }
268 276 break;
269 277 case Qt::AlignLeft: {
270 278 QPointF point(0,0);
271 279 m_width = 0;
272 280 m_height = 0;
273 281 qreal maxWidth = 0;
274 282 for (int i=0; i<markers.count(); i++) {
275 283 LegendMarker *marker = markers.at(i);
276 284 if (marker->isVisible()) {
277 285 marker->setGeometry(geometry);
278 286 const QRectF& boundingRect = marker->boundingRect();
279 287 qreal w = boundingRect.width();
280 288 qreal h = boundingRect.height();
281 289 m_height = qMax(m_height,h);
282 290 maxWidth = qMax(maxWidth,w);
283 291 marker->setPos(point.x(),point.y());
284 292 point.setY(point.y() + h);
285 293 if (point.y() + h > geometry.bottom() - bottom) {
286 294 // Next item would go off rect.
287 295 point.setX(point.x() + maxWidth);
288 296 point.setY(0);
289 297 if (i+1 < markers.count()) {
290 298 m_width += maxWidth;
291 299 maxWidth = 0;
292 300 }
293 301 }
294 302 }
295 303 }
296 304 m_width += maxWidth;
297 305 m_legend->d_ptr->items()->setPos(geometry.topLeft());
298 306
299 307 m_minOffsetX = -left;
300 308 m_minOffsetY = -top;
301 309 m_maxOffsetX = m_width - geometry.width() - right;
302 310 m_maxOffsetY = m_height - geometry.height() - bottom;
303 311 }
304 312 break;
305 313 case Qt::AlignRight: {
306 314 QPointF point(geometry.width(),0);
307 315 m_width = 0;
308 316 m_height = 0;
309 317 qreal maxWidth = 0;
310 318 for (int i=0; i<markers.count(); i++) {
311 319 LegendMarker *marker = markers.at(i);
312 320 if (marker->isVisible()) {
313 321 marker->setGeometry(geometry);
314 322 const QRectF& boundingRect = marker->boundingRect();
315 323 qreal w = boundingRect.width();
316 324 qreal h = boundingRect.height();
317 325 m_height = qMax(m_height,h);
318 326 maxWidth = qMax(maxWidth,w);
319 327 marker->setPos(point.x() - w,point.y());
320 328 point.setY(point.y() + h);
321 329 if (point.y() + h > geometry.bottom()-bottom) {
322 330 // Next item would go off rect.
323 331 point.setX(point.x() - maxWidth);
324 332 point.setY(0);
325 333 if (i+1 < markers.count()) {
326 334 m_width += maxWidth;
327 335 maxWidth = 0;
328 336 }
329 337 }
330 338 }
331 339 }
332 340 m_width += maxWidth;
333 341 m_legend->d_ptr->items()->setPos(geometry.topLeft());
334 342
335 343 m_minOffsetX = - m_width + geometry.width() - left;
336 344 m_minOffsetY = -top;
337 345 m_maxOffsetX = - right;
338 346 m_maxOffsetY = m_height - geometry.height() - bottom;
339 347 }
340 348 break;
341 349 default:
342 350 break;
343 351 }
344 352
345 353 }
346 354
347 355 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
348 356 {
349 357 QSizeF size(0, 0);
350 358 qreal left, top, right, bottom;
351 359 getContentsMargins(&left, &top, &right, &bottom);
352 360
353 361 if(constraint.isValid()) {
354 362 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
355 363 size = size.expandedTo(marker->effectiveSizeHint(which));
356 364 }
357 365 size = size.boundedTo(constraint);
358 366 }
359 367 else if (constraint.width() >= 0) {
360 368 qreal width = 0;
361 369 qreal height = 0;
362 370 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
363 371 width+=marker->effectiveSizeHint(which).width();
364 372 height=qMax(height,marker->effectiveSizeHint(which).height());
365 373 }
366 374
367 375 size = QSizeF(qMin(constraint.width(),width), height);
368 376 }
369 377 else if (constraint.height() >= 0) {
370 378 qreal width = 0;
371 379 qreal height = 0;
372 380 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
373 381 width=qMax(width,marker->effectiveSizeHint(which).width());
374 382 height+=height,marker->effectiveSizeHint(which).height();
375 383 }
376 384 size = QSizeF(width,qMin(constraint.height(),height));
377 385 }
378 386 else {
379 387 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
380 388 size = size.expandedTo(marker->effectiveSizeHint(which));
381 389 }
382 390 }
383 391 size += QSize(left + right, top + bottom);
384 392 return size;
385 393 }
386 394
387 395 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,68
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 #ifndef LEGENDLAYOUT_H
22 22 #define LEGENDLAYOUT_H
23 23 #include <QGraphicsLayout>
24 24 #include "qchartglobal.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 class QLegend;
29 29
30 30 class LegendLayout : public QGraphicsLayout
31 31 {
32 32 public:
33 33
34 34 LegendLayout(QLegend* legend);
35 35 virtual ~LegendLayout();
36 36
37 37 void setGeometry(const QRectF& rect);
38 38
39 39 void setOffset(qreal x, qreal y);
40 40 QPointF offset() const;
41 41
42 void invalidate();
42 43 protected:
43 44 QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
44 45 int count() const { return 0; }
45 46 QGraphicsLayoutItem* itemAt(int) const { return 0; };
46 47 void removeAt(int){};
47 48
48 49 private:
49 50 void setAttachedGeometry(const QRectF& rect);
50 51 void setDettachedGeometry(const QRectF& rect);
51 52
52 53 private:
53 54 QLegend* m_legend;
54 55 qreal m_offsetX;
55 56 qreal m_offsetY;
56 57 qreal m_minOffsetX;
57 58 qreal m_minOffsetY;
58 59 qreal m_maxOffsetX;
59 60 qreal m_maxOffsetY;
60 61 qreal m_width;
61 62 qreal m_height;
62 63
63 64 };
64 65
65 66 QTCOMMERCIALCHART_END_NAMESPACE
66 67
67 68 #endif
@@ -1,254 +1,254
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 "legendmarker_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "qlegend.h"
25 25 #include "qabstractbarseries.h"
26 26 #include "qpieseries.h"
27 27 #include "qpieslice.h"
28 28 #include "qbarset.h"
29 29 #include "qbarset_p.h"
30 30 #include "qareaseries.h"
31 31 #include "qareaseries_p.h"
32 32 #include <QPainter>
33 33 #include <QGraphicsSceneEvent>
34 34 #include <QGraphicsSimpleTextItem>
35 35 #include <QGraphicsLayout>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
40 40 QGraphicsObject(legend),
41 41 m_series(series),
42 42 m_markerRect(0,0,10.0,10.0),
43 43 m_boundingRect(0,0,0,0),
44 44 m_legend(legend),
45 45 m_textItem(new QGraphicsSimpleTextItem(this)),
46 46 m_rectItem(new QGraphicsRectItem(this)),
47 47 m_margin(4),
48 48 m_space(4)
49 49 {
50 50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
51 51 m_rectItem->setRect(m_markerRect);
52 52 }
53 53
54 54 void LegendMarker::setPen(const QPen &pen)
55 55 {
56 56 m_rectItem->setPen(pen);
57 57 }
58 58
59 59 QPen LegendMarker::pen() const
60 60 {
61 61 return m_rectItem->pen();
62 62 }
63 63
64 64 void LegendMarker::setBrush(const QBrush &brush)
65 65 {
66 66 m_rectItem->setBrush(brush);
67 67 }
68 68
69 69 QBrush LegendMarker::brush() const
70 70 {
71 71 return m_rectItem->brush();
72 72 }
73 73
74 74 void LegendMarker::setFont(const QFont &font)
75 75 {
76 76 m_textItem->setFont(font);
77 77 QFontMetrics fn(font);
78 78 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
79 79 updateGeometry();
80 m_legend->layout()->invalidate();
80 81 }
81 82
82 83 QFont LegendMarker::font() const
83 84 {
84 85 return m_textItem->font();
85 86 }
86 87
87 88 void LegendMarker::setLabel(const QString label)
88 89 {
89 90 m_text = label;
90 91 updateGeometry();
91 92 m_legend->layout()->invalidate();
92 93 }
93 94
94 95 QString LegendMarker::label() const
95 96 {
96 97 return m_text;
97 98 }
98 99
99 100 QRectF LegendMarker::boundingRect() const
100 101 {
101 102 return m_boundingRect;
102 103 }
103 104
104 105 void LegendMarker::setLabelBrush(const QBrush &brush)
105 106 {
106 107 m_textItem->setBrush(brush);
107 108 }
108 109
109 110 QBrush LegendMarker::labelBrush() const
110 111 {
111 112 return m_textItem->brush();
112 113 }
113 114
114 115
115 116 void LegendMarker::setGeometry(const QRectF& rect)
116 117 {
117 118 QFontMetrics fn (font());
118 119
119 120 int width = rect.width();
120 121 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
121 122 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
122 123
123 124 if (fn.boundingRect(m_text).width() + x > width)
124 125 {
125 126 QString string = m_text + "...";
126 127 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
127 128 string.remove(string.length() - 4, 1);
128 129 m_textItem->setText(string);
129 130 }
130 131 else
131 132 m_textItem->setText(m_text);
132 133
133 134 const QRectF& textRect = m_textItem->boundingRect();
134 135
135 136
136 137 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
137 138 m_rectItem->setRect(m_markerRect);
138 139 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
139 140
140 141 prepareGeometryChange();
141 142 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
142 143 }
143 144
144 145 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
145 146 {
146 147 Q_UNUSED(option)
147 148 Q_UNUSED(widget)
148 149 Q_UNUSED(painter)
149 150 }
150 151
151 152 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
152 153 {
153 154 Q_UNUSED(constraint)
154 155
155 156 QFontMetrics fn(m_textItem->font());
156 157 QSizeF sh;
157 158
158 159 switch (which) {
159 160 case Qt::MinimumSize:
160 161 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
161 162 break;
162 163 case Qt::PreferredSize:
163 164 sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
164 165 break;
165 166 default:
166 167 break;
167 168 }
168
169 169 return sh;
170 170 }
171 171
172 172 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
173 173 {
174 174 QGraphicsObject::mousePressEvent(event);
175 175 //TODO: selected signal removed for now
176 176 }
177 177
178 178 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
179 179
180 180 AreaLegendMarker::AreaLegendMarker(QAreaSeries *series,QLegend *legend) : LegendMarker(series,legend),
181 181 m_series(series)
182 182 {
183 183 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
184 184 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
185 185 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
186 186 updated();
187 187 }
188 188
189 189 void AreaLegendMarker::updated()
190 190 {
191 191 setBrush(m_series->brush());
192 192 setLabel(m_series->name());
193 193 }
194 194
195 195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
196 196
197 197 BarLegendMarker::BarLegendMarker(QAbstractBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarker(barseries,legend),
198 198 m_barset(barset)
199 199 {
200 200 //QObject::connect(this, SIGNAL(selected()),barset->d_ptr.data(), SIGNAL(selected()));
201 201 QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
202 202 updated();
203 203 }
204 204
205 205 void BarLegendMarker::updated()
206 206 {
207 207 setBrush(m_barset->brush());
208 208 setLabel(m_barset->label());
209 209 }
210 210
211 211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
212 212
213 213 PieLegendMarker::PieLegendMarker(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarker(series,legend),
214 214 m_pieslice(pieslice)
215 215 {
216 216 QObject::connect(pieslice, SIGNAL(labelChanged()), this, SLOT(updated()));
217 217 QObject::connect(pieslice, SIGNAL(brushChanged()), this, SLOT(updated()));
218 218 updated();
219 219 }
220 220
221 221 void PieLegendMarker::updated()
222 222 {
223 223 setBrush(m_pieslice->brush());
224 224 setLabel(m_pieslice->label());
225 225 }
226 226
227 227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 228
229 229 XYLegendMarker::XYLegendMarker(QXYSeries *series, QLegend *legend) : LegendMarker(series,legend),
230 230 m_series(series)
231 231 {
232 232 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
233 233 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
234 234 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
235 235 updated();
236 236 }
237 237
238 238 void XYLegendMarker::updated()
239 239 {
240 240 setLabel(m_series->name());
241 241
242 242 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
243 243 {
244 244 setBrush(m_series->brush());
245 245
246 246 }
247 247 else {
248 248 setBrush(QBrush(m_series->pen().color()));
249 249 }
250 250 }
251 251
252 252 #include "moc_legendmarker_p.cpp"
253 253
254 254 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,525 +1,516
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 #include "legendlayout_p.h"
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 "qabstractbarseries.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 #include <QGraphicsLayout>
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 48
49 49 /*!
50 50 \class QLegend
51 51 \brief Legend object
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 used 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 (brush) color. Note that if you change the color
107 107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 108 */
109 109 /*!
110 110 \qmlproperty color Legend::color
111 111 The color of the legend, i.e. the background (brush) color.
112 112 */
113 113
114 114 /*!
115 115 \property QLegend::borderColor
116 116 The border color of the legend, i.e. the line color.
117 117 */
118 118 /*!
119 119 \qmlproperty color Legend::borderColor
120 120 The border color of the legend, i.e. the line color.
121 121 */
122 122
123 123 /*!
124 124 \property QLegend::font
125 125 The font of markers used by legend
126 126 */
127 127 /*!
128 128 \qmlproperty color Legend::font
129 129 The font of markers used by legend
130 130 */
131 131
132 132 /*!
133 133 \property QLegend::labelColor
134 134 The color of brush used to draw labels.
135 135 */
136 136 /*!
137 137 \qmlproperty color QLegend::labelColor
138 138 The color of brush used to draw labels.
139 139 */
140 140
141 141 /*!
142 142 \fn void QLegend::backgroundVisibleChanged(bool)
143 143 The visibility of the legend background changed to \a visible.
144 144 */
145 145
146 146 /*!
147 147 \fn void QLegend::colorChanged(QColor)
148 148 The color of the legend background changed to \a color.
149 149 */
150 150
151 151 /*!
152 152 \fn void QLegend::borderColorChanged(QColor)
153 153 The border color of the legend background changed to \a color.
154 154 */
155 155
156 156 /*!
157 157 \fn void QLegend::fontChanged(QFont)
158 158 The font of markers of the legend changed to \a font.
159 159 */
160 160
161 161 /*!
162 162 \fn void QLegend::labelColorChanged(QColor color)
163 163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
164 164 */
165 165
166 166 /*!
167 167 Constructs the legend object and sets the parent to \a parent
168 168 */
169 169
170 170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
171 171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
172 172 {
173 173 setZValue(ChartPresenter::LegendZValue);
174 174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
175 175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
176 176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
177 177 // QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
178 178 setLayout(d_ptr->m_layout);
179 179 }
180 180
181 181 /*!
182 182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
183 183 */
184 184 QLegend::~QLegend()
185 185 {
186 186 }
187 187
188 188 /*!
189 189 \internal
190 190 */
191 191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
192 192 {
193 193 Q_UNUSED(option)
194 194 Q_UNUSED(widget)
195 195
196 196 if(!d_ptr->m_backgroundVisible) return;
197 197
198 198 painter->setOpacity(opacity());
199 199 painter->setPen(d_ptr->m_pen);
200 200 painter->setBrush(d_ptr->m_brush);
201 201 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
202 202
203 203 }
204 204
205 205
206 206 /*!
207 207 Sets the \a brush of legend. Brush affects the background of legend.
208 208 */
209 209 void QLegend::setBrush(const QBrush &brush)
210 210 {
211 211 if (d_ptr->m_brush != brush) {
212 212 d_ptr->m_brush = brush;
213 213 update();
214 214 emit colorChanged(brush.color());
215 215 }
216 216 }
217 217
218 218 /*!
219 219 Returns the brush used by legend.
220 220 */
221 221 QBrush QLegend::brush() const
222 222 {
223 223 return d_ptr->m_brush;
224 224 }
225 225
226 226 void QLegend::setColor(QColor color)
227 227 {
228 228 QBrush b = d_ptr->m_brush;
229 229 if (b.style() != Qt::SolidPattern || b.color() != color) {
230 230 b.setStyle(Qt::SolidPattern);
231 231 b.setColor(color);
232 232 setBrush(b);
233 233 }
234 234 }
235 235
236 236 QColor QLegend::color()
237 237 {
238 238 return d_ptr->m_brush.color();
239 239 }
240 240
241 241 /*!
242 242 Sets the \a pen of legend. Pen affects the legend borders.
243 243 */
244 244 void QLegend::setPen(const QPen &pen)
245 245 {
246 246 if (d_ptr->m_pen != pen) {
247 247 d_ptr->m_pen = pen;
248 248 update();
249 249 emit borderColorChanged(pen.color());
250 250 }
251 251 }
252 252
253 253 /*!
254 254 Returns the pen used by legend
255 255 */
256 256
257 257 QPen QLegend::pen() const
258 258 {
259 259 return d_ptr->m_pen;
260 260 }
261 261
262 262 void QLegend::setFont(const QFont &font)
263 263 {
264 264 if (d_ptr->m_font != font) {
265 265 d_ptr->m_font = font;
266 266
267 267 foreach (LegendMarker *marker, d_ptr->markers()) {
268 268 marker->setFont(d_ptr->m_font);
269 269 }
270 270 layout()->invalidate();
271 271 emit fontChanged(font);
272 272 }
273 273 }
274 274
275 275 QFont QLegend::font() const
276 276 {
277 277 return d_ptr->m_font;
278 278 }
279 279
280 280 void QLegend::setBorderColor(QColor color)
281 281 {
282 282 QPen p = d_ptr->m_pen;
283 283 if (p.color() != color) {
284 284 p.setColor(color);
285 285 setPen(p);
286 286 }
287 287 }
288 288
289 289 QColor QLegend::borderColor()
290 290 {
291 291 return d_ptr->m_pen.color();
292 292 }
293 293
294 294 /*!
295 295 Set brush used to draw labels to \a brush.
296 296 */
297 297 void QLegend::setLabelBrush(const QBrush &brush)
298 298 {
299 299 if (d_ptr->m_labelBrush != brush) {
300 300 d_ptr->m_labelBrush = brush;
301 301 foreach (LegendMarker *marker, d_ptr->markers()) {
302 302 marker->setLabelBrush(d_ptr->m_labelBrush);
303 303 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
304 304 // instead of mapping it from label brush color
305 305 marker->setPen(brush.color());
306 306 }
307 307 emit labelColorChanged(brush.color());
308 308 }
309 309 }
310 310
311 311 /*!
312 312 Brush used to draw labels.
313 313 */
314 314 QBrush QLegend::labelBrush() const
315 315 {
316 316 return d_ptr->m_labelBrush;
317 317 }
318 318
319 319 void QLegend::setLabelColor(QColor color)
320 320 {
321 321 QBrush b = d_ptr->m_labelBrush;
322 322 if (b.style() != Qt::SolidPattern || b.color() != color) {
323 323 b.setStyle(Qt::SolidPattern);
324 324 b.setColor(color);
325 325 setLabelBrush(b);
326 326 }
327 327 }
328 328
329 329 QColor QLegend::labelColor() const
330 330 {
331 331 return d_ptr->m_labelBrush.color();
332 332 }
333 333
334 334
335 335 void QLegend::setAlignment(Qt::Alignment alignment)
336 336 {
337 337 if(d_ptr->m_alignment!=alignment) {
338 338 d_ptr->m_alignment = alignment;
339 if(isAttachedToChart()){
340 d_ptr->m_presenter->layout()->invalidate();
341 }else{
342 layout()->invalidate();
343 }
339 layout()->invalidate();
344 340 }
345 341 }
346 342
347 343 Qt::Alignment QLegend::alignment() const
348 344 {
349 345 return d_ptr->m_alignment;
350 346 }
351 347
352 348 /*!
353 349 Detaches the legend from chart. Chart won't change layout of the legend.
354 350 */
355 351 void QLegend::detachFromChart()
356 352 {
357 353 d_ptr->m_attachedToChart = false;
358 d_ptr->m_layout->invalidate();
354 layout()->invalidate();
359 355 setParent(0);
360 356
361 357 }
362 358
363 359 /*!
364 360 Attaches the legend to chart. Chart may change layout of the legend.
365 361 */
366 362 void QLegend::attachToChart()
367 363 {
368 364 d_ptr->m_attachedToChart = true;
369 d_ptr->m_presenter->layout()->invalidate();
365 layout()->invalidate();
370 366 setParent(d_ptr->m_chart);
371 367 }
372 368
373 369 /*!
374 370 Returns true, if legend is attached to chart.
375 371 */
376 372 bool QLegend::isAttachedToChart()
377 373 {
378 374 return d_ptr->m_attachedToChart;
379 375 }
380 376
381 377 /*!
382 378 Sets the visibility of legend background to \a visible
383 379 */
384 380 void QLegend::setBackgroundVisible(bool visible)
385 381 {
386 382 if(d_ptr->m_backgroundVisible != visible) {
387 383 d_ptr->m_backgroundVisible = visible;
388 384 update();
389 385 emit backgroundVisibleChanged(visible);
390 386 }
391 387 }
392 388
393 389 /*!
394 390 Returns the visibility of legend background
395 391 */
396 392 bool QLegend::isBackgroundVisible() const
397 393 {
398 394 return d_ptr->m_backgroundVisible;
399 395 }
400 396
401 397 /*!
402 398 \internal \a event see QGraphicsWidget for details
403 399 */
404 400 void QLegend::hideEvent(QHideEvent *event)
405 401 {
406 402 if(isAttachedToChart()) d_ptr->m_presenter->layout()->invalidate();
407 403 QGraphicsWidget::hideEvent(event);
408 404 }
409
410 405 /*!
411 406 \internal \a event see QGraphicsWidget for details
412 407 */
413 408 void QLegend::showEvent(QShowEvent *event)
414 409 {
415 410 if(isAttachedToChart()) {
416 d_ptr->m_presenter->layout()->invalidate();
417 411 d_ptr->items()->setVisible(false);
418 412 layout()->invalidate();
419 413 }
420 414 QGraphicsWidget::showEvent(event);
421 415 //layout activation will show the items
422 416 }
423 417
424 418 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
425 419
426 420 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
427 421 q_ptr(q),
428 422 m_presenter(presenter),
429 423 m_layout(new LegendLayout(q)),
430 424 m_chart(chart),
431 425 m_items(new QGraphicsItemGroup(q)),
432 426 m_alignment(Qt::AlignTop),
433 427 m_brush(QBrush()),
434 428 m_pen(QPen()),
435 429 m_labelBrush(QBrush()),
436 430 m_diameter(5),
437 431 m_attachedToChart(true),
438 432 m_backgroundVisible(false)
439 433 {
440 434
441 435 }
442 436
443 437 QLegendPrivate::~QLegendPrivate()
444 438 {
445 439
446 440 }
447 441
448 442 void QLegendPrivate::setOffset(qreal x, qreal y)
449 443 {
450 444 m_layout->setOffset(x,y);
451 445 }
452 446
453 447 QPointF QLegendPrivate::offset() const
454 448 {
455 449 return m_layout->offset();
456 450 }
457 451
458 452 int QLegendPrivate::roundness(qreal size)
459 453 {
460 454 return 100*m_diameter/int(size);
461 455 }
462 456
463 457 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
464 458 {
465 459 Q_UNUSED(domain)
466 460
467 461 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
468 462
469 463 foreach (LegendMarker* marker, markers) {
470 464 marker->setFont(m_font);
471 465 marker->setLabelBrush(m_labelBrush);
472 466 marker->setVisible(series->isVisible());
473 467 m_items->addToGroup(marker);
474 468 m_markers<<marker;
475 469 }
476 470
477 471 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
478 472 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
479 473
480 474 m_items->setVisible(false);
481 q_ptr->layout()->invalidate();
482 m_presenter->layout()->invalidate();
475 m_layout->invalidate();
483 476 }
484 477
485 478 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
486 479 {
487 480 foreach (LegendMarker *marker, m_markers) {
488 481 if (marker->series() == series) {
489 482 delete marker;
490 483 m_markers.removeAll(marker);
491 484 }
492 485 }
493 486
494 487 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
495 488 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
496
497 q_ptr->layout()->invalidate();
489 m_layout->invalidate();
498 490 }
499 491
500 492 void QLegendPrivate::handleSeriesVisibleChanged()
501 493 {
502 494 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
503 495 Q_ASSERT(series);
504 496
505 497 foreach (LegendMarker* marker, m_markers) {
506 498 if (marker->series() == series) {
507 499 marker->setVisible(series->isVisible());
508 500 }
509 501 }
510
511 q_ptr->layout()->invalidate();
502 m_layout->invalidate();
512 503 }
513 504
514 505 void QLegendPrivate::handleCountChanged()
515 506 {
516 507 QAbstractSeriesPrivate* series = qobject_cast<QAbstractSeriesPrivate *> (sender());
517 508 Q_ASSERT(series);
518 509 handleSeriesRemoved(series->q_ptr);
519 510 handleSeriesAdded(series->q_ptr, 0);
520 511 }
521 512
522 513 #include "moc_qlegend.cpp"
523 514 #include "moc_qlegend_p.cpp"
524 515
525 516 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,87 +1,88
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 class LegendLayout;
41 41 class LegendMarker;
42 42 class Domain;
43 43
44 44 class QLegendPrivate : public QObject
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
49 49 ~QLegendPrivate();
50 50
51 51 void setOffset(qreal x, qreal y);
52 52 QPointF offset() const;
53 53 int roundness(qreal size);
54 54
55 55 QList<LegendMarker*> markers() { return m_markers; }
56 56 QGraphicsItemGroup* items() { return m_items; }
57 57
58 58 public Q_SLOTS:
59 59 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
60 60 void handleSeriesRemoved(QAbstractSeries *series);
61 61 void handleSeriesVisibleChanged();
62 62 void handleCountChanged();
63 63
64 64 private:
65 65 QLegend *q_ptr;
66 66 ChartPresenter *m_presenter;
67 67 LegendLayout *m_layout;
68 68 QChart* m_chart;
69 69 QGraphicsItemGroup* m_items;
70 70 QList<LegendMarker*> m_markers;
71 71 Qt::Alignment m_alignment;
72 72 QBrush m_brush;
73 73 QPen m_pen;
74 74 QFont m_font;
75 75 QBrush m_labelBrush;
76 76
77 77 qreal m_diameter;
78 78 bool m_attachedToChart;
79 79 bool m_backgroundVisible;
80 80
81 81 friend class QLegend;
82 friend class LegendLayout;
82 83
83 84 };
84 85
85 86 QTCOMMERCIALCHART_END_NAMESPACE
86 87
87 88 #endif
General Comments 0
You need to be logged in to leave comments. Login now