#include "ElaFlowLayoutPrivate.h" #include #include #include "ElaFlowLayout.h" ElaFlowLayoutPrivate::ElaFlowLayoutPrivate(QObject *parent) : QObject{parent} {} ElaFlowLayoutPrivate::~ElaFlowLayoutPrivate() {} int ElaFlowLayoutPrivate::_doLayout(const QRect &rect, bool testOnly) const { Q_Q(const ElaFlowLayout); int left, top, right, bottom; q->getContentsMargins(&left, &top, &right, &bottom); QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); int x = effectiveRect.x(); int y = effectiveRect.y(); int lineHeight = 0; for (QLayoutItem *item : std::as_const(_itemList)) { const QWidget *wid = item->widget(); int spaceX = q->horizontalSpacing(); if (spaceX == -1) { spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); } int spaceY = q->verticalSpacing(); if (spaceY == -1) { spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); } int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; } if (!_lastGeometryMap.contains(item)) { _lastGeometryMap.insert(item, QPoint(x, y)); } if (!testOnly) { if ((item->geometry().x() == 0 && item->geometry().y() == 0)) { item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); } else if (item->geometry().x() != x || item->geometry().y() != y) { if (_isAnimation) { // 阻止多重动画 if (_lastGeometryMap[item] == QPoint(x, y)) { lineHeight = qMax(lineHeight, item->sizeHint().height()); return y + lineHeight - rect.y() + bottom; } QPropertyAnimation *geometryAnimation = new QPropertyAnimation(item->widget(), "geometry"); geometryAnimation->setStartValue(item->widget()->geometry()); geometryAnimation->setEndValue(QRect(QPoint(x, y), item->sizeHint())); geometryAnimation->setDuration(300); geometryAnimation->setEasingCurve(QEasingCurve::InOutSine); geometryAnimation->start(QAbstractAnimation::DeleteWhenStopped); _lastGeometryMap[item] = QPoint(x, y); } else { item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); } } } x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y() + bottom; } int ElaFlowLayoutPrivate::_smartSpacing(QStyle::PixelMetric pm) const { Q_Q(const ElaFlowLayout); QObject *parent = q->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { QWidget *pw = static_cast(parent); return pw->style()->pixelMetric(pm, nullptr, pw); } else { return static_cast(parent)->spacing(); } }