@@ -136,19 +136,97 void LegendLayout::setAttachedGeometry(const QRectF &rect) | |||
|
136 | 136 | switch(m_legend->alignment()) { |
|
137 | 137 | case Qt::AlignTop: |
|
138 | 138 | case Qt::AlignBottom: { |
|
139 | // Calculate the space required for items and add them to a sorted list. | |
|
140 | qreal markerItemsWidth = 0; | |
|
141 | qreal itemMargins = 0; | |
|
142 | QList<LegendWidthStruct *> legendWidthList; | |
|
143 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { | |
|
144 | LegendMarkerItem *item = marker->d_ptr->item(); | |
|
145 | if (item->isVisible()) { | |
|
146 | QSizeF dummySize; | |
|
147 | qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width(); | |
|
148 | LegendWidthStruct *structItem = new LegendWidthStruct; | |
|
149 | structItem->item = item; | |
|
150 | structItem->width = itemWidth; | |
|
151 | legendWidthList.append(structItem); | |
|
152 | markerItemsWidth += itemWidth; | |
|
153 | itemMargins += marker->d_ptr->item()->m_margin; | |
|
154 | } | |
|
155 | } | |
|
156 | qSort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan); | |
|
157 | ||
|
158 | // If the items would occupy more space than is available, start truncating them | |
|
159 | // from the longest one. | |
|
160 | qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins; | |
|
161 | if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 1) { | |
|
162 | bool truncated(false); | |
|
163 | int count = legendWidthList.count(); | |
|
164 | for (int i = 1; i < count; i++) { | |
|
165 | int truncateIndex = i - 1; | |
|
166 | ||
|
167 | while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width | |
|
168 | && !truncated) { | |
|
169 | legendWidthList.at(truncateIndex)->width--; | |
|
170 | markerItemsWidth--; | |
|
171 | if (i > 1) { | |
|
172 | // Truncate the items that are before the truncated one in the list. | |
|
173 | for (int j = truncateIndex - 1; j >= 0; j--) { | |
|
174 | if (legendWidthList.at(truncateIndex)->width | |
|
175 | < legendWidthList.at(j)->width) { | |
|
176 | legendWidthList.at(j)->width--; | |
|
177 | markerItemsWidth--; | |
|
178 | } | |
|
179 | } | |
|
180 | } | |
|
181 | if (markerItemsWidth < availableGeometry) | |
|
182 | truncated = true; | |
|
183 | } | |
|
184 | // Truncate the last item if needed. | |
|
185 | if (i == count - 1) { | |
|
186 | if (legendWidthList.at(count - 1)->width | |
|
187 | > legendWidthList.at(truncateIndex)->width) { | |
|
188 | legendWidthList.at(count - 1)->width--; | |
|
189 | markerItemsWidth--; | |
|
190 | } | |
|
191 | } | |
|
192 | ||
|
193 | if (truncated) | |
|
194 | break; | |
|
195 | } | |
|
196 | // Items are of same width and all of them need to be truncated. | |
|
197 | while (markerItemsWidth >= availableGeometry) { | |
|
198 | for (int i = 0; i < count; i++) { | |
|
199 | legendWidthList.at(i)->width--; | |
|
200 | markerItemsWidth--; | |
|
201 | } | |
|
202 | } | |
|
203 | } | |
|
204 | ||
|
139 | 205 | QPointF point(0,0); |
|
140 | 206 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
141 | 207 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
142 | 208 | if (item->isVisible()) { |
|
143 |
|
|
|
209 | QRectF itemRect = geometry; | |
|
210 | qreal availableWidth = 0; | |
|
211 | for (int i = 0; i < legendWidthList.size(); ++i) { | |
|
212 | if (legendWidthList.at(i)->item == item) { | |
|
213 | availableWidth = legendWidthList.at(i)->width; | |
|
214 | break; | |
|
215 | } | |
|
216 | } | |
|
217 | itemRect.setWidth(availableWidth); | |
|
218 | item->setGeometry(itemRect); | |
|
144 | 219 | item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2); |
|
145 | 220 | const QRectF &rect = item->boundingRect(); |
|
146 | 221 | size = size.expandedTo(rect.size()); |
|
147 | 222 | qreal w = rect.width(); |
|
148 |
m_width+ |
|
|
223 | m_width = m_width + w - item->m_margin; | |
|
149 | 224 | point.setX(point.x() + w); |
|
150 | 225 | } |
|
151 | 226 | } |
|
227 | // Delete structs from the container | |
|
228 | qDeleteAll(legendWidthList); | |
|
229 | ||
|
152 | 230 | if (m_width < geometry.width()) |
|
153 | 231 | m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top()); |
|
154 | 232 | else |
@@ -405,4 +483,10 QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) cons | |||
|
405 | 483 | return size; |
|
406 | 484 | } |
|
407 | 485 | |
|
486 | bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1, | |
|
487 | const LegendWidthStruct *item2) | |
|
488 | { | |
|
489 | return item1->width > item2->width; | |
|
490 | } | |
|
491 | ||
|
408 | 492 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -35,6 +35,7 | |||
|
35 | 35 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
36 | 36 | |
|
37 | 37 | class QLegend; |
|
38 | class LegendMarkerItem; | |
|
38 | 39 | |
|
39 | 40 | class LegendLayout : public QGraphicsLayout |
|
40 | 41 | { |
@@ -59,6 +60,13 private: | |||
|
59 | 60 | void setAttachedGeometry(const QRectF &rect); |
|
60 | 61 | void setDettachedGeometry(const QRectF &rect); |
|
61 | 62 | |
|
63 | struct LegendWidthStruct { | |
|
64 | LegendMarkerItem *item; | |
|
65 | qreal width; | |
|
66 | }; | |
|
67 | static bool widthLongerThan(const LegendWidthStruct *item1, | |
|
68 | const LegendWidthStruct *item2); | |
|
69 | ||
|
62 | 70 | private: |
|
63 | 71 | QLegend *m_legend; |
|
64 | 72 | qreal m_offsetX; |
General Comments 0
You need to be logged in to leave comments.
Login now