##// END OF EJS Templates
Fix legend truncation...
Titta Heikkala -
r2673:fc7673506633
parent child
Show More
@@ -1,493 +1,493
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2013 Digia Plc
3 ** Copyright (C) 2013 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "legendlayout_p.h"
21 #include "legendlayout_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlegend_p.h"
23 #include "qlegend_p.h"
24 #include "abstractchartlayout_p.h"
24 #include "abstractchartlayout_p.h"
25
25
26 #include "qlegendmarker_p.h"
26 #include "qlegendmarker_p.h"
27 #include "legendmarkeritem_p.h"
27 #include "legendmarkeritem_p.h"
28 #include "qlegendmarker.h"
28 #include "qlegendmarker.h"
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 LegendLayout::LegendLayout(QLegend *legend)
32 LegendLayout::LegendLayout(QLegend *legend)
33 : m_legend(legend),
33 : m_legend(legend),
34 m_offsetX(0),
34 m_offsetX(0),
35 m_offsetY(0)
35 m_offsetY(0)
36 {
36 {
37
37
38 }
38 }
39
39
40 LegendLayout::~LegendLayout()
40 LegendLayout::~LegendLayout()
41 {
41 {
42
42
43 }
43 }
44
44
45 void LegendLayout::setOffset(qreal x, qreal y)
45 void LegendLayout::setOffset(qreal x, qreal y)
46 {
46 {
47 bool scrollHorizontal = true;
47 bool scrollHorizontal = true;
48 switch (m_legend->alignment()) {
48 switch (m_legend->alignment()) {
49 case Qt::AlignTop:
49 case Qt::AlignTop:
50 case Qt::AlignBottom:
50 case Qt::AlignBottom:
51 scrollHorizontal = true;
51 scrollHorizontal = true;
52 break;
52 break;
53 case Qt::AlignLeft:
53 case Qt::AlignLeft:
54 case Qt::AlignRight:
54 case Qt::AlignRight:
55 scrollHorizontal = false;
55 scrollHorizontal = false;
56 break;
56 break;
57 }
57 }
58
58
59 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
59 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
60 if (!m_legend->isAttachedToChart())
60 if (!m_legend->isAttachedToChart())
61 scrollHorizontal = !scrollHorizontal;
61 scrollHorizontal = !scrollHorizontal;
62
62
63 QRectF boundingRect = geometry();
63 QRectF boundingRect = geometry();
64 qreal left, top, right, bottom;
64 qreal left, top, right, bottom;
65 getContentsMargins(&left, &top, &right, &bottom);
65 getContentsMargins(&left, &top, &right, &bottom);
66 boundingRect.adjust(left, top, -right, -bottom);
66 boundingRect.adjust(left, top, -right, -bottom);
67
67
68 // Limit offset between m_minOffset and m_maxOffset
68 // Limit offset between m_minOffset and m_maxOffset
69 if (scrollHorizontal) {
69 if (scrollHorizontal) {
70 if (m_width <= boundingRect.width())
70 if (m_width <= boundingRect.width())
71 return;
71 return;
72
72
73 if (x != m_offsetX) {
73 if (x != m_offsetX) {
74 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
74 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
75 m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top());
75 m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top());
76 }
76 }
77 } else {
77 } else {
78 if (m_height <= boundingRect.height())
78 if (m_height <= boundingRect.height())
79 return;
79 return;
80
80
81 if (y != m_offsetY) {
81 if (y != m_offsetY) {
82 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
82 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
83 m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY);
83 m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY);
84 }
84 }
85 }
85 }
86 }
86 }
87
87
88 QPointF LegendLayout::offset() const
88 QPointF LegendLayout::offset() const
89 {
89 {
90 return QPointF(m_offsetX, m_offsetY);
90 return QPointF(m_offsetX, m_offsetY);
91 }
91 }
92
92
93 void LegendLayout::invalidate()
93 void LegendLayout::invalidate()
94 {
94 {
95 QGraphicsLayout::invalidate();
95 QGraphicsLayout::invalidate();
96 if (m_legend->isAttachedToChart())
96 if (m_legend->isAttachedToChart())
97 m_legend->d_ptr->m_presenter->layout()->invalidate();
97 m_legend->d_ptr->m_presenter->layout()->invalidate();
98 }
98 }
99
99
100 void LegendLayout::setGeometry(const QRectF &rect)
100 void LegendLayout::setGeometry(const QRectF &rect)
101 {
101 {
102 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
102 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
103
103
104 QGraphicsLayout::setGeometry(rect);
104 QGraphicsLayout::setGeometry(rect);
105
105
106 if (m_legend->isAttachedToChart())
106 if (m_legend->isAttachedToChart())
107 setAttachedGeometry(rect);
107 setAttachedGeometry(rect);
108 else
108 else
109 setDettachedGeometry(rect);
109 setDettachedGeometry(rect);
110 }
110 }
111
111
112 void LegendLayout::setAttachedGeometry(const QRectF &rect)
112 void LegendLayout::setAttachedGeometry(const QRectF &rect)
113 {
113 {
114 if (!rect.isValid())
114 if (!rect.isValid())
115 return;
115 return;
116
116
117 qreal oldOffsetX = m_offsetX;
117 qreal oldOffsetX = m_offsetX;
118 qreal oldOffsetY = m_offsetY;
118 qreal oldOffsetY = m_offsetY;
119 m_offsetX = 0;
119 m_offsetX = 0;
120 m_offsetY = 0;
120 m_offsetY = 0;
121
121
122 QSizeF size(0, 0);
122 QSizeF size(0, 0);
123
123
124 if (m_legend->d_ptr->markers().isEmpty()) {
124 if (m_legend->d_ptr->markers().isEmpty()) {
125 return;
125 return;
126 }
126 }
127
127
128 m_width = 0;
128 m_width = 0;
129 m_height = 0;
129 m_height = 0;
130
130
131 qreal left, top, right, bottom;
131 qreal left, top, right, bottom;
132 getContentsMargins(&left, &top, &right, &bottom);
132 getContentsMargins(&left, &top, &right, &bottom);
133
133
134 QRectF geometry = rect.adjusted(left, top, -right, -bottom);
134 QRectF geometry = rect.adjusted(left, top, -right, -bottom);
135
135
136 switch(m_legend->alignment()) {
136 switch(m_legend->alignment()) {
137 case Qt::AlignTop:
137 case Qt::AlignTop:
138 case Qt::AlignBottom: {
138 case Qt::AlignBottom: {
139 // Calculate the space required for items and add them to a sorted list.
139 // Calculate the space required for items and add them to a sorted list.
140 qreal markerItemsWidth = 0;
140 qreal markerItemsWidth = 0;
141 qreal itemMargins = 0;
141 qreal itemMargins = 0;
142 QList<LegendWidthStruct *> legendWidthList;
142 QList<LegendWidthStruct *> legendWidthList;
143 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
143 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
144 LegendMarkerItem *item = marker->d_ptr->item();
144 LegendMarkerItem *item = marker->d_ptr->item();
145 if (item->isVisible()) {
145 if (item->isVisible()) {
146 QSizeF dummySize;
146 QSizeF dummySize;
147 qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width();
147 qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width();
148 LegendWidthStruct *structItem = new LegendWidthStruct;
148 LegendWidthStruct *structItem = new LegendWidthStruct;
149 structItem->item = item;
149 structItem->item = item;
150 structItem->width = itemWidth;
150 structItem->width = itemWidth;
151 legendWidthList.append(structItem);
151 legendWidthList.append(structItem);
152 markerItemsWidth += itemWidth;
152 markerItemsWidth += itemWidth;
153 itemMargins += marker->d_ptr->item()->m_margin;
153 itemMargins += marker->d_ptr->item()->m_margin;
154 }
154 }
155 }
155 }
156 qSort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan);
156 qSort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan);
157
157
158 // If the items would occupy more space than is available, start truncating them
158 // If the items would occupy more space than is available, start truncating them
159 // from the longest one.
159 // from the longest one.
160 qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins;
160 qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins;
161 if (markerItemsWidth >= availableGeometry) {
161 if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 0) {
162 bool truncated(false);
162 bool truncated(false);
163 int count = legendWidthList.count();
163 int count = legendWidthList.count();
164 for (int i = 1; i < count; i++) {
164 for (int i = 1; i < count; i++) {
165 int truncateIndex = i - 1;
165 int truncateIndex = i - 1;
166
166
167 while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width
167 while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width
168 && !truncated) {
168 && !truncated) {
169 legendWidthList.at(truncateIndex)->width--;
169 legendWidthList.at(truncateIndex)->width--;
170 markerItemsWidth--;
170 markerItemsWidth--;
171 if (i > 1) {
171 if (i > 1) {
172 // Truncate the items that are before the truncated one in the list.
172 // Truncate the items that are before the truncated one in the list.
173 for (int j = truncateIndex - 1; j >= 0; j--) {
173 for (int j = truncateIndex - 1; j >= 0; j--) {
174 if (legendWidthList.at(truncateIndex)->width
174 if (legendWidthList.at(truncateIndex)->width
175 < legendWidthList.at(j)->width) {
175 < legendWidthList.at(j)->width) {
176 legendWidthList.at(j)->width--;
176 legendWidthList.at(j)->width--;
177 markerItemsWidth--;
177 markerItemsWidth--;
178 }
178 }
179 }
179 }
180 }
180 }
181 if (markerItemsWidth < availableGeometry)
181 if (markerItemsWidth < availableGeometry)
182 truncated = true;
182 truncated = true;
183 }
183 }
184 // Truncate the last item if needed.
184 // Truncate the last item if needed.
185 if (i == count - 1) {
185 if (i == count - 1) {
186 if (legendWidthList.at(count - 1)->width
186 if (legendWidthList.at(count - 1)->width
187 > legendWidthList.at(truncateIndex)->width) {
187 > legendWidthList.at(truncateIndex)->width) {
188 legendWidthList.at(count - 1)->width--;
188 legendWidthList.at(count - 1)->width--;
189 markerItemsWidth--;
189 markerItemsWidth--;
190 }
190 }
191 }
191 }
192
192
193 if (truncated)
193 if (truncated)
194 break;
194 break;
195 }
195 }
196 // Items are of same width and all of them need to be truncated
196 // Items are of same width and all of them need to be truncated
197 // or there is just one item that is truncated.
197 // or there is just one item that is truncated.
198 while (markerItemsWidth >= availableGeometry) {
198 while (markerItemsWidth >= availableGeometry) {
199 for (int i = 0; i < count; i++) {
199 for (int i = 0; i < count; i++) {
200 legendWidthList.at(i)->width--;
200 legendWidthList.at(i)->width--;
201 markerItemsWidth--;
201 markerItemsWidth--;
202 }
202 }
203 }
203 }
204 }
204 }
205
205
206 QPointF point(0,0);
206 QPointF point(0,0);
207 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
207 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
208 LegendMarkerItem *item = marker->d_ptr->item();
208 LegendMarkerItem *item = marker->d_ptr->item();
209 if (item->isVisible()) {
209 if (item->isVisible()) {
210 QRectF itemRect = geometry;
210 QRectF itemRect = geometry;
211 qreal availableWidth = 0;
211 qreal availableWidth = 0;
212 for (int i = 0; i < legendWidthList.size(); ++i) {
212 for (int i = 0; i < legendWidthList.size(); ++i) {
213 if (legendWidthList.at(i)->item == item) {
213 if (legendWidthList.at(i)->item == item) {
214 availableWidth = legendWidthList.at(i)->width;
214 availableWidth = legendWidthList.at(i)->width;
215 break;
215 break;
216 }
216 }
217 }
217 }
218 itemRect.setWidth(availableWidth);
218 itemRect.setWidth(availableWidth);
219 item->setGeometry(itemRect);
219 item->setGeometry(itemRect);
220 item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
220 item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
221 const QRectF &rect = item->boundingRect();
221 const QRectF &rect = item->boundingRect();
222 size = size.expandedTo(rect.size());
222 size = size.expandedTo(rect.size());
223 qreal w = rect.width();
223 qreal w = rect.width();
224 m_width = m_width + w - item->m_margin;
224 m_width = m_width + w - item->m_margin;
225 point.setX(point.x() + w);
225 point.setX(point.x() + w);
226 }
226 }
227 }
227 }
228 // Delete structs from the container
228 // Delete structs from the container
229 qDeleteAll(legendWidthList);
229 qDeleteAll(legendWidthList);
230
230
231 if (m_width < geometry.width())
231 if (m_width < geometry.width())
232 m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
232 m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
233 else
233 else
234 m_legend->d_ptr->items()->setPos(geometry.topLeft());
234 m_legend->d_ptr->items()->setPos(geometry.topLeft());
235 m_height = size.height();
235 m_height = size.height();
236 }
236 }
237 break;
237 break;
238 case Qt::AlignLeft:
238 case Qt::AlignLeft:
239 case Qt::AlignRight: {
239 case Qt::AlignRight: {
240 QPointF point(0,0);
240 QPointF point(0,0);
241 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
241 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
242 LegendMarkerItem *item = marker->d_ptr->item();
242 LegendMarkerItem *item = marker->d_ptr->item();
243 if (item->isVisible()) {
243 if (item->isVisible()) {
244 item->setGeometry(geometry);
244 item->setGeometry(geometry);
245 item->setPos(point);
245 item->setPos(point);
246 const QRectF &rect = item->boundingRect();
246 const QRectF &rect = item->boundingRect();
247 qreal h = rect.height();
247 qreal h = rect.height();
248 size = size.expandedTo(rect.size());
248 size = size.expandedTo(rect.size());
249 m_height+=h;
249 m_height+=h;
250 point.setY(point.y() + h);
250 point.setY(point.y() + h);
251 }
251 }
252 }
252 }
253
253
254 if (m_height < geometry.height())
254 if (m_height < geometry.height())
255 m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2);
255 m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2);
256 else
256 else
257 m_legend->d_ptr->items()->setPos(geometry.topLeft());
257 m_legend->d_ptr->items()->setPos(geometry.topLeft());
258 m_width = size.width();
258 m_width = size.width();
259 break;
259 break;
260 }
260 }
261 }
261 }
262
262
263 m_minOffsetX = -left;
263 m_minOffsetX = -left;
264 m_minOffsetY = - top;
264 m_minOffsetY = - top;
265 m_maxOffsetX = m_width - geometry.width() - right;
265 m_maxOffsetX = m_width - geometry.width() - right;
266 m_maxOffsetY = m_height - geometry.height() - bottom;
266 m_maxOffsetY = m_height - geometry.height() - bottom;
267
267
268 setOffset(oldOffsetX, oldOffsetY);
268 setOffset(oldOffsetX, oldOffsetY);
269 }
269 }
270
270
271 void LegendLayout::setDettachedGeometry(const QRectF &rect)
271 void LegendLayout::setDettachedGeometry(const QRectF &rect)
272 {
272 {
273 if (!rect.isValid())
273 if (!rect.isValid())
274 return;
274 return;
275
275
276 // Detached layout is different.
276 // Detached layout is different.
277 // In detached mode legend may have multiple rows and columns, so layout calculations
277 // In detached mode legend may have multiple rows and columns, so layout calculations
278 // differ a log from attached mode.
278 // differ a log from attached mode.
279 // Also the scrolling logic is bit different.
279 // Also the scrolling logic is bit different.
280
280
281 qreal oldOffsetX = m_offsetX;
281 qreal oldOffsetX = m_offsetX;
282 qreal oldOffsetY = m_offsetY;
282 qreal oldOffsetY = m_offsetY;
283 m_offsetX = 0;
283 m_offsetX = 0;
284 m_offsetY = 0;
284 m_offsetY = 0;
285
285
286 qreal left, top, right, bottom;
286 qreal left, top, right, bottom;
287 getContentsMargins(&left, &top, &right, &bottom);
287 getContentsMargins(&left, &top, &right, &bottom);
288 QRectF geometry = rect.adjusted(left, top, -right, -bottom);
288 QRectF geometry = rect.adjusted(left, top, -right, -bottom);
289
289
290 QSizeF size(0, 0);
290 QSizeF size(0, 0);
291
291
292 QList<QLegendMarker *> markers = m_legend->d_ptr->markers();
292 QList<QLegendMarker *> markers = m_legend->d_ptr->markers();
293
293
294 if (markers.isEmpty())
294 if (markers.isEmpty())
295 return;
295 return;
296
296
297 switch (m_legend->alignment()) {
297 switch (m_legend->alignment()) {
298 case Qt::AlignTop: {
298 case Qt::AlignTop: {
299 QPointF point(0, 0);
299 QPointF point(0, 0);
300 m_width = 0;
300 m_width = 0;
301 m_height = 0;
301 m_height = 0;
302 for (int i = 0; i < markers.count(); i++) {
302 for (int i = 0; i < markers.count(); i++) {
303 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
303 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
304 if (item->isVisible()) {
304 if (item->isVisible()) {
305 item->setGeometry(geometry);
305 item->setGeometry(geometry);
306 item->setPos(point.x(),point.y());
306 item->setPos(point.x(),point.y());
307 const QRectF &boundingRect = item->boundingRect();
307 const QRectF &boundingRect = item->boundingRect();
308 qreal w = boundingRect.width();
308 qreal w = boundingRect.width();
309 qreal h = boundingRect.height();
309 qreal h = boundingRect.height();
310 m_width = qMax(m_width,w);
310 m_width = qMax(m_width,w);
311 m_height = qMax(m_height,h);
311 m_height = qMax(m_height,h);
312 point.setX(point.x() + w);
312 point.setX(point.x() + w);
313 if (point.x() + w > geometry.left() + geometry.width() - right) {
313 if (point.x() + w > geometry.left() + geometry.width() - right) {
314 // Next item would go off rect.
314 // Next item would go off rect.
315 point.setX(0);
315 point.setX(0);
316 point.setY(point.y() + h);
316 point.setY(point.y() + h);
317 if (i+1 < markers.count()) {
317 if (i+1 < markers.count()) {
318 m_height += h;
318 m_height += h;
319 }
319 }
320 }
320 }
321 }
321 }
322 }
322 }
323 m_legend->d_ptr->items()->setPos(geometry.topLeft());
323 m_legend->d_ptr->items()->setPos(geometry.topLeft());
324
324
325 m_minOffsetX = -left;
325 m_minOffsetX = -left;
326 m_minOffsetY = -top;
326 m_minOffsetY = -top;
327 m_maxOffsetX = m_width - geometry.width() - right;
327 m_maxOffsetX = m_width - geometry.width() - right;
328 m_maxOffsetY = m_height - geometry.height() - bottom;
328 m_maxOffsetY = m_height - geometry.height() - bottom;
329 }
329 }
330 break;
330 break;
331 case Qt::AlignBottom: {
331 case Qt::AlignBottom: {
332 QPointF point(0, geometry.height());
332 QPointF point(0, geometry.height());
333 m_width = 0;
333 m_width = 0;
334 m_height = 0;
334 m_height = 0;
335 for (int i = 0; i < markers.count(); i++) {
335 for (int i = 0; i < markers.count(); i++) {
336 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
336 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
337 if (item->isVisible()) {
337 if (item->isVisible()) {
338 item->setGeometry(geometry);
338 item->setGeometry(geometry);
339 const QRectF &boundingRect = item->boundingRect();
339 const QRectF &boundingRect = item->boundingRect();
340 qreal w = boundingRect.width();
340 qreal w = boundingRect.width();
341 qreal h = boundingRect.height();
341 qreal h = boundingRect.height();
342 m_width = qMax(m_width,w);
342 m_width = qMax(m_width,w);
343 m_height = qMax(m_height,h);
343 m_height = qMax(m_height,h);
344 item->setPos(point.x(),point.y() - h);
344 item->setPos(point.x(),point.y() - h);
345 point.setX(point.x() + w);
345 point.setX(point.x() + w);
346 if (point.x() + w > geometry.left() + geometry.width() - right) {
346 if (point.x() + w > geometry.left() + geometry.width() - right) {
347 // Next item would go off rect.
347 // Next item would go off rect.
348 point.setX(0);
348 point.setX(0);
349 point.setY(point.y() - h);
349 point.setY(point.y() - h);
350 if (i+1 < markers.count()) {
350 if (i+1 < markers.count()) {
351 m_height += h;
351 m_height += h;
352 }
352 }
353 }
353 }
354 }
354 }
355 }
355 }
356 m_legend->d_ptr->items()->setPos(geometry.topLeft());
356 m_legend->d_ptr->items()->setPos(geometry.topLeft());
357
357
358 m_minOffsetX = -left;
358 m_minOffsetX = -left;
359 m_minOffsetY = -m_height + geometry.height() - top;
359 m_minOffsetY = -m_height + geometry.height() - top;
360 m_maxOffsetX = m_width - geometry.width() - right;
360 m_maxOffsetX = m_width - geometry.width() - right;
361 m_maxOffsetY = -bottom;
361 m_maxOffsetY = -bottom;
362 }
362 }
363 break;
363 break;
364 case Qt::AlignLeft: {
364 case Qt::AlignLeft: {
365 QPointF point(0, 0);
365 QPointF point(0, 0);
366 m_width = 0;
366 m_width = 0;
367 m_height = 0;
367 m_height = 0;
368 qreal maxWidth = 0;
368 qreal maxWidth = 0;
369 for (int i = 0; i < markers.count(); i++) {
369 for (int i = 0; i < markers.count(); i++) {
370 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
370 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
371 if (item->isVisible()) {
371 if (item->isVisible()) {
372 item->setGeometry(geometry);
372 item->setGeometry(geometry);
373 const QRectF &boundingRect = item->boundingRect();
373 const QRectF &boundingRect = item->boundingRect();
374 qreal w = boundingRect.width();
374 qreal w = boundingRect.width();
375 qreal h = boundingRect.height();
375 qreal h = boundingRect.height();
376 m_height = qMax(m_height,h);
376 m_height = qMax(m_height,h);
377 maxWidth = qMax(maxWidth,w);
377 maxWidth = qMax(maxWidth,w);
378 item->setPos(point.x(),point.y());
378 item->setPos(point.x(),point.y());
379 point.setY(point.y() + h);
379 point.setY(point.y() + h);
380 if (point.y() + h > geometry.bottom() - bottom) {
380 if (point.y() + h > geometry.bottom() - bottom) {
381 // Next item would go off rect.
381 // Next item would go off rect.
382 point.setX(point.x() + maxWidth);
382 point.setX(point.x() + maxWidth);
383 point.setY(0);
383 point.setY(0);
384 if (i+1 < markers.count()) {
384 if (i+1 < markers.count()) {
385 m_width += maxWidth;
385 m_width += maxWidth;
386 maxWidth = 0;
386 maxWidth = 0;
387 }
387 }
388 }
388 }
389 }
389 }
390 }
390 }
391 m_width += maxWidth;
391 m_width += maxWidth;
392 m_legend->d_ptr->items()->setPos(geometry.topLeft());
392 m_legend->d_ptr->items()->setPos(geometry.topLeft());
393
393
394 m_minOffsetX = -left;
394 m_minOffsetX = -left;
395 m_minOffsetY = -top;
395 m_minOffsetY = -top;
396 m_maxOffsetX = m_width - geometry.width() - right;
396 m_maxOffsetX = m_width - geometry.width() - right;
397 m_maxOffsetY = m_height - geometry.height() - bottom;
397 m_maxOffsetY = m_height - geometry.height() - bottom;
398 }
398 }
399 break;
399 break;
400 case Qt::AlignRight: {
400 case Qt::AlignRight: {
401 QPointF point(geometry.width(), 0);
401 QPointF point(geometry.width(), 0);
402 m_width = 0;
402 m_width = 0;
403 m_height = 0;
403 m_height = 0;
404 qreal maxWidth = 0;
404 qreal maxWidth = 0;
405 for (int i = 0; i < markers.count(); i++) {
405 for (int i = 0; i < markers.count(); i++) {
406 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
406 LegendMarkerItem *item = markers.at(i)->d_ptr->item();
407 if (item->isVisible()) {
407 if (item->isVisible()) {
408 item->setGeometry(geometry);
408 item->setGeometry(geometry);
409 const QRectF &boundingRect = item->boundingRect();
409 const QRectF &boundingRect = item->boundingRect();
410 qreal w = boundingRect.width();
410 qreal w = boundingRect.width();
411 qreal h = boundingRect.height();
411 qreal h = boundingRect.height();
412 m_height = qMax(m_height,h);
412 m_height = qMax(m_height,h);
413 maxWidth = qMax(maxWidth,w);
413 maxWidth = qMax(maxWidth,w);
414 item->setPos(point.x() - w,point.y());
414 item->setPos(point.x() - w,point.y());
415 point.setY(point.y() + h);
415 point.setY(point.y() + h);
416 if (point.y() + h > geometry.bottom()-bottom) {
416 if (point.y() + h > geometry.bottom()-bottom) {
417 // Next item would go off rect.
417 // Next item would go off rect.
418 point.setX(point.x() - maxWidth);
418 point.setX(point.x() - maxWidth);
419 point.setY(0);
419 point.setY(0);
420 if (i+1 < markers.count()) {
420 if (i+1 < markers.count()) {
421 m_width += maxWidth;
421 m_width += maxWidth;
422 maxWidth = 0;
422 maxWidth = 0;
423 }
423 }
424 }
424 }
425 }
425 }
426 }
426 }
427 m_width += maxWidth;
427 m_width += maxWidth;
428 m_legend->d_ptr->items()->setPos(geometry.topLeft());
428 m_legend->d_ptr->items()->setPos(geometry.topLeft());
429
429
430 m_minOffsetX = - m_width + geometry.width() - left;
430 m_minOffsetX = - m_width + geometry.width() - left;
431 m_minOffsetY = -top;
431 m_minOffsetY = -top;
432 m_maxOffsetX = - right;
432 m_maxOffsetX = - right;
433 m_maxOffsetY = m_height - geometry.height() - bottom;
433 m_maxOffsetY = m_height - geometry.height() - bottom;
434 }
434 }
435 break;
435 break;
436 default:
436 default:
437 break;
437 break;
438 }
438 }
439
439
440 setOffset(oldOffsetX, oldOffsetY);
440 setOffset(oldOffsetX, oldOffsetY);
441 }
441 }
442
442
443 QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
443 QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
444 {
444 {
445 QSizeF size(0, 0);
445 QSizeF size(0, 0);
446 qreal left, top, right, bottom;
446 qreal left, top, right, bottom;
447 getContentsMargins(&left, &top, &right, &bottom);
447 getContentsMargins(&left, &top, &right, &bottom);
448
448
449 if(constraint.isValid()) {
449 if(constraint.isValid()) {
450 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
450 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
451 LegendMarkerItem *item = marker->d_ptr->item();
451 LegendMarkerItem *item = marker->d_ptr->item();
452 size = size.expandedTo(item->effectiveSizeHint(which));
452 size = size.expandedTo(item->effectiveSizeHint(which));
453 }
453 }
454 size = size.boundedTo(constraint);
454 size = size.boundedTo(constraint);
455 }
455 }
456 else if (constraint.width() >= 0) {
456 else if (constraint.width() >= 0) {
457 qreal width = 0;
457 qreal width = 0;
458 qreal height = 0;
458 qreal height = 0;
459 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
459 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
460 LegendMarkerItem *item = marker->d_ptr->item();
460 LegendMarkerItem *item = marker->d_ptr->item();
461 width+=item->effectiveSizeHint(which).width();
461 width+=item->effectiveSizeHint(which).width();
462 height=qMax(height,item->effectiveSizeHint(which).height());
462 height=qMax(height,item->effectiveSizeHint(which).height());
463 }
463 }
464
464
465 size = QSizeF(qMin(constraint.width(),width), height);
465 size = QSizeF(qMin(constraint.width(),width), height);
466 }
466 }
467 else if (constraint.height() >= 0) {
467 else if (constraint.height() >= 0) {
468 qreal width = 0;
468 qreal width = 0;
469 qreal height = 0;
469 qreal height = 0;
470 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
470 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
471 LegendMarkerItem *item = marker->d_ptr->item();
471 LegendMarkerItem *item = marker->d_ptr->item();
472 width=qMax(width,item->effectiveSizeHint(which).width());
472 width=qMax(width,item->effectiveSizeHint(which).width());
473 height+=height,item->effectiveSizeHint(which).height();
473 height+=height,item->effectiveSizeHint(which).height();
474 }
474 }
475 size = QSizeF(width,qMin(constraint.height(),height));
475 size = QSizeF(width,qMin(constraint.height(),height));
476 }
476 }
477 else {
477 else {
478 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
478 foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
479 LegendMarkerItem *item = marker->d_ptr->item();
479 LegendMarkerItem *item = marker->d_ptr->item();
480 size = size.expandedTo(item->effectiveSizeHint(which));
480 size = size.expandedTo(item->effectiveSizeHint(which));
481 }
481 }
482 }
482 }
483 size += QSize(left + right, top + bottom);
483 size += QSize(left + right, top + bottom);
484 return size;
484 return size;
485 }
485 }
486
486
487 bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1,
487 bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1,
488 const LegendWidthStruct *item2)
488 const LegendWidthStruct *item2)
489 {
489 {
490 return item1->width > item2->width;
490 return item1->width > item2->width;
491 }
491 }
492
492
493 QTCOMMERCIALCHART_END_NAMESPACE
493 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now