Long live QSize(F)::grownBy/shrunkBy()

These functions tighten the integration of QMargins(F) with the rest
of the geometry classes by providing a way to apply margins to sizes
(and later, rects).

Apply them in a few obvious cases across QtWidgets.

[ChangeLog][QtCore][QSize/QSizeF] Added grownBy(QMargin(F))/shrunkBy(QMargin(F)).

Change-Id: I8a549436824cdb7fb6125a8cde89d5bf02826934
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2019-05-24 21:20:37 +02:00
parent 529b271520
commit 5b2dfbc649
6 changed files with 126 additions and 19 deletions

View File

@ -390,7 +390,25 @@ QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const noexcept
\sa expandedTo(), scale()
*/
/*!
\fn QSize QSize::grownBy(QMargins margins) const
\fn QSizeF QSizeF::grownBy(QMarginsF margins) const
\since 5.14
Returns the size that results from growing this size by \a margins.
\sa shrunkBy()
*/
/*!
\fn QSize QSize::shrunkBy(QMargins margins) const
\fn QSizeF QSizeF::shrunkBy(QMarginsF margins) const
\since 5.14
Returns the size that results from shrinking this size by \a margins.
\sa grownBy()
*/
/*****************************************************************************
QSize stream functions

View File

@ -41,6 +41,7 @@
#define QSIZE_H
#include <QtCore/qnamespace.h>
#include <QtCore/qmargins.h>
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
struct CGSize;
@ -74,6 +75,11 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSize expandedTo(const QSize &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSize boundedTo(const QSize &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSize grownBy(QMargins m) const noexcept
{ return {width() + m.left() + m.right(), height() + m.top() + m.bottom()}; }
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSize shrunkBy(QMargins m) const noexcept
{ return {width() - m.left() - m.right(), height() - m.top() - m.bottom()}; }
Q_DECL_RELAXED_CONSTEXPR inline int &rwidth() noexcept;
Q_DECL_RELAXED_CONSTEXPR inline int &rheight() noexcept;
@ -238,6 +244,11 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSizeF expandedTo(const QSizeF &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSizeF boundedTo(const QSizeF &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSizeF grownBy(QMarginsF m) const noexcept
{ return {width() + m.left() + m.right(), height() + m.top() + m.bottom()}; }
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSizeF shrunkBy(QMarginsF m) const noexcept
{ return {width() - m.left() - m.right(), height() - m.top() - m.bottom()}; }
Q_DECL_RELAXED_CONSTEXPR inline qreal &rwidth() noexcept;
Q_DECL_RELAXED_CONSTEXPR inline qreal &rheight() noexcept;

View File

@ -138,11 +138,8 @@ bool QDockAreaLayoutItem::skip() const
QSize QDockAreaLayoutItem::minimumSize() const
{
if (widgetItem != 0) {
int left, top, right, bottom;
widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
return widgetItem->minimumSize() + QSize(left+right, top+bottom);
}
if (widgetItem)
return widgetItem->minimumSize().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->minimumSize();
return QSize(0, 0);
@ -150,11 +147,8 @@ QSize QDockAreaLayoutItem::minimumSize() const
QSize QDockAreaLayoutItem::maximumSize() const
{
if (widgetItem != 0) {
int left, top, right, bottom;
widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
return widgetItem->maximumSize()+ QSize(left+right, top+bottom);
}
if (widgetItem)
return widgetItem->maximumSize().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->maximumSize();
return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
@ -180,11 +174,8 @@ QSize QDockAreaLayoutItem::sizeHint() const
{
if (placeHolderItem != 0)
return QSize(0, 0);
if (widgetItem != 0) {
int left, top, right, bottom;
widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
return widgetItem->sizeHint() + QSize(left+right, top+bottom);
}
if (widgetItem)
return widgetItem->sizeHint().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->sizeHint();
return QSize(-1, -1);

View File

@ -381,11 +381,10 @@ QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) co
if (content.height() < 0)
result.setHeight(-1);
int left, top, right, bottom;
w->getContentsMargins(&left, &top, &right, &bottom);
const QMargins margins = w->contentsMargins();
//we need to subtract the contents margin (it will be added by the caller)
QSize min = w->minimumSize() - QSize(left + right, top + bottom);
QSize max = w->maximumSize() - QSize(left + right, top + bottom);
QSize min = w->minimumSize().shrunkBy(margins);
QSize max = w->maximumSize().shrunkBy(margins);
/* A floating dockwidget will automatically get its minimumSize set to the layout's
minimum size + deco. We're *not* interested in this, we only take minimumSize()

View File

@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <qsize.h>
Q_DECLARE_METATYPE(QMargins)
class tst_QSize : public QObject
{
@ -43,6 +44,9 @@ private slots:
void boundedTo_data();
void boundedTo();
void grownOrShrunkBy_data();
void grownOrShrunkBy();
void transpose_data();
void transpose();
};
@ -186,6 +190,46 @@ void tst_QSize::boundedTo()
QCOMPARE( input1.boundedTo(input2), expected);
}
void tst_QSize::grownOrShrunkBy_data()
{
QTest::addColumn<QSize>("input");
QTest::addColumn<QMargins>("margins");
QTest::addColumn<QSize>("grown");
QTest::addColumn<QSize>("shrunk");
auto row = [](QSize i, QMargins m, QSize g, QSize s) {
QTest::addRow("{%d,%d}/{%d,%d,%d,%d}", i.width(), i.height(),
m.left(), m.top(), m.right(), m.bottom())
<< i << m << g << s;
};
const QSize zero = {0, 0};
const QSize some = {100, 200};
const QMargins zeroMargins = {};
const QMargins negative = {-1, -2, -3, -4};
const QMargins positive = { 1, 2, 3, 4};
row(zero, zeroMargins, zero, zero);
row(zero, negative, {-4, -6}, { 4, 6});
row(zero, positive, { 4, 6}, {-4, -6});
row(some, zeroMargins, some, some);
row(some, negative, { 96, 194}, {104, 206});
row(some, positive, {104, 206}, { 96, 194});
}
void tst_QSize::grownOrShrunkBy()
{
QFETCH(const QSize, input);
QFETCH(const QMargins, margins);
QFETCH(const QSize, grown);
QFETCH(const QSize, shrunk);
QCOMPARE(input.grownBy(margins), grown);
QCOMPARE(input.shrunkBy(margins), shrunk);
QCOMPARE(grown.shrunkBy(margins), input);
QCOMPARE(shrunk.grownBy(margins), input);
}
void tst_QSize::transpose_data()
{
QTest::addColumn<QSize>("input1");

View File

@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <qsize.h>
Q_DECLARE_METATYPE(QMarginsF)
class tst_QSizeF : public QObject
{
@ -45,6 +46,9 @@ private slots:
void boundedTo_data();
void boundedTo();
void grownOrShrunkBy_data();
void grownOrShrunkBy();
void transpose_data();
void transpose();
};
@ -152,6 +156,46 @@ void tst_QSizeF::boundedTo() {
QCOMPARE( input1.boundedTo(input2), expected);
}
void tst_QSizeF::grownOrShrunkBy_data()
{
QTest::addColumn<QSizeF>("input");
QTest::addColumn<QMarginsF>("margins");
QTest::addColumn<QSizeF>("grown");
QTest::addColumn<QSizeF>("shrunk");
auto row = [](QSizeF i, QMarginsF m, QSizeF g, QSizeF s) {
QTest::addRow("{%g,%g}/{%g,%g,%g,%g}", i.width(), i.height(),
m.left(), m.top(), m.right(), m.bottom())
<< i << m << g << s;
};
const QSizeF zero = {0, 0};
const QSizeF some = {100, 200};
const QMarginsF zeroMargins = {};
const QMarginsF negative = {-1, -2, -3, -4};
const QMarginsF positive = { 1, 2, 3, 4};
row(zero, zeroMargins, zero, zero);
row(zero, negative, {-4, -6}, { 4, 6});
row(zero, positive, { 4, 6}, {-4, -6});
row(some, zeroMargins, some, some);
row(some, negative, { 96, 194}, {104, 206});
row(some, positive, {104, 206}, { 96, 194});
}
void tst_QSizeF::grownOrShrunkBy()
{
QFETCH(const QSizeF, input);
QFETCH(const QMarginsF, margins);
QFETCH(const QSizeF, grown);
QFETCH(const QSizeF, shrunk);
QCOMPARE(input.grownBy(margins), grown);
QCOMPARE(input.shrunkBy(margins), shrunk);
QCOMPARE(grown.shrunkBy(margins), input);
QCOMPARE(shrunk.grownBy(margins), input);
}
void tst_QSizeF::transpose_data() {
QTest::addColumn<QSizeF>("input1");
QTest::addColumn<QSizeF>("expected");