2 #include "flowlayout.h"
6 FlowLayoutItem() : item(0) {}
7 FlowLayoutItem(QLayoutItem
*item
, int x
, int y
) : item(item
), pos(x
, y
) {}
13 FlowLayout::FlowLayout(QWidget
*parent
, int margin
, int hSpacing
, int vSpacing
)
14 : QLayout(parent
), _hSpace(hSpacing
), _vSpace(vSpacing
)
16 setContentsMargins(margin
, margin
, margin
, margin
);
19 FlowLayout::FlowLayout(int margin
, int hSpacing
, int vSpacing
)
20 : _hSpace(hSpacing
), _vSpace(vSpacing
)
22 setContentsMargins(margin
, margin
, margin
, margin
);
25 FlowLayout::~FlowLayout()
30 void FlowLayout::addItem(QLayoutItem
*item
)
35 int FlowLayout::horizontalSpacing() const
39 : smartSpacing(QStyle::PM_LayoutHorizontalSpacing
);
42 int FlowLayout::verticalSpacing() const
46 : smartSpacing(QStyle::PM_LayoutVerticalSpacing
);
49 int FlowLayout::count() const
54 QLayoutItem
*FlowLayout::itemAt(int index
) const
56 return _items
.value(index
);
59 QLayoutItem
*FlowLayout::takeAt(int index
)
61 if (index
>= 0 && index
< _items
.size())
62 return _items
.takeAt(index
);
67 Qt::Orientations
FlowLayout::expandingDirections() const
72 bool FlowLayout::hasHeightForWidth() const
77 int FlowLayout::heightForWidth(int width
) const
79 int height
= doLayout(QRect(0, 0, width
, 0), true);
83 void FlowLayout::setGeometry(const QRect
&rect
)
85 QLayout::setGeometry(rect
);
86 doLayout(rect
, false);
89 QSize
FlowLayout::sizeHint() const
94 QSize
FlowLayout::minimumSize() const
98 for (int i
= 0; i
< _items
.size(); i
++)
99 size
= size
.expandedTo(_items
.at(i
)->minimumSize());
101 const QMargins margins
= contentsMargins();
102 size
+= QSize(margins
.left() + margins
.right(), margins
.top()
108 int FlowLayout::doLayout(const QRect
&rect
, bool testOnly
) const
110 int left
, top
, right
, bottom
;
111 getContentsMargins(&left
, &top
, &right
, &bottom
);
112 QRect effectiveRect
= rect
.adjusted(+left
, +top
, -right
, -bottom
);
113 int x
= effectiveRect
.x();
114 int y
= effectiveRect
.y();
116 QVector
<QVector
<FlowLayoutItem
>> rows
;
118 for (int i
= 0; i
< _items
.size(); i
++) {
119 QLayoutItem
*item
= _items
.at(i
);
120 const QWidget
*wid
= item
->widget();
121 int spaceX
= horizontalSpacing();
123 spaceX
= wid
->style()->layoutSpacing(QSizePolicy::PushButton
,
124 QSizePolicy::PushButton
, Qt::Horizontal
);
125 int spaceY
= verticalSpacing();
127 spaceY
= wid
->style()->layoutSpacing(QSizePolicy::PushButton
,
128 QSizePolicy::PushButton
, Qt::Vertical
);
130 int nextX
= x
+ item
->sizeHint().width() + spaceX
;
131 if (nextX
- spaceX
> effectiveRect
.right() && lineHeight
> 0) {
132 x
= effectiveRect
.x();
133 y
= y
+ lineHeight
+ spaceY
;
134 nextX
= x
+ item
->sizeHint().width() + spaceX
;
136 rows
.append(QVector
<FlowLayoutItem
>());
140 rows
.append(QVector
<FlowLayoutItem
>());
141 rows
.last().append(FlowLayoutItem(item
, x
, y
));
144 lineHeight
= qMax(lineHeight
, item
->sizeHint().height());
148 for (int i
= 0; i
< rows
.size(); i
++) {
149 const FlowLayoutItem
&li
= rows
.at(i
).last();
150 int width
= li
.item
->sizeHint().width() + li
.pos
.x()
152 int offset
= (effectiveRect
.width() - width
) / 2;
155 for (int j
= 0; j
< rows
.at(i
).size(); j
++)
156 height
= qMax(rows
.at(i
).at(j
).item
->sizeHint().height(), height
);
158 for (int j
= 0; j
< rows
.at(i
).size(); j
++) {
159 QLayoutItem
*item
= rows
.at(i
).at(j
).item
;
160 const QPoint
&p
= rows
.at(i
).at(j
).pos
;
161 QSize
sh(item
->sizeHint());
162 item
->setGeometry(QRect(QPoint(p
.x() + offset
, p
.y() + height
163 - sh
.height()), sh
));
168 return y
+ lineHeight
- rect
.y() + bottom
;
171 int FlowLayout::smartSpacing(QStyle::PixelMetric pm
) const
173 QObject
*parent
= this->parent();
176 else if (parent
->isWidgetType()) {
177 QWidget
*pw
= static_cast<QWidget
*>(parent
);
178 return pw
->style()->pixelMetric(pm
, 0, pw
);
180 return static_cast<QLayout
*>(parent
)->spacing();