@@ -136,19 +136,97 void LegendLayout::setAttachedGeometry(const QRectF &rect) | |||||
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. | |||
|
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 | QPointF point(0,0); |
|
205 | QPointF point(0,0); | |
140 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { |
|
206 | foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) { | |
141 | LegendMarkerItem *item = marker->d_ptr->item(); |
|
207 | LegendMarkerItem *item = marker->d_ptr->item(); | |
142 | if (item->isVisible()) { |
|
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 | item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2); |
|
219 | item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2); | |
145 | const QRectF &rect = item->boundingRect(); |
|
220 | const QRectF &rect = item->boundingRect(); | |
146 | size = size.expandedTo(rect.size()); |
|
221 | size = size.expandedTo(rect.size()); | |
147 | qreal w = rect.width(); |
|
222 | qreal w = rect.width(); | |
148 |
m_width+ |
|
223 | m_width = m_width + w - item->m_margin; | |
149 | point.setX(point.x() + w); |
|
224 | point.setX(point.x() + w); | |
150 | } |
|
225 | } | |
151 | } |
|
226 | } | |
|
227 | // Delete structs from the container | |||
|
228 | qDeleteAll(legendWidthList); | |||
|
229 | ||||
152 | if (m_width < geometry.width()) |
|
230 | if (m_width < geometry.width()) | |
153 | m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top()); |
|
231 | m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top()); | |
154 | else |
|
232 | else | |
@@ -405,4 +483,10 QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) cons | |||||
405 | return size; |
|
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 | QTCOMMERCIALCHART_END_NAMESPACE |
|
492 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -35,6 +35,7 | |||||
35 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
35 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
36 |
|
36 | |||
37 | class QLegend; |
|
37 | class QLegend; | |
|
38 | class LegendMarkerItem; | |||
38 |
|
39 | |||
39 | class LegendLayout : public QGraphicsLayout |
|
40 | class LegendLayout : public QGraphicsLayout | |
40 | { |
|
41 | { | |
@@ -59,6 +60,13 private: | |||||
59 | void setAttachedGeometry(const QRectF &rect); |
|
60 | void setAttachedGeometry(const QRectF &rect); | |
60 | void setDettachedGeometry(const QRectF &rect); |
|
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 | private: |
|
70 | private: | |
63 | QLegend *m_legend; |
|
71 | QLegend *m_legend; | |
64 | qreal m_offsetX; |
|
72 | qreal m_offsetX; |
General Comments 0
You need to be logged in to leave comments.
Login now