#include "flowlayout.h" #include #include FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) : QLayout(parent), m_hSpacing(hSpacing), m_vSpacing(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::~FlowLayout() { QLayoutItem *item; while ((item = takeAt(0))) { delete item; } } void FlowLayout::clear() { while (QLayoutItem *item = takeAt(0)) { if (item->widget()) { item->widget()->hide(); } delete item; } } void FlowLayout::addItem(QLayoutItem *item) { m_items.append(item); } int FlowLayout::count() const { return m_items.size(); } QLayoutItem *FlowLayout::itemAt(int index) const { return m_items.value(index); } QLayoutItem *FlowLayout::takeAt(int index) { return (index >= 0 && index < m_items.size()) ? m_items.takeAt(index) : nullptr; } Qt::Orientations FlowLayout::expandingDirections() const { return Qt::Orientation(0); } bool FlowLayout::hasHeightForWidth() const { return true; } int FlowLayout::heightForWidth(int width) const { return doLayout(QRect(0, 0, width, 0), true); } void FlowLayout::setGeometry(const QRect &rect) { QLayout::setGeometry(rect); doLayout(rect, false); } QSize FlowLayout::sizeHint() const { return minimumSize(); } QSize FlowLayout::minimumSize() const { QSize size; for (const QLayoutItem *item : std::as_const(m_items)) { size = size.expandedTo(item->minimumSize()); } const QMargins margins = contentsMargins(); size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); return size; } int FlowLayout::doLayout(const QRect &rect, bool testOnly) const { int x = rect.x(); int y = rect.y(); int lineHeight = 0; for (QLayoutItem *item : std::as_const(m_items)) { int spaceX = horizontalSpacing(); int spaceY = verticalSpacing(); int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > rect.right() && lineHeight > 0) { x = rect.x(); y += lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; } if (!testOnly) { item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); } x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y(); } int FlowLayout::horizontalSpacing() const { return (m_hSpacing >= 0) ? m_hSpacing : smartSpacing(QStyle::PM_LayoutHorizontalSpacing); } int FlowLayout::verticalSpacing() const { return (m_vSpacing >= 0) ? m_vSpacing : smartSpacing(QStyle::PM_LayoutVerticalSpacing); } int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { QObject *parent = this->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { return static_cast(parent)->style()->pixelMetric(pm, nullptr, static_cast(parent)); } else { return static_cast(parent)->spacing(); } }