73#include "flowlayout.h"
75FlowLayout::FlowLayout(
QWidget *parent,
int margin,
int hSpacing,
int vSpacing)
76 :
QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
78 setContentsMargins(margin, margin, margin, margin);
81FlowLayout::FlowLayout(
int margin,
int hSpacing,
int vSpacing)
82 :
FlowLayout(nullptr, margin, hSpacing, vSpacing)
85FlowLayout::~FlowLayout()
88 while ((item = takeAt(0)))
97int FlowLayout::horizontalSpacing()
const
106int FlowLayout::verticalSpacing()
const
115int FlowLayout::count()
const
117 return itemList.
size();
122 return itemList.
value(index);
127 if (index >= 0 && index < itemList.
size())
128 return itemList.
takeAt(index);
133bool FlowLayout::hasHeightForWidth()
const
143int FlowLayout::heightForWidth(
int width)
const
145 return calculateHeightForWidth(width);
148void FlowLayout::setGeometry(
const QRect &rect)
151 mNumberOfRows = applyLayout(rect);
154QSize FlowLayout::sizeHint()
const
156 return minimumSize();
159QSize FlowLayout::minimumSize()
const
163 foreach (item, itemList)
167 size +=
QSize(left + right, top + bottom);
171RowLayoutInfo FlowLayout::alignJustifiedRow(
int startIndex,
int count,
const QRect& effectiveRect,
int spaceX)
const
176 int gapCount = count + 1;
177 int rowWidth = calculateRowWidth(startIndex, count, spaceX);
178 int availableSpace = effectiveRect.
width() - rowWidth;
180 spacing = (gapCount > 0 && availableSpace > 0)
181 ? availableSpace / gapCount
190 row.startIndex = startIndex;
191 row.spacing = spaceX +
spacing;
193 for (
int j = startIndex; j < startIndex + count; j += 1) {
197 itemX += row.spacing + itemSize.
width();
203RowLayoutInfo FlowLayout::alignHCenterRow(
int startIndex,
int count,
const QRect &effectiveRect,
int spaceX)
const
205 int rowWidth = calculateRowWidth(startIndex, count, spaceX);
206 int offset = (effectiveRect.
width() - rowWidth) / 2;
207 int rowOffsetX = effectiveRect.
left() + offset;
211 row.startX = rowOffsetX;
212 row.startIndex = startIndex;
213 row.spacing = spaceX;
215 for (
int i = startIndex; i < startIndex + count; i += 1) {
220 rowOffsetX += row.spacing + itemSize.
width();
226int FlowLayout::calculateHeightForWidth(
int width)
const
234 int spaceX = horizontalSpacing();
235 int spaceY = verticalSpacing();
239 for (
int i = 0; i < itemList.
length(); i++) {
242 int rowWidth = calculateRowWidth(0, rowCount, spaceX);
251 if (rowWidth + item->
sizeHint().
width() + spaceX >= width && lineHeight > 0) {
254 y += lineHeight + spaceY;
264 return lineHeight + y + top + bottom;
267int FlowLayout::applyLayout(
const QRect &rect)
const
272 int spaceX = horizontalSpacing();
273 int spaceY = verticalSpacing();
275 QRect effectiveRect = rect.
adjusted(+left, +top, -right, -bottom);
276 int x = effectiveRect.
x();
277 int y = effectiveRect.
y();
284 int currentRowCount = 0;
287 for (
int i = 0; i < itemList.
length(); i += 1) {
288 item = itemList.
at(i);
298 int startRowIndex = i - currentRowCount;
299 int rowWidth = calculateRowWidth(startRowIndex, currentRowCount, spaceX);
301 if (currentRowCount > 0) {
302 maxRowCount = qMax(currentRowCount, maxRowCount);
306 rowAlignments.
append(alignHCenterRow(startRowIndex, currentRowCount, effectiveRect, spaceX));
308 rowAlignments.
append(alignJustifiedRow(startRowIndex, currentRowCount, effectiveRect, spaceX));
311 y = y + lineHeight + spaceY;
320 currentRowCount += 1;
323 if (maxRowCount == itemList.
length() - 1) {
324 alignHCenterRow(itemList.
length() - currentRowCount, currentRowCount, effectiveRect, spaceX);
325 }
else if (currentRowCount > 0) {
326 lastLineAlignment(itemList.
length() - currentRowCount, currentRowCount, rowAlignments.
last(), effectiveRect);
332void FlowLayout::lastLineAlignment(
int startIndex,
int count,
RowLayoutInfo rowInfo,
const QRect& effectiveRect)
const
335 alignHCenterRow(startIndex, count, effectiveRect, rowInfo.spacing);
337 alignJustifiedRow(startIndex, count, effectiveRect, rowInfo.spacing);
341int FlowLayout::calculateRowWidth(
int start,
int end,
int spacing)
const
343 if (itemList.
isEmpty()) {
return 0; }
347 for (
int i = start; i < start + end; i += 1) {
351 return totalWidth + (
spacing * (end - 1));
void getContentsMargins(int *left, int *top, int *right, int *bottom) const const
virtual void setGeometry(const QRect &r) override
Qt::Alignment alignment() const const
virtual QRect geometry() const const=0
virtual QSize minimumSize() const const=0
virtual void setGeometry(const QRect &r)=0
virtual QSize sizeHint() const const=0
void append(const T &value)
const T & at(int i) const const
bool isEmpty() const const
T value(int i) const const
QObject * parent() const const
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
QSize expandedTo(const QSize &otherSize) const const
PM_LayoutHorizontalSpacing
virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const const=0
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
void append(const T &value)