diff options
author | Thorbjørn Lund Martsum <[email protected]> | 2024-08-19 14:41:55 +0200 |
---|---|---|
committer | Thorbjørn Lund Martsum <[email protected]> | 2025-05-15 23:55:03 +0200 |
commit | 5b33c4e84ce23f1d7720306f4f01e771ac8be2e3 (patch) | |
tree | d720fc486c84fe0e57bf5483917cc75721f07e59 | |
parent | bf38ab9990f30151c148dbff77c8c9bf3982f097 (diff) |
QLayout - Introduce vertical and horizontal layout constraints
In most situations the simple setSizeConstraint is
sufficient to get the sizeConstaint the user wants.
However in certain other situations the QLayout size constraint
demanding same vertical and horizontal behavior could simply
be extremely annoying.
This patch fixes a design-flaw as it makes perfectly sense
to have a fixed sized or minimum size constraint in one
orientation and having it something else (e.g minMax) in
the another.
Likely the old logic was that the user could use
setMinimumWidth and setMaximumWidth on the widget itself
(and similar for height) to get this behavior, but on 2+ monitor
systems with different DPR that is not really an option
(at least not a good one).
[ChangeLog][QWidgets][QLayout] Introduced a vertical and horizontal
size constraint in layout as the size constraint behavior can depend on
the orientation.
Fixes: QTBUG-17730
Change-Id: I8aefcd2b4df228494604b41e8ab7319e9f599d07
Reviewed-by: Richard Moe Gustavsen <[email protected]>
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 277 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.h | 15 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout_p.h | 3 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp | 285 |
4 files changed, 513 insertions, 67 deletions
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index ec28581b041..c8b87540bfc 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -109,7 +109,7 @@ QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w) QLayoutPrivate::QLayoutPrivate() : QObjectPrivate(), insideSpacing(-1), userLeftMargin(-1), userTopMargin(-1), userRightMargin(-1), userBottomMargin(-1), topLevel(false), enabled(true), activated(true), autoNewChild(false), - constraint(QLayout::SetDefaultConstraint), menubar(nullptr) + horizontalConstraint(QLayout::SetDefaultConstraint), verticalConstraint(QLayout::SetDefaultConstraint), menubar(nullptr) { } @@ -841,13 +841,6 @@ void QLayout::addChildWidget(QWidget *w) QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later } - - - - - - - /*! Tells the geometry manager to place the menu bar \a widget at the top of parentWidget(), outside QWidget::contentsMargins(). All @@ -987,43 +980,127 @@ bool QLayout::activate() uint explMin = md->extra ? md->extra->explicitMinSize : 0; uint explMax = md->extra ? md->extra->explicitMaxSize : 0; - switch (d->constraint) { - case SetFixedSize: - // will trigger resize - mw->setFixedSize(totalSizeHint()); - break; - case SetMinimumSize: - mw->setMinimumSize(totalMinimumSize()); - break; - case SetMaximumSize: - mw->setMaximumSize(totalMaximumSize()); - break; - case SetMinAndMaxSize: - mw->setMinimumSize(totalMinimumSize()); - mw->setMaximumSize(totalMaximumSize()); - break; - case SetDefaultConstraint: { - bool widthSet = explMin & Qt::Horizontal; - bool heightSet = explMin & Qt::Vertical; - if (mw->isWindow()) { - QSize ms = totalMinimumSize(); - if (widthSet) - ms.setWidth(mw->minimumSize().width()); - if (heightSet) - ms.setHeight(mw->minimumSize().height()); - mw->setMinimumSize(ms); - } else if (!widthSet || !heightSet) { - QSize ms = mw->minimumSize(); - if (!widthSet) - ms.setWidth(0); - if (!heightSet) - ms.setHeight(0); - mw->setMinimumSize(ms); + // Do actual calculation + // Result values (needs to be zero or greater to be considered valid/set) + // We make some illegal values different from each other due a later compare. + // ### In the future we may want minSize(0, 0) and maxSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) + // ### Also see comment below. + QSize minSize(-1, -1); + QSize maxSize(-2, -2); + + // Potentially cached values to avoid calling the same function more times. + constexpr QSize empty(0, 0); + QSize totalSzH = empty; + QSize totalMinSz = empty; + QSize totalMaxSz = empty; + + switch (d->verticalConstraint) { + case SetFixedSize: + totalSzH = totalSizeHint(); + minSize.setHeight(totalSzH.height()); + maxSize.setHeight(totalSzH.height()); + break; + case SetMinimumSize: + totalMinSz = totalMinimumSize(); + minSize.setHeight(totalMinSz.height()); + break; + case SetMaximumSize: + totalMaxSz = totalMaximumSize(); + maxSize.setHeight(totalMaxSz.height()); + break; + case SetMinAndMaxSize: + totalMinSz = totalMinimumSize(); + totalMaxSz = totalMaximumSize(); + minSize.setHeight(totalMinSz.height()); + maxSize.setHeight(totalMaxSz.height()); + break; + case SetDefaultConstraint: { + bool heightSet = explMin & Qt::Vertical; + if (mw->isWindow()) { + if (!heightSet) { + totalMinSz = totalMinimumSize(); + minSize.setHeight(totalMinSz.height()); + } else { + minSize.setHeight(mw->minimumHeight()); + } + } else { + minSize.setHeight(heightSet ? mw->minimumHeight() : 0); + } + break; } - break; + case SetNoConstraint: + break; } - case SetNoConstraint: - break; + switch (d->horizontalConstraint) { + case SetFixedSize: + if (totalSzH == empty) + totalSzH = totalSizeHint(); + minSize.setWidth(totalSzH.width()); + maxSize.setWidth(totalSzH.width()); + break; + case SetMinimumSize: + if (totalMinSz == empty) + totalMinSz = totalMinimumSize(); + minSize.setWidth(totalMinSz.width()); + break; + case SetMaximumSize: + if (totalMaxSz == empty) + totalMaxSz = totalMaximumSize(); + maxSize.setWidth(totalMaxSz.width()); + break; + case SetMinAndMaxSize: + if (totalMinSz == empty) + totalMinSz = totalMinimumSize(); + if (totalMaxSz == empty) + totalMaxSz = totalMaximumSize(); + + minSize.setWidth(totalMinSz.width()); + maxSize.setWidth(totalMaxSz.width()); + break; + case SetDefaultConstraint: { + const bool widthSet = explMin & Qt::Horizontal; + if (mw->isWindow()) { + if (!widthSet) { + if (totalMinSz == empty) + totalMinSz = totalMinimumSize(); + minSize.setWidth(totalMinSz.width()); + } else { + minSize.setWidth(mw->minimumWidth()); + } + } else { + minSize.setWidth(widthSet ? mw->minimumWidth() : 0); + } + break; + } + case SetNoConstraint: + break; + } + if (minSize == maxSize) { + mw->setFixedSize(minSize); + } + else { + // ### To preserve backward compatibility with behavior prior to introducing separate + // ### horizontal and vertical constraints, we only update the specific size properties + // ### dictated by the constraints. For example, if only minimum width is specified + // ### by the constraint, we leave the minimum height untouched. + // ### Like before we leave unconstrained values unchanged though it can + // ### (unintentionally?) retain stale values. + + // handle min-size + if (minSize.isValid()) + mw->setMinimumSize(minSize); + else if (minSize.width() >= 0) + mw->setMinimumWidth(minSize.width()); + else if (minSize.height() >= 0) + mw->setMinimumHeight(minSize.height()); + + // handle max-size + if (maxSize.isValid()) + mw->setMaximumSize(maxSize); + else if (maxSize.width() >= 0) + mw->setMaximumWidth(maxSize.width()); + else if (maxSize.height() >= 0) + mw->setMaximumHeight(maxSize.height()); } d->doResize(); @@ -1181,51 +1258,127 @@ int QLayout::indexOf(const QLayoutItem *layoutItem) const /*! \enum QLayout::SizeConstraint + Describes how the layout constrains the size of the widget. + + A vertical constraint affects the widget's height, while a horizontal constraint affects its width. The possible values are: - \value SetDefaultConstraint The main widget's minimum size is set - to minimumSize(), unless the widget already has - a minimum size. + \value SetDefaultConstraint + In the constrained orientation(s), the widget’s minimum extent + is set to \l minimumSize(), unless a minimum size has already been set. + + \value SetFixedSize + In the constrained orientation(s), the widget’s extent is set to + \l sizeHint(), and it cannot be resized in that direction. - \value SetFixedSize The main widget's size is set to sizeHint(); it - cannot be resized at all. - \value SetMinimumSize The main widget's minimum size is set to - minimumSize(); it cannot be smaller. + \value SetMinimumSize + In the constrained orientation(s), the widget’s minimum extent + is set to \l minimumSize(). - \value SetMaximumSize The main widget's maximum size is set to - maximumSize(); it cannot be larger. + \value SetMaximumSize + In the constrained orientation(s), the widget’s maximum extent + is set to \l maximumSize(). - \value SetMinAndMaxSize The main widget's minimum size is set to - minimumSize() and its maximum size is set to - maximumSize(). + \value SetMinAndMaxSize + In the constrained orientation(s), the widget’s minimum extent + is set to \l minimumSize(), and the maximum extent is set to \l maximumSize(). - \value SetNoConstraint The widget is not constrained. + \value SetNoConstraint + No size constraints are applied to the widget. - \sa setSizeConstraint() + \sa setSizeConstraint(), setSizeConstraints(), horizontalSizeConstraint(), setHorizontalSizeConstraint(), setVerticalSizeConstraint() */ /*! \property QLayout::sizeConstraint - \brief the resize mode of the layout + \brief the resize mode of the layout. + Setting the size constraint for the dialog. + Setting a vertical or horizontal size constraint will override this. The default mode is \l {QLayout::SetDefaultConstraint} {SetDefaultConstraint}. + + \sa horizontalSizeConstraint(), verticalSizeConstraint() */ + void QLayout::setSizeConstraint(SizeConstraint constraint) { + setSizeConstraints(constraint, constraint); +} + +/*! + * \brief the resize mode of the layout. + * \since 6.10 + * Sets both the \a horizontal and \a vertical size constraint. + * Provided for convenience. + * \sa sizeConstraint(), horizontalSizeConstraint(), verticalSizeConstraint() + */ +void QLayout::setSizeConstraints(SizeConstraint horizontal, SizeConstraint vertical) +{ Q_D(QLayout); - if (constraint == d->constraint) + if (horizontal == d->horizontalConstraint && vertical == d->verticalConstraint) return; - - d->constraint = constraint; + d->horizontalConstraint = horizontal; + d->verticalConstraint = vertical; invalidate(); } QLayout::SizeConstraint QLayout::sizeConstraint() const { Q_D(const QLayout); - return d->constraint; + return d->horizontalConstraint; +} + +/*! + \property QLayout::horizontalSizeConstraint + \since 6.10 + \brief The horizontal size constraint. + + The default mode is \l {QLayout::SetDefaultConstraint} + + \sa verticalSizeConstraint(), sizeConstraint() +*/ + +void QLayout::setHorizontalSizeConstraint(SizeConstraint constraint) +{ + Q_D(QLayout); + if (constraint == d->horizontalConstraint) + return; + d->horizontalConstraint = constraint; + invalidate(); +} + + +QLayout::SizeConstraint QLayout::horizontalSizeConstraint() const +{ + Q_D(const QLayout); + return d->horizontalConstraint; +} + +/*! + \property QLayout::verticalSizeConstraint + \since 6.10 + \brief The vertical size constraint. + + The default mode is \l {QLayout::SetDefaultConstraint} + + \sa horizontalSizeConstraint(), sizeConstraint() +*/ + +void QLayout::setVerticalSizeConstraint(SizeConstraint constraint) +{ + Q_D(QLayout); + if (constraint == d->verticalConstraint) + return; + d->verticalConstraint = constraint; + invalidate(); +} + +QLayout::SizeConstraint QLayout::verticalSizeConstraint() const +{ + Q_D(const QLayout); + return d->verticalConstraint; } /*! diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index ee7b5e047cf..3d0560fd78e 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -30,7 +30,11 @@ class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem Q_PROPERTY(int spacing READ spacing WRITE setSpacing) Q_PROPERTY(QMargins contentsMargins READ contentsMargins WRITE setContentsMargins RESET unsetContentsMargins) + Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint) + Q_PROPERTY(SizeConstraint horizontalSizeConstraint READ horizontalSizeConstraint WRITE setHorizontalSizeConstraint) + Q_PROPERTY(SizeConstraint verticalSizeConstraint READ verticalSizeConstraint WRITE setVerticalSizeConstraint) + public: enum SizeConstraint { SetDefaultConstraint, @@ -59,8 +63,17 @@ public: bool setAlignment(QLayout *l, Qt::Alignment alignment); using QLayoutItem::setAlignment; - void setSizeConstraint(SizeConstraint); + void setSizeConstraint(SizeConstraint constraint); SizeConstraint sizeConstraint() const; + + void setSizeConstraints(SizeConstraint horizontal, SizeConstraint vertical); + + void setHorizontalSizeConstraint(SizeConstraint constraint); + SizeConstraint horizontalSizeConstraint() const; + + void setVerticalSizeConstraint(SizeConstraint constraint); + SizeConstraint verticalSizeConstraint() const; + void setMenuBar(QWidget *w); QWidget *menuBar() const; diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h index cd40a98fb7d..c1f0288c94d 100644 --- a/src/widgets/kernel/qlayout_p.h +++ b/src/widgets/kernel/qlayout_p.h @@ -58,7 +58,8 @@ public: uint enabled : 1; uint activated : 1; uint autoNewChild : 1; - QLayout::SizeConstraint constraint; + QLayout::SizeConstraint horizontalConstraint; + QLayout::SizeConstraint verticalConstraint; QRect rect; QWidget *menubar; }; diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index ff19d4ff657..a5a146c1486 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -24,6 +24,62 @@ #include <QtCore/qscopeguard.h> +namespace { + class LayoutWithContent : public QGridLayout + { + public: + LayoutWithContent(QWidget *parentWdg) : QGridLayout(parentWdg) + { + QWidget *minMaxSizeWdg = new QWidget(); + minMaxSizeWdg->setMinimumSize(40, 40); + minMaxSizeWdg->setMaximumSize(140, 140); + QLabel *label1 = new QLabel(QStringLiteral("This is a qt label 1")); + QLabel *label2 = new QLabel(QStringLiteral("This is a qt label 2")); + addWidget(minMaxSizeWdg, 0, 0); + label1->setMaximumHeight(100); + label2->setMaximumHeight(100); + label1->setMaximumWidth(100); + label2->setMaximumWidth(100); + addWidget(label1, 1, 0); + addWidget(label2, 0, 1); + } + + void applySizeConstraint(SizeConstraint sc) + { + setSizeConstraint(sc); + activate(); + } + + void applyVerticalSizeConstraint(SizeConstraint sc) + { + setVerticalSizeConstraint(sc); + activate(); + } + + void applyHorizontalSizeConstraint(SizeConstraint sc) + { + setHorizontalSizeConstraint(sc); + activate(); + } + + void clearConstraintAndResize(QSize sz, Qt::Orientations o = Qt::Horizontal | Qt::Vertical) + { + if (o == (Qt::Horizontal | Qt::Vertical)) + setSizeConstraint(QLayout::SizeConstraint::SetNoConstraint); + else if (o == Qt::Vertical) + setVerticalSizeConstraint(QLayout::SizeConstraint::SetNoConstraint); + else if (o == Qt::Horizontal) + setHorizontalSizeConstraint(QLayout::SizeConstraint::SetNoConstraint); + + // Make sure we can always remove any set constraint as they are not removed by a change of the constraint. + parentWidget()->setMinimumSize(0, 0); + parentWidget()->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + parentWidget()->resize(sz); + activate(); + } + }; +} + using namespace QTestPrivate; class tst_QLayout : public QObject @@ -48,6 +104,14 @@ private slots: void adjustSizeShouldMakeSureLayoutIsActivated(); void testRetainSizeWhenHidden(); void removeWidget(); + void sizeConstraints(); + + void checkVerticalSizeConstraint_data(); + void checkVerticalSizeConstraint(); + void checkHorizontalSizeConstraint_data(); + void checkHorizontalSizeConstraint(); +private: + void setupDataSizeConstraint(); }; tst_QLayout::tst_QLayout() @@ -79,9 +143,6 @@ public: : QFrame(0), sh(sh), msh(msh) { setFrameStyle(QFrame::Box | QFrame::Plain); } - - - void setSizeHint(const QSize &s) { sh = s; } QSize sizeHint() const override { return sh; } QSize minimumSizeHint() const override { return msh; } @@ -406,5 +467,223 @@ void tst_QLayout::removeWidget() layout.setEnabled(true); } +void tst_QLayout::sizeConstraints() +{ + QWidget windowWdg; + auto *layout = new LayoutWithContent(&windowWdg); + + // Check fixed size + layout->applySizeConstraint(QLayout::SizeConstraint::SetFixedSize); + QCOMPARE(windowWdg.size(), layout->totalSizeHint()); + layout->clearConstraintAndResize(QSize(100, 100)); + + const QSize verySmall(5, 5); + const QSize veryBig(1500, 1500); + + // Check minimumSize changes + layout->clearConstraintAndResize(verySmall); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMinimumSize); + QCOMPARE(windowWdg.size(), layout->minimumSize()); + + // Check no-max on minimumSize changes + layout->clearConstraintAndResize(veryBig); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMinimumSize); + QCOMPARE(windowWdg.size(), veryBig); + + // Check maximumSize + layout->clearConstraintAndResize(veryBig); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMaximumSize); + QCOMPARE(windowWdg.size(), layout->maximumSize()); + + // Check no-max on minimumSize changes + layout->clearConstraintAndResize(verySmall); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMaximumSize); + QCOMPARE(windowWdg.size(), verySmall); + + // Check min on MinMax + layout->clearConstraintAndResize(verySmall); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize); + QCOMPARE(windowWdg.size(), layout->minimumSize()); + + // Check max on MinMax + layout->clearConstraintAndResize(veryBig); + layout->applySizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize); + QCOMPARE(windowWdg.size(), layout->maximumSize()); + + // Default size constaint with window + layout->clearConstraintAndResize(verySmall); + layout->applySizeConstraint(QLayout::SizeConstraint::SetDefaultConstraint); + QCOMPARE(windowWdg.size(), layout->totalMinimumSize()); + + // Default size constaint without window. + // It can appear weird that the default constraint removes earlier constraints in + // non-window mode when nothing similar happens for other constraints. + // So this part could *maybe* be a subject for a change. + // However, we need to be extremely careful as about every widget application + // uses layouts. + QWidget windowWidget; + QHBoxLayout *topLayout = new QHBoxLayout(&windowWidget); + QWidget *innerWidget = new QWidget(); + topLayout->addWidget(innerWidget); + auto *layout2 = new LayoutWithContent(innerWidget); + // make sure we set a minimumSize (that shouldn't be explicit) here. + layout2->applySizeConstraint(QLayout::SizeConstraint::SetMinimumSize); + QCOMPARE(innerWidget->minimumSize(), layout2->totalMinimumSize()); + // Only set here as we actually like to keep the size we had from minimumSize + layout2->setSizeConstraint(QLayout::SizeConstraint::SetDefaultConstraint); + QCOMPARE(innerWidget->minimumSize(), layout2->totalMinimumSize()); + layout2->activate(); + QCOMPARE(innerWidget->minimumSize(), QSize(0, 0)); +} + +void tst_QLayout::setupDataSizeConstraint() +{ + QTest::addColumn<QLayout::SizeConstraint>("constraint"); + + const auto constraints = { + QLayout::SetFixedSize, + QLayout::SetMinimumSize, + QLayout::SetMaximumSize, + QLayout::SetMinAndMaxSize, + QLayout::SetDefaultConstraint, + QLayout::SetNoConstraint + }; + + for (auto c : constraints) { + const QString desc = QLatin1String("Constraint_") + QTest::toString(c); + QTest::addRow("%s", qPrintable(desc)) << c; + } +} + +void tst_QLayout::checkVerticalSizeConstraint_data() +{ + setupDataSizeConstraint(); +} + +void tst_QLayout::checkVerticalSizeConstraint() +{ + QFETCH(QLayout::SizeConstraint, constraint); + + QWidget windowWdg; + auto *layout = new LayoutWithContent(&windowWdg); + layout->setHorizontalSizeConstraint(constraint); + + // Check fixed size + layout->applyVerticalSizeConstraint(QLayout::SetFixedSize); + QCOMPARE(windowWdg.height(), layout->totalSizeHint().height()); + layout->clearConstraintAndResize(QSize(100, 100), Qt::Vertical); + + const QSize verySmall(5, 5); + const QSize veryBig(1500, 1500); + + layout->clearConstraintAndResize(verySmall, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(windowWdg.size().height(), layout->minimumSize().height()); + + layout->clearConstraintAndResize(veryBig, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(windowWdg.size().height(), veryBig.height()); + + layout->clearConstraintAndResize(veryBig, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMaximumSize); + QCOMPARE(windowWdg.size().height(), layout->maximumSize().height()); + + layout->clearConstraintAndResize(verySmall, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMaximumSize); + QCOMPARE(windowWdg.size().height(), verySmall.height()); + + layout->clearConstraintAndResize(verySmall, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMinAndMaxSize); + QCOMPARE(windowWdg.size().height(), layout->minimumSize().height()); + + layout->clearConstraintAndResize(veryBig, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetMinAndMaxSize); + QCOMPARE(windowWdg.size().height(), layout->maximumSize().height()); + + layout->clearConstraintAndResize(verySmall, Qt::Vertical); + layout->applyVerticalSizeConstraint(QLayout::SetDefaultConstraint); + QCOMPARE(windowWdg.size().height(), layout->totalMinimumSize().height()); + + // Inner widget check + QWidget windowWidget; + QHBoxLayout *topLayout = new QHBoxLayout(&windowWidget); + QWidget *innerWidget = new QWidget(); + topLayout->addWidget(innerWidget); + auto *layout2 = new LayoutWithContent(innerWidget); + layout2->applyVerticalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(innerWidget->minimumSize().height(), layout2->totalMinimumSize().height()); + layout2->setVerticalSizeConstraint(QLayout::SetDefaultConstraint); + QCOMPARE(innerWidget->minimumSize().height(), layout2->totalMinimumSize().height()); + layout2->activate(); + QCOMPARE(innerWidget->minimumSize().height(), 0); +} + +void tst_QLayout::checkHorizontalSizeConstraint_data() +{ + setupDataSizeConstraint(); +} + +void tst_QLayout::checkHorizontalSizeConstraint() +{ + QFETCH(QLayout::SizeConstraint, constraint); + + QWidget windowWdg; + auto *layout = new LayoutWithContent(&windowWdg); + layout->setVerticalSizeConstraint(constraint); + + // Fixed size + layout->applyHorizontalSizeConstraint(QLayout::SetFixedSize); + QCOMPARE(windowWdg.width(), layout->totalSizeHint().width()); + layout->clearConstraintAndResize(QSize(100, 100), Qt::Horizontal); + + const QSize verySmall(5, 5); + const QSize veryBig(1500, 1500); + + // Minimum size + layout->clearConstraintAndResize(verySmall, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(windowWdg.size().width(), layout->minimumSize().width()); + + layout->clearConstraintAndResize(veryBig, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(windowWdg.size().width(), veryBig.width()); + + // Maximum size + layout->clearConstraintAndResize(veryBig, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMaximumSize); + QCOMPARE(windowWdg.size().width(), layout->maximumSize().width()); + + layout->clearConstraintAndResize(verySmall, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMaximumSize); + QCOMPARE(windowWdg.size().width(), verySmall.width()); + + // Min and Max + layout->clearConstraintAndResize(verySmall, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMinAndMaxSize); + QCOMPARE(windowWdg.size().width(), layout->minimumSize().width()); + + layout->clearConstraintAndResize(veryBig, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetMinAndMaxSize); + QCOMPARE(windowWdg.size().width(), layout->maximumSize().width()); + + // Default constraint + layout->clearConstraintAndResize(verySmall, Qt::Horizontal); + layout->applyHorizontalSizeConstraint(QLayout::SetDefaultConstraint); + QCOMPARE(windowWdg.size().width(), layout->totalMinimumSize().width()); + + // Final innerWidget check + QWidget windowWidget; + QHBoxLayout *topLayout = new QHBoxLayout(&windowWidget); + QWidget *innerWidget = new QWidget(); + topLayout->addWidget(innerWidget); + auto *layout2 = new LayoutWithContent(innerWidget); + layout2->applyHorizontalSizeConstraint(QLayout::SetMinimumSize); + QCOMPARE(innerWidget->minimumSize().width(), layout2->totalMinimumSize().width()); + layout2->setHorizontalSizeConstraint(QLayout::SetDefaultConstraint); + QCOMPARE(innerWidget->minimumSize().width(), layout2->totalMinimumSize().width()); + layout2->activate(); + QCOMPARE(innerWidget->minimumSize().width(), 0); +} + QTEST_MAIN(tst_QLayout) #include "tst_qlayout.moc" |