qt5base-lts/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp
Qt by Nokia 38be0d1383 Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you
want to look at revision history older than this, please refer to the
Qt Git wiki for how to use Git history grafting. At the time of
writing, this wiki is located here:

http://qt.gitorious.org/qt/pages/GitIntroductionWithQt

If you have already performed the grafting and you don't see any
history beyond this commit, try running "git log" with the "--follow"
argument.

Branched from the monolithic repo, Qt master branch, at commit
896db169ea224deb96c59ce8af800d019de63f12
2011-04-27 12:05:43 +02:00

3122 lines
120 KiB
C++

/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include <QtTest/QtTest>
#include <QTest>
#include <QMetaType>
#include <QtGui/qgraphicsanchorlayout.h>
#include <private/qgraphicsanchorlayout_p.h>
#define TEST_COMPLEX_CASES
//---------------------- AnchorLayout helper class ----------------------------
class TheAnchorLayout : public QGraphicsAnchorLayout
{
public:
TheAnchorLayout() : QGraphicsAnchorLayout()
{
setContentsMargins( 0,0,0,0 );
setSpacing( 0 );
}
bool isValid()
{
return !QGraphicsAnchorLayoutPrivate::get(this)->hasConflicts();
}
void setAnchor(
QGraphicsLayoutItem *startItem,
Qt::AnchorPoint startEdge,
QGraphicsLayoutItem *endItem,
Qt::AnchorPoint endEdge,
qreal value)
{
QGraphicsAnchor *anchor = addAnchor( startItem, startEdge, endItem, endEdge);
if (anchor)
anchor->setSpacing(value);
}
int indexOf(const QGraphicsLayoutItem* item) const
{
for ( int i=0; i< count(); i++) {
if ( itemAt(i) == item ) {
return i;
}
}
return -1;
}
void removeItem(QGraphicsLayoutItem* item)
{
removeAt(indexOf(item));
}
void removeAnchor(
QGraphicsLayoutItem *startItem,
Qt::AnchorPoint startEdge,
QGraphicsLayoutItem *endItem,
Qt::AnchorPoint endEdge)
{
delete QGraphicsAnchorLayout::anchor(startItem, startEdge, endItem, endEdge);
}
};
//-----------------------------------------------------------------------------
struct BasicLayoutTestData
{
inline BasicLayoutTestData(
int index1, Qt::AnchorPoint edge1,
int index2, Qt::AnchorPoint edge2,
qreal distance)
: firstIndex(index1), firstEdge(edge1),
secondIndex(index2), secondEdge(edge2),
spacing(distance)
{
}
int firstIndex;
Qt::AnchorPoint firstEdge;
int secondIndex;
Qt::AnchorPoint secondEdge;
qreal spacing;
};
struct AnchorItemSizeHint
{
inline AnchorItemSizeHint(
qreal hmin, qreal hpref, qreal hmax,
qreal vmin, qreal vpref, qreal vmax )
: hmin(hmin), hpref(hpref), hmax(hmax), vmin(vmin), vpref(vpref), vmax(vmax)
{
}
qreal hmin, hpref, hmax;
qreal vmin, vpref, vmax;
};
// some test results
struct BasicLayoutTestResult
{
inline BasicLayoutTestResult(
int resultIndex, const QRectF& resultRect )
: index(resultIndex), rect(resultRect)
{
}
int index;
QRectF rect;
};
typedef QList<BasicLayoutTestData> BasicLayoutTestDataList;
Q_DECLARE_METATYPE(BasicLayoutTestDataList)
typedef QList<BasicLayoutTestResult> BasicLayoutTestResultList;
Q_DECLARE_METATYPE(BasicLayoutTestResultList)
typedef QList<AnchorItemSizeHint> AnchorItemSizeHintList;
Q_DECLARE_METATYPE(AnchorItemSizeHintList)
//---------------------- Test Widget used on all tests ------------------------
class TestWidget : public QGraphicsWidget
{
public:
inline TestWidget(QGraphicsItem *parent = 0, const QString &name = QString())
: QGraphicsWidget(parent)
{
setContentsMargins( 0,0,0,0 );
if (name.isEmpty())
setData(0, QString::fromAscii("w%1").arg(quintptr(this)));
else
setData(0, name);
}
~TestWidget()
{
}
protected:
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
};
QSizeF TestWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
Q_UNUSED( constraint );
if (which == Qt::MinimumSize) {
return QSizeF(5,5);
}
if (which == Qt::PreferredSize) {
return QSizeF(50,50);
}
return QSizeF(500,500);
}
//-----------------------------------------------------------------------------
//----------------------------- Test class ------------------------------------
class tst_QGraphicsAnchorLayout1 : public QObject
{
Q_OBJECT
private slots:
void testCount();
void testRemoveAt();
void testRemoveItem();
void testItemAt();
void testIndexOf();
void testAddAndRemoveAnchor();
void testIsValid();
void testSpecialCases();
void testBasicLayout_data();
void testBasicLayout();
void testNegativeSpacing_data();
void testNegativeSpacing();
void testMixedSpacing_data();
void testMixedSpacing();
void testMulti_data();
void testMulti();
void testCenterAnchors_data();
void testCenterAnchors();
void testRemoveCenterAnchor_data();
void testRemoveCenterAnchor();
void testSingleSizePolicy_data();
void testSingleSizePolicy();
void testDoubleSizePolicy_data();
void testDoubleSizePolicy();
void testSizeDistribution_data();
void testSizeDistribution();
void testSizeHint();
#ifdef TEST_COMPLEX_CASES
void testComplexCases_data();
void testComplexCases();
#endif
};
void tst_QGraphicsAnchorLayout1::testCount()
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
QVERIFY( layout->count() == 0 );
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
QCOMPARE( layout->count(), 1 );
// adding one more anchor for already added widget should not increase the count
layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, 1);
QCOMPARE( layout->count(), 1 );
// create one more widget and attach with anchor layout
TestWidget *widget2 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
QCOMPARE( layout->count(), 2 );
widget->setLayout(layout);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testRemoveAt()
{
TheAnchorLayout *layout = new TheAnchorLayout();
QVERIFY( layout->count() == 0 );
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
QVERIFY( layout->count() == 1 );
TestWidget *widget2 = new TestWidget();
layout->setAnchor(widget2, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
QVERIFY( layout->count() == 2 );
layout->removeAt(0);
QVERIFY( layout->count() == 1 );
layout->removeAt(-55);
layout->removeAt(55);
QVERIFY( layout->count() == 1 );
layout->removeAt(0);
QVERIFY( layout->count() == 0 );
delete layout;
delete widget1;
delete widget2;
}
void tst_QGraphicsAnchorLayout1::testRemoveItem()
{
TheAnchorLayout *layout = new TheAnchorLayout();
QCOMPARE( layout->count(), 0 );
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
QCOMPARE( layout->count(), 1 );
TestWidget *widget2 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
QCOMPARE( layout->count(), 2 );
layout->removeItem(0);
QCOMPARE( layout->count(), 2 );
layout->removeItem(widget1);
QCOMPARE( layout->count(), 1 );
QCOMPARE( layout->indexOf(widget1), -1 );
QCOMPARE( layout->indexOf(widget2), 0 );
layout->removeItem(widget1);
QCOMPARE( layout->count(), 1 );
layout->removeItem(widget2);
QVERIFY( layout->count() == 0 );
delete layout;
delete widget1;
delete widget2;
}
void tst_QGraphicsAnchorLayout1::testItemAt()
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
TestWidget *widget2 = new TestWidget();
TestWidget *widget3 = new TestWidget();
TestWidget *widget4 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
QVERIFY( layout->itemAt(0) == widget1 );
layout->removeAt(0);
QVERIFY( layout->itemAt(0) == widget2 );
delete widget1;
widget->setLayout(layout);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testIndexOf()
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
TestWidget *widget2 = new TestWidget();
TestWidget *widget3 = new TestWidget();
TestWidget *widget4 = new TestWidget();
QCOMPARE( layout->indexOf(widget1), -1 );
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
QCOMPARE( layout->indexOf(widget4), -1 );
layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
QCOMPARE( layout->count(), 4 );
for (int i = 0; i < layout->count(); ++i) {
QCOMPARE(layout->indexOf(layout->itemAt(i)), i);
}
QCOMPARE( layout->indexOf(0), -1 );
widget->setLayout(layout);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor()
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
TestWidget *widget2 = new TestWidget();
TestWidget *widget3 = new TestWidget();
TestWidget *widget4 = new TestWidget();
TestWidget *widget5 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.5);
layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 10);
layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
QCOMPARE( layout->count(), 4 );
// test setting invalid anchors
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1);
QCOMPARE( layout->count(), 4 );
// test removing invalid anchors
layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight);
// anchor one horizontal edge with vertical edge. it should not add this widget as a child
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10);
QCOMPARE( layout->count(), 4 );
// anchor two edges of a widget (to define width / height)
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10);
// QCOMPARE( layout->count(), 5 );
QCOMPARE( layout->count(), 4 );
// anchor yet new widget properly
layout->setAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight, 20 );
QCOMPARE( layout->count(), 5 );
// remove anchor for widget1. widget1 should be removed from layout since the
// last anchor was removed.
layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft);
QCOMPARE( layout->count(), 4 );
QVERIFY( !widget1->parentLayoutItem() );
// test that item is not removed from layout if other anchors remain set
layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10);
layout->removeAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft);
QCOMPARE( layout->count(), 4 );
// remove all the anchors
layout->removeAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight);
layout->removeAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft);
layout->removeAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft);
layout->removeAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight);
layout->removeAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight);
QCOMPARE( layout->count(), 0 );
// set one anchor "another way round" to get full coverage for "removeAnchor"
layout->setAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
layout->removeAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft);
QCOMPARE( layout->count(), 0 );
delete widget1;
delete widget2;
delete widget3;
delete widget4;
delete widget5;
widget->setLayout(layout);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testIsValid()
{
// Empty, valid
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
widget->setLayout(layout);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(layout->isValid(), true);
delete widget;
}
// One widget, valid
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
widget->setLayout(layout);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(layout->isValid(), true);
delete widget;
}
// Overconstrained one widget, invalid
// ### Our understanding is that this case is valid. What happens though,
// is that the layout minimum and maximum vertical size hints become
// the same, 10.1. That means its height is fixed.
// What will "fail" then is the "setGeometry(0, 0, 100, 100)" call,
// after which the layout geometry will be (0, 0, 100, 10.1).
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
layout->setAnchor(widget1, Qt::AnchorTop, layout, Qt::AnchorBottom, 10);
widget->setLayout(layout);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(layout->isValid(), true);
delete widget;
}
// Underconstrained two widgets, valid
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
TestWidget *widget2 = new TestWidget();
// Vertically the layout has floating items. Therefore, we have a conflict
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1);
// Horizontally the layout has floating items. Therefore, we have a conflict
layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1);
layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1);
widget->setLayout(layout);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(layout->isValid(), false);
delete widget;
}
}
void tst_QGraphicsAnchorLayout1::testSpecialCases()
{
// One widget, setLayout before defining layouts
{
#ifdef QT_DEBUG
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
" in wrong parent; moved to correct parent");
#endif
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
widget->setLayout(layout);
TestWidget *widget1 = new TestWidget();
layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(widget1->geometry(), QRectF(1,1,98,98));
delete widget1;
delete widget;
}
// One widget, layout inside layout, layout inside layout inside layout
{
#ifdef QT_DEBUG
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
" in wrong parent; moved to correct parent");
#endif
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
widget->setLayout(layout);
TheAnchorLayout *layout1 = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
TheAnchorLayout *layout2 = new TheAnchorLayout();
TestWidget *widget2 = new TestWidget();
layout2->setAnchor(layout2, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
layout2->setAnchor(layout2, Qt::AnchorTop, widget2, Qt::AnchorTop, 1);
layout2->setAnchor(widget2, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
layout2->setAnchor(widget2, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
layout1->setAnchor(layout1, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 1);
layout1->setAnchor(layout1, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
layout1->setAnchor(layout2, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
layout1->setAnchor(layout2, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
// remove and add again to improve test coverage.
layout->removeItem(layout1);
layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
QCOMPARE(widget2->geometry(), QRectF(3,3,94,94));
delete widget;
}
// One widget, layout inside layout, setLayout after layout definition
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
TheAnchorLayout *layout1 = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
widget->setLayout(layout);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
delete widget;
}
// One widget, layout inside layout, setLayout after layout definition, widget transferred from
// one layout to another
{
QGraphicsWidget *widget = new QGraphicsWidget;
TheAnchorLayout *layout = new TheAnchorLayout();
widget->setLayout(layout);
TheAnchorLayout *layout1 = new TheAnchorLayout();
TestWidget *widget1 = new TestWidget();
// Additional layout + widget to improve coverage.
TheAnchorLayout *layout0 = new TheAnchorLayout();
TestWidget *widget0 = new TestWidget();
// widget0 to layout0
layout0->setAnchor(layout0, Qt::AnchorLeft, widget0, Qt::AnchorLeft, 1);
layout0->setAnchor(layout0, Qt::AnchorTop, widget0, Qt::AnchorTop, 1);
layout0->setAnchor(widget0, Qt::AnchorRight, layout0, Qt::AnchorRight, 1);
layout0->setAnchor(widget0, Qt::AnchorBottom, layout0, Qt::AnchorBottom, 1);
// layout0 to layout
layout->setAnchor(layout, Qt::AnchorLeft, layout0, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, layout0, Qt::AnchorTop, 1);
layout->setAnchor(layout0, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
layout->setAnchor(layout0, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
// widget1 to layout1
layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
// layout1 to layout
layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
TheAnchorLayout *layout2 = new TheAnchorLayout();
// layout2 to layout
layout->setAnchor(layout, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 50);
layout->setAnchor(layout, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
layout->setAnchor(layout2, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
layout->setAnchor(layout2, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
// transfer widget1 to layout2
layout2->setAnchor(layout2, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
layout2->setAnchor(layout2, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
layout2->setAnchor(widget1, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
layout2->setAnchor(widget1, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
widget->setGeometry(QRectF(0,0,100,100));
QCOMPARE(widget1->geometry(), QRectF(51,2,47,96));
delete widget;
}
// One widget, set first to one layout then to another. Child reparented.
// In addition widget as a direct child of another widget. Child reparented.
{
QGraphicsWidget *widget1 = new QGraphicsWidget;
TheAnchorLayout *layout1 = new TheAnchorLayout();
widget1->setLayout(layout1);
TestWidget *childWidget = new TestWidget();
// childWidget to layout1
layout1->setAnchor(layout1, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
layout1->setAnchor(layout1, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
layout1->setAnchor(childWidget, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
layout1->setAnchor(childWidget, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
widget1->setGeometry(QRectF(0,0,100,100));
QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
QVERIFY(childWidget->parentLayoutItem() == layout1);
QGraphicsWidget *widget2 = new QGraphicsWidget;
TheAnchorLayout *layout2 = new TheAnchorLayout();
widget2->setLayout(layout2);
// childWidget to layout2
layout2->setAnchor(layout2, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
layout2->setAnchor(layout2, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
layout2->setAnchor(childWidget, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
layout2->setAnchor(childWidget, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
QGraphicsWidget *widget3 = new QGraphicsWidget;
QGraphicsWidget *widget4 = new QGraphicsWidget;
// widget4 is a direct child of widget3 (i.e. not in any layout)
widget4->setParentItem(widget3);
// widget4 to layout2
layout2->setAnchor(layout2, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 1);
layout2->setAnchor(layout2, Qt::AnchorTop, widget4, Qt::AnchorTop, 1);
layout2->setAnchor(widget4, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
layout2->setAnchor(widget4, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
widget2->setGeometry(QRectF(0,0,100,100));
QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
QVERIFY(childWidget->parentLayoutItem() == layout2);
QCOMPARE(widget4->geometry(), QRectF(1,1,98,98));
QVERIFY(widget4->parentLayoutItem() == layout2);
QVERIFY(widget4->parentItem() == widget2);
delete widget4;
delete widget3;
delete widget1;
delete childWidget;
delete widget2;
}
}
void tst_QGraphicsAnchorLayout1::testBasicLayout_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// One widget, basic
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
;
theResult
<< BasicResult(0, QRectF(20, 10, 150, 50) )
;
QTest::newRow("One, simple") << QSizeF(200, 100) << theData << theResult;
}
// One widget, duplicates
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
;
theResult
<< BasicResult(0, QRectF(0, 0, 200, 100) )
;
QTest::newRow("One, duplicates") << QSizeF(200, 100) << theData << theResult;
}
// One widget, mixed
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 80)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 150)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 150)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 80)
;
theResult
<< BasicResult(0, QRectF(50, 20, 100, 60) )
;
QTest::newRow("One, mixed") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets (same layout), different ordering
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
;
theResult
<< BasicResult(0, QRectF(10, 10, 180, 80) )
<< BasicResult(1, QRectF(10, 10, 180, 80) )
;
QTest::newRow("Two, orderings") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, duplicate anchors
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 30)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
;
theResult
<< BasicResult(0, QRectF(30, 10, 160, 70) )
<< BasicResult(1, QRectF(10, 0, 190, 90) )
;
QTest::newRow("Two, duplicates") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, mixed
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 90)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 190)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 190)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 90)
<< BasicData(1, Qt::AnchorTop, -1, Qt::AnchorBottom, 20)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 180, 80) )
<< BasicResult(1, QRectF(10, 80, 10, 10) )
;
QTest::newRow("Two, mixed") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 1 horizontal connection, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(30, 10, 160, 70) )
;
QTest::newRow("Two, 1h connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 2 horizontal connections, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
// ### QGAL is not sensible to the argument order in this case
// To achieve the desired result we must explicitly set a negative
// spacing.
// << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 30)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(50, 10, 60, 70) )
;
QTest::newRow("Two, 2h connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 1 vertical connection, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(30, 20, 160, 60) )
;
QTest::newRow("Two, 1v connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 2 vertical connections, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(30, 20, 160, 50) )
;
QTest::newRow("Two, 2v connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 1 horizontal and 1 vertical connection, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(80, 10, 40, 70) )
;
QTest::newRow("Two, 1h+1v connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 2 horizontal and 2 vertical connections, first completely defined
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
;
theResult
<< BasicResult(0, QRectF(10, 10, 10, 80) )
<< BasicResult(1, QRectF(90, 20, 30, 60) )
;
QTest::newRow("Two, 2h+2v connected") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other.
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 150)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 10)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 90)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
;
theResult
<< BasicResult(0, QRectF(10, 10, 30, 60) )
<< BasicResult(1, QRectF(100, 20, 90, 60) )
;
QTest::newRow("Two, 2h+2v connected2") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, connected, overlapping
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
// << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, 30)
// ### QGAL has different semantics and assumes right edges are always
// to the left of left edges. Thus we need the minus sign here.
<< BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -30)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 40)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 40)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
;
theResult
<< BasicResult(0, QRectF(10, 10, 60, 40) )
<< BasicResult(1, QRectF(40, 20, 150, 70) )
;
QTest::newRow("Two, connected overlapping") << QSizeF(200, 100) << theData << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testNegativeSpacing_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// One widget, negative spacing
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
/// ### QGAL assumes items are always inside the layout.
// In this case, the negative spacing would make the item
// grow beyond the layout edges, which is OK, but gives a
// different result.
// Changing the direction of anchors (-1 to 0 or vice-versa)
// has no effect in this case.
theData
// << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
// << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
// << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -20)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, -30)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, -40)
;
theResult
// << BasicResult(0, QRectF(20, 10, 150, 50) )
<< BasicResult(0, QRectF(-20, -10, 250, 150) )
;
QTest::newRow("One, simple (n)") << QSizeF(200, 100) << theData << theResult;
}
// One widget, duplicates, negative spacing
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -20)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -10)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
;
theResult
// ### Same as above...
// << BasicResult(0, QRectF(10, 10, 180, 80) )
<< BasicResult(0, QRectF(-10, -10, 220, 120) )
;
QTest::newRow("One, duplicates (n)") << QSizeF(200, 100) << theData << theResult;
}
// One widget, mixed, negative spacing
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// ### All anchors of negative spacing between the layout and an
// item are handled as to make sure the item is _outside_ the
// layout.
// To keep it inside, one _must_ use positive spacings.
// << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, -80)
// << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, -150)
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, -150)
// << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, -80)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, 80)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, 150)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, 150)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, 80)
;
theResult
<< BasicResult(0, QRectF(50, 20, 100, 60) )
;
QTest::newRow("One, mixed (n)") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 1 horizontal connection, first completely defined, negative spacing
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
// << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
// << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -180)
// << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
// << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
// << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
// << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 180)
<< BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
<< BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
<< BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
<< BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
;
theResult
// << BasicResult(0, QRectF(10, 10, 10, 80) )
// << BasicResult(1, QRectF(30, 10, 160, 70) )
<< BasicResult(0, QRectF(-10, -10, 30, 120) )
<< BasicResult(1, QRectF(10, -10, 200, 130) )
;
QTest::newRow("Two, 1h connected (n)") << QSizeF(200, 100) << theData << theResult;
}
// Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other, negative spacing
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
<< BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, -150)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
<< BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -90)
<< BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
<< BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
<< BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
;
theResult
// << BasicResult(0, QRectF(10, 10, 30, 60) )
// << BasicResult(1, QRectF(100, 20, 90, 60) )
<< BasicResult(0, QRectF(-10, -10, 70, 120) )
<< BasicResult(1, QRectF(80, 0, 130, 120) )
;
QTest::newRow("Two, 2h+2v connected2 (n)") << QSizeF(200, 100) << theData << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testMixedSpacing_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// Two widgets, partial overlapping
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -50)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 50)
<< BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, 15)
// << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, 5)
<< BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, -5)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, -10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 20)
<< BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -5)
;
theResult
// << BasicResult(0, QRectF(50, 10, 45, 40) )
// << BasicResult(1, QRectF(40, 45, 40, 50) )
<< BasicResult(0, QRectF(-50, 10, 145, 40) )
<< BasicResult(1, QRectF(-60, 45, 140, 60) )
;
QTest::newRow("Two, partial overlap") << QSizeF(100, 100) << theData << theResult;
}
// Two widgets, complete overlapping
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 25)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
<< BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorRight, 50)
<< BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
;
theResult
<< BasicResult(0, QRectF(65, 5, 35, 35) )
<< BasicResult(1, QRectF(40, 5, 60, 35) )
;
QTest::newRow("Two, complete overlap") << QSizeF(90, 45) << theData << theResult;
}
// Five widgets, v shaped, edges shared
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// edges shared
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 0)
<< BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 0)
<< BasicData(2, Qt::AnchorRight, 3, Qt::AnchorLeft, 0)
<< BasicData(3, Qt::AnchorRight, 4, Qt::AnchorLeft, 0)
<< BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 0)
<< BasicData(3, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
<< BasicData(4, Qt::AnchorBottom, 3, Qt::AnchorTop, 0)
<< BasicData(0, Qt::AnchorBottom, 4, Qt::AnchorBottom, 0)
<< BasicData(1, Qt::AnchorBottom, 3, Qt::AnchorBottom, 0)
<< BasicData(0, Qt::AnchorTop, 4, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorTop, 3, Qt::AnchorTop, 0)
// margins
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 5)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
<< BasicData(2, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
// << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, -5)
<< BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, 5)
// additional details for exact size determination easily
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 25)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 50)
// << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, -25)
// << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, -50)
<< BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, 25)
<< BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, 50)
<< BasicData(-1, Qt::AnchorTop, 3, Qt::AnchorBottom, 50)
// << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, -50)
<< BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, 50)
;
theResult
<< BasicResult(0, QRectF(5,5,20,20))
<< BasicResult(1, QRectF(25,25,25,25))
<< BasicResult(2, QRectF(50,50,25,20))
<< BasicResult(3, QRectF(75,25,25,25))
<< BasicResult(4, QRectF(100,5,20,20))
;
QTest::newRow("Five, V shape") << QSizeF(125, 75) << theData << theResult;
}
// ### The behavior is different in QGraphicsAnchorLayout. What happens here is
// that when the above anchors are set, the layout size hints are changed.
// In the example, the minimum item width is 5, thus the minimum layout width
// becomes 105 (50 + 5 + 50). Once that size hint is set, trying to set
// the widget size to (10, 10) is not possible because
// QGraphicsWidget::setGeometry() will enforce the minimum is respected.
if (0)
// One widget, unsolvable
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
;
theResult
<< BasicResult(0, QRectF(0,0,0,0))
;
QTest::newRow("One widget, unsolvable") << QSizeF(10, 10) << theData << theResult;
}
// Two widgets, one has fixed size
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
// not supported, use sizePolicy instead
// << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 50)
<< BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 50)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
;
theResult
<< BasicResult(0, QRectF(50,0,50,50))
<< BasicResult(1, QRectF(50,0,50,50))
;
QTest::newRow("Two widgets, one has fixed size") << QSizeF(150, 150) << theData << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testMulti_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// Multiple widgets, all overllapping
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
const int n = 30;
for ( int i = 0 ; i < n; i++ ) {
theData
<< BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, 20)
<< BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, 10)
// << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -40)
// << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -30);
<< BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, 40)
<< BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, 30);
theResult
<< BasicResult(i, QRectF(10, 20, 160, 40) );
}
QTest::newRow("Overlapping multi") << QSizeF(200, 100) << theData << theResult;
}
// Multiple widgets, linear order
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
const qreal height = 1000.f;
const qreal width = 2000.f;
const int n = 30;
const qreal verticalStep = height/qreal(n+2);
const qreal horizontalStep = width/qreal(n+2);
for ( int i = 0 ; i < n; i++ ) {
if ( i == 0 ) {
// First item
theData
<< BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
} else if ( i == n-1 ) {
// Last item
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
<< BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
// << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
// << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
} else {
// items in the middle
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
// << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
// << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
}
theResult
<< BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
}
if (sizeof(qreal) == 4) {
qDebug("Linear multi: Skipping! (qreal has too little precision, result will be wrong)");
} else {
QTest::newRow("Linear multi") << QSizeF(width, height) << theData << theResult;
}
}
// Multiple widgets, V shape
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
const qreal height = 100.f;
const qreal width = 200.f;
const int n = 31; // odd number please (3,5,7... )
const qreal verticalStep = height/(2.f+(n+1)/2.f);
const qreal horizontalStep = width/(n+2.f);
for ( int i = 0 ; i < n; i++ ) {
if ( i == 0 ) {
// First item
theData
<< BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
} else if ( i == n-1 ) {
// Last item
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i, Qt::AnchorRight, -1, Qt::AnchorRight, horizontalStep);
} else if ( i == ((n-1)/2) ) {
// midway
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
// << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
<< BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
} else if ( i < ((n-1)/2) ) {
// before midway - going down
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
} else {
// after midway - going up
theData
<< BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
}
if ( i <= ((n-1)/2) ) {
// until midway
theResult
<< BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
} else {
// after midway
theResult
<< BasicResult(i, QRectF((i+1)*horizontalStep, (n-i)*verticalStep, horizontalStep, verticalStep) );
}
}
if (sizeof(qreal) == 4) {
qDebug("V multi: Skipping! (qreal has too little precision, result will be wrong)");
} else {
QTest::newRow("V multi") << QSizeF(width, height) << theData << theResult;
}
}
// Multiple widgets, grid
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
const qreal height = 100.f;
const qreal width = 200.f;
const int d = 10; // items per dimension
const int n = d*d;
const qreal verticalStep = height/(d+2.f);
const qreal horizontalStep = width/(d+2.f);
for ( int i = 0 ; i < n; i++ ) {
if ( i%d == 0 ) {
// left side item
theData
<< BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
} else if ( (i+1)%d == 0 ) {
// rigth side item
theData
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
// << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
<< BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
} else {
// horizontal middle
theData
<< BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
<< BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
}
if ( i < d ) {
// top line
theData
<< BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
} else if ( i >= (d-1)*d ){
// bottom line
theData
<< BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
// << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
<< BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep);
} else {
// vertical middle
theData
<< BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
<< BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
}
theResult
<< BasicResult(i, QRectF(((i%d)+1)*horizontalStep, ((i/d)+1)*verticalStep, horizontalStep, verticalStep) );
}
if (sizeof(qreal) == 4) {
qDebug("Grid multi: Skipping! (qreal has too little precision, result will be wrong)");
} else {
QTest::newRow("Grid multi") << QSizeF(200, 100) << theData << theResult;
}
}
}
inline QGraphicsLayoutItem *getItem(
int index,
const QList<QGraphicsWidget *>& widgets,
QGraphicsLayoutItem *defaultItem)
{
if (index < 0) {
return defaultItem;
}
return widgets[index];
}
static bool fuzzierCompare(qreal a, qreal b)
{
return qAbs(a - b) <= qreal(0.0001);
}
static bool fuzzierCompare(const QRectF &r1, const QRectF &r2)
{
return fuzzierCompare(r1.x(), r2.x()) && fuzzierCompare(r1.y(), r2.y())
&& fuzzierCompare(r1.width(), r2.width()) && fuzzierCompare(r1.height(), r2.height());
}
void tst_QGraphicsAnchorLayout1::testBasicLayout()
{
QFETCH(QSizeF, size);
QFETCH(BasicLayoutTestDataList, data);
QFETCH(BasicLayoutTestResultList, result);
QGraphicsWidget *widget = new QGraphicsWidget;
// Determine amount of widgets to add.
int widgetCount = -1;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
widgetCount = qMax(widgetCount, item.firstIndex);
widgetCount = qMax(widgetCount, item.secondIndex);
}
++widgetCount; // widgetCount is max of indices.
// Create dummy widgets
QList<QGraphicsWidget *> widgets;
for (int i = 0; i < widgetCount; ++i) {
TestWidget *w = new TestWidget(0, QString::fromAscii("W%1").arg(i));
widgets << w;
}
// Setup anchor layout
TheAnchorLayout *layout = new TheAnchorLayout;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
layout->setAnchor(
getItem(item.firstIndex, widgets, layout),
item.firstEdge,
getItem(item.secondIndex, widgets, layout),
item.secondEdge,
item.spacing );
}
widget->setLayout(layout);
widget->setContentsMargins(0,0,0,0);
widget->resize(size);
QCOMPARE(widget->size(), size);
// Validate
for (int i = 0; i < result.count(); ++i) {
const BasicLayoutTestResult item = result[i];
QRectF expected = item.rect;
QRectF actual = widgets[item.index]->geometry();
QVERIFY(fuzzierCompare(actual, expected));
}
// Test mirrored mode
widget->setLayoutDirection(Qt::RightToLeft);
layout->activate();
// Validate
for (int j = 0; j < result.count(); ++j) {
const BasicLayoutTestResult item = result[j];
QRectF mirroredRect(item.rect);
// only valid cases are mirrored
if (mirroredRect.isValid()){
mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
}
QRectF expected = mirroredRect;
QRectF actual = widgets[item.index]->geometry();
QVERIFY(fuzzierCompare(actual, expected));
}
qDeleteAll(widgets);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testNegativeSpacing()
{
// use the same frame
testBasicLayout();
}
void tst_QGraphicsAnchorLayout1::testMixedSpacing()
{
// use the same frame
testBasicLayout();
}
void tst_QGraphicsAnchorLayout1::testMulti()
{
// use the same frame
testBasicLayout();
}
void tst_QGraphicsAnchorLayout1::testCenterAnchors_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// Basic center case
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5);
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::newRow("center, basic") << QSizeF(20, 20) << theData << theResult;
}
// Basic center case, with invalid (shouldn't affect on result)
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
// bogus definitions
<< BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorBottom, 5)
<< BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorVerticalCenter, 5)
<< BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorRight, 5)
<< BasicData(0, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 666)
<< BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 999)
<< BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorLeft, 333)
<< BasicData(-1, Qt::AnchorRight, -1, Qt::AnchorRight, 222)
<< BasicData(0, Qt::AnchorTop, 0, Qt::AnchorTop, 111)
<< BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorBottom, 444);
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult;
}
// Basic center case 2
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
// Not supported << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::newRow("center, basic 2") << QSizeF(20, 20) << theData << theResult;
}
// Basic center case, overrides
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 20)
<< BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 30)
<< BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 40)
// actual data:
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
// << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::newRow("center, overrides") << QSizeF(20, 20) << theData << theResult;
}
// Two nested
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorLeft, 0)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
<< BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorTop, 0)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 0);
theResult
<< BasicResult(0, QRectF(20, 0, 20, 40))
<< BasicResult(1, QRectF(20, 20, 20, 20));
QTest::newRow("center, two nested") << QSizeF(40, 40) << theData << theResult;
}
// Two overlap
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
// theData
// // horizontal
// << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
// << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
// << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
// << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
// << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 10)
// // vertical is pretty much same as horizontal, just roles swapped
// << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
// << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
// << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, -5)
// << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
// << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, 10);
theData
// horizontal
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
<< BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorHorizontalCenter, 5)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 20)
// vertical
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
<< BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorVerticalCenter, 5)
<< BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20);
theResult
<< BasicResult(0, QRectF(20, 30, 20, 30))
<< BasicResult(1, QRectF(30, 20, 30, 20));
QTest::newRow("center, two overlap") << QSizeF(70, 70) << theData << theResult;
}
// Three
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
<< BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
<< BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
<< BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
<< BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
<< BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
<< BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
<< BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
theResult
<< BasicResult(0, QRectF(0, 30, 10, 20))
<< BasicResult(1, QRectF(20, 0, 30, 10))
<< BasicResult(2, QRectF(60, 15, 40, 10));
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult;
}
// Two, parent center
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// vertical is pretty much same as horizontal, just roles swapped
<< BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, -15)
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 10)
<< BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
<< BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
// horizontal
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -15)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0);
theResult
<< BasicResult(0, QRectF(20, 20, 30, 80))
<< BasicResult(1, QRectF(20, 20, 80, 30));
QTest::newRow("center, parent") << QSizeF(100, 100) << theData << theResult;
}
// Two, parent center 2
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, 15)
<< BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, -15)
<< BasicData(1, Qt::AnchorRight, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorRight, -5)
// vertical
<< BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 20)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 20)
<< BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10);
theResult
<< BasicResult(0, QRectF(30, 10, 15, 10))
<< BasicResult(1, QRectF(10, 30, 10, 10));
QTest::newRow("center, parent 2") << QSizeF(50, 50) << theData << theResult;
}
// Two, parent center 3
{
BasicLayoutTestDataList theData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 5)
// << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
<< BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
<< BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, 0)
// vertical
<< BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
<< BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
<< BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10)
// << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
;
theResult
<< BasicResult(0, QRectF(0, 0, 45, 45))
<< BasicResult(1, QRectF(55, 55, 45, 45));
QTest::newRow("center, parent 3") << QSizeF(100, 100) << theData << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testCenterAnchors()
{
// use the same frame
testBasicLayout();
}
void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<BasicLayoutTestDataList>("removeData");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
{
BasicLayoutTestDataList theData;
BasicLayoutTestDataList theRemoveData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
<< BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
<< BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
;
theRemoveData
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0)
<< BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 0)
<< BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0);
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::newRow("remove, center, basic") << QSizeF(20, 20) << theData
<< theRemoveData << theResult;
}
{
BasicLayoutTestDataList theData;
BasicLayoutTestDataList theRemoveData;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
<< BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
<< BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
<< BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
// extra:
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
<< BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
<< BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
<< BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
<< BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
<< BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
<< BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
<< BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
<< BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
theRemoveData
<< BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
<< BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
<< BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55);
theResult
<< BasicResult(0, QRectF(0, 30, 10, 20))
<< BasicResult(1, QRectF(20, 0, 30, 10))
<< BasicResult(2, QRectF(60, 15, 40, 10));
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult;
}
// add edge (item0,edge0,item1,edge1), remove (item1,edge1,item0,edge0)
{
BasicLayoutTestDataList theData;
BasicLayoutTestDataList theRemoveData;
BasicLayoutTestResultList theResult;
theData
// << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
<< BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
<< BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
<< BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
<< BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
<< BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
<< BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 22)
<< BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 11)
;
theRemoveData
<< BasicData(1, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 0)
<< BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 0)
<< BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
<< BasicData(0, Qt::AnchorRight, 0, Qt::AnchorLeft, 0)
<< BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorTop, 0)
;
theResult
<< BasicResult(0, QRectF(5, 5, 10, 10) );
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData
<< theRemoveData << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor()
{
QFETCH(QSizeF, size);
QFETCH(BasicLayoutTestDataList, data);
QFETCH(BasicLayoutTestDataList, removeData);
QFETCH(BasicLayoutTestResultList, result);
QGraphicsWidget *widget = new QGraphicsWidget;
// Determine amount of widgets to add.
int widgetCount = -1;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
widgetCount = qMax(widgetCount, item.firstIndex);
widgetCount = qMax(widgetCount, item.secondIndex);
}
++widgetCount; // widgetCount is max of indices.
// Create dummy widgets
QList<QGraphicsWidget *> widgets;
for (int i = 0; i < widgetCount; ++i) {
TestWidget *w = new TestWidget;
widgets << w;
}
// Setup anchor layout
TheAnchorLayout *layout = new TheAnchorLayout;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
layout->setAnchor(
getItem(item.firstIndex, widgets, layout),
item.firstEdge,
getItem(item.secondIndex, widgets, layout),
item.secondEdge,
item.spacing );
}
for (int i = 0; i < removeData.count(); ++i) {
const BasicLayoutTestData item = removeData[i];
layout->removeAnchor(
getItem(item.firstIndex, widgets, layout),
item.firstEdge,
getItem(item.secondIndex, widgets, layout),
item.secondEdge);
}
widget->setLayout(layout);
widget->setContentsMargins(0,0,0,0);
widget->resize(size);
QCOMPARE(widget->size(), size);
// Validate
for (int i = 0; i < result.count(); ++i) {
const BasicLayoutTestResult item = result[i];
QCOMPARE(widgets[item.index]->geometry(), item.rect);
}
qDeleteAll(widgets);
delete widget;
}
void tst_QGraphicsAnchorLayout1::testSingleSizePolicy_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<QSizePolicy>("policy");
QTest::addColumn<bool>("valid");
// FIXED
{
QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
QTest::newRow("single size policy: fixed ok") << QSizeF(70, 70) << sizePolicy << true;
}
/*
{
QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
QTest::newRow("single size policy: fixed too big") << QSizeF(100, 100) << sizePolicy << false;
}
{
QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
QTest::newRow("single size policy: fixed too small") << QSizeF(50, 50) << sizePolicy << false;
}
*/
// MINIMUM
{
QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
QTest::newRow("single size policy: minimum bigger ok") << QSizeF(100, 100) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
QTest::newRow("single size policy: minimum limit ok") << QSizeF(70, 70) << sizePolicy << true;
}
/*
{
QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
QTest::newRow("single size policy: minimum too small") << QSizeF(50, 50) << sizePolicy << false;
}
*/
// MAXIMUM
{
QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
QTest::newRow("single size policy: maximum small ok") << QSizeF(50, 50) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
QTest::newRow("single size policy: maximum limit ok") << QSizeF(70, 70) << sizePolicy << true;
}
/*
{
QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
QTest::newRow("single size policy: maximum bigger fail") << QSizeF(100, 100) << sizePolicy << false;
}
*/
// PREFERRED
{
QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
QTest::newRow("single size policy: preferred bigger ok") << QSizeF(100, 100) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
QTest::newRow("single size policy: preferred smaller ok") << QSizeF(50, 50) << sizePolicy << true;
}
/*
{
QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
QTest::newRow("single size policy: preferred too big") << QSizeF(700, 700) << sizePolicy << false;
}
{
QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
QTest::newRow("single size policy: preferred too small") << QSizeF(21, 21) << sizePolicy << false;
}
*/
// MINIMUMEXPANDING
{
QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
QTest::newRow("single size policy: min.expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
QTest::newRow("single size policy: min.expanding limit ok") << QSizeF(70, 70) << sizePolicy << true;
}
/*{
QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
QTest::newRow("single size policy: min.expanding too small") << QSizeF(50, 50) << sizePolicy << false;
}*/
// EXPANDING
{
QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
QTest::newRow("single size policy: expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
QTest::newRow("single size policy: expanding smaller ok") << QSizeF(50, 50) << sizePolicy << true;
}
// IGNORED
{
QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
QTest::newRow("single size policy: ignored bigger ok") << QSizeF(100, 100) << sizePolicy << true;
}
{
QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
QTest::newRow("single size policy: ignored smaller ok") << QSizeF(50, 50) << sizePolicy << true;
}
}
void tst_QGraphicsAnchorLayout1::testSingleSizePolicy()
{
QFETCH(QSizeF, size);
QFETCH(QSizePolicy, policy);
QFETCH(bool, valid);
// create objects
QGraphicsWidget widget;
TheAnchorLayout *layout = new TheAnchorLayout;
TestWidget *childWidget = new TestWidget;
// set anchors
layout->setAnchor( layout, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 10 );
layout->setAnchor( childWidget, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
layout->setAnchor( layout, Qt::AnchorTop, childWidget, Qt::AnchorTop, 10 );
layout->setAnchor( childWidget, Qt::AnchorBottom, layout, Qt::AnchorBottom, 10 );
widget.setLayout( layout );
// set test case specific: policy and size
childWidget->setSizePolicy( policy );
widget.setGeometry( QRectF( QPoint(0,0), size ) );
QCOMPARE( layout->isValid() , valid );
const QRectF childRect = childWidget->geometry();
Q_UNUSED( childRect );
}
void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy_data()
{
// tests only horizontal direction
QTest::addColumn<QSizePolicy>("policy1");
QTest::addColumn<QSizePolicy>("policy2");
QTest::addColumn<qreal>("width1");
QTest::addColumn<qreal>("width2");
// layout size always 100x100 and size hints for items are 5<50<500
// gabs: 10-item1-10-item2-10
{
QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 50;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: fixed-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 50;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: minimum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 35;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: maximum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 35;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: preferred-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 50;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: min.expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 35;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
// QGAL handling of ignored flag is different
if (0)
{
QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
const qreal width1 = 35;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: ignored-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
/*{
QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = -1;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: fixed-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
}*/
/*{
QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = -1;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: minimum-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
}*/
{
QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = 20;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: maximum-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = 20;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: preferred-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
/*{
QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = -1;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: min.expanding-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
}*/
{
QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = 20;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: expanding-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
{
QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
const qreal width1 = 20;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("double size policy: ignored-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
}
}
void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy()
{
QFETCH(QSizePolicy, policy1);
QFETCH(QSizePolicy, policy2);
QFETCH(qreal, width1);
QFETCH(qreal, width2);
// create objects
QGraphicsWidget widget;
TheAnchorLayout *layout = new TheAnchorLayout;
TestWidget *childWidget1 = new TestWidget;
TestWidget *childWidget2 = new TestWidget;
// set anchors
layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
widget.setLayout( layout );
// set test case specific: policy
childWidget1->setSizePolicy( policy1 );
childWidget2->setSizePolicy( policy2 );
widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
// check results:
if ( width1 == -1.0f ) {
// invalid
QCOMPARE( layout->isValid() , false );
} else {
// valid
QCOMPARE( childWidget1->geometry().width(), width1 );
QCOMPARE( childWidget2->geometry().width(), width2 );
}
}
typedef QMap<int,qreal> SizeHintArray;
Q_DECLARE_METATYPE(SizeHintArray)
void tst_QGraphicsAnchorLayout1::testSizeDistribution_data()
{
// tests only horizontal direction
QTest::addColumn<SizeHintArray>("sizeHints1");
QTest::addColumn<SizeHintArray>("sizeHints2");
QTest::addColumn<qreal>("width1");
QTest::addColumn<qreal>("width2");
// layout size always 100x100 and size policy for items is preferred-preferred
// gabs: 10-item1-10-item2-10
{
SizeHintArray sizeHints1;
sizeHints1.insert( Qt::MinimumSize, 30 );
sizeHints1.insert( Qt::PreferredSize, 35 );
sizeHints1.insert( Qt::MaximumSize, 40 );
Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
SizeHintArray sizeHints2;
sizeHints2.insert( Qt::MinimumSize, 5 );
sizeHints2.insert( Qt::PreferredSize, 35 );
sizeHints2.insert( Qt::MaximumSize, 300 );
Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
const qreal width1 = 35;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("size distribution: preferred equal") << sizeHints1 << sizeHints2 << width1 << width2;
}
{
SizeHintArray sizeHints1;
sizeHints1.insert( Qt::MinimumSize, 0 );
sizeHints1.insert( Qt::PreferredSize, 20 );
sizeHints1.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
SizeHintArray sizeHints2;
sizeHints2.insert( Qt::MinimumSize, 0 );
sizeHints2.insert( Qt::PreferredSize, 50 );
sizeHints2.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
const qreal width1 = 20;
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("size distribution: preferred non-equal") << sizeHints1 << sizeHints2 << width1 << width2;
}
{
SizeHintArray sizeHints1;
sizeHints1.insert( Qt::MinimumSize, 0 );
sizeHints1.insert( Qt::PreferredSize, 40 );
sizeHints1.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
SizeHintArray sizeHints2;
sizeHints2.insert( Qt::MinimumSize, 0 );
sizeHints2.insert( Qt::PreferredSize, 60 );
sizeHints2.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
const qreal width1 = 28; // got from manual calculation
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("size distribution: below preferred") << sizeHints1 << sizeHints2 << width1 << width2;
}
{
SizeHintArray sizeHints1;
sizeHints1.insert( Qt::MinimumSize, 0 );
sizeHints1.insert( Qt::PreferredSize, 10 );
sizeHints1.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
SizeHintArray sizeHints2;
sizeHints2.insert( Qt::MinimumSize, 0 );
sizeHints2.insert( Qt::PreferredSize, 40 );
sizeHints2.insert( Qt::MaximumSize, 100 );
Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
const qreal width1 = 22; // got from manual calculation
const qreal width2 = 100-10-10-10-width1;
QTest::newRow("size distribution: above preferred") << sizeHints1 << sizeHints2 << width1 << width2;
}
}
void tst_QGraphicsAnchorLayout1::testSizeDistribution()
{
QFETCH(SizeHintArray, sizeHints1);
QFETCH(SizeHintArray, sizeHints2);
QFETCH(qreal, width1);
QFETCH(qreal, width2);
// create objects
QGraphicsWidget widget;
TheAnchorLayout *layout = new TheAnchorLayout;
TestWidget *childWidget1 = new TestWidget;
TestWidget *childWidget2 = new TestWidget;
// set anchors
layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
widget.setLayout( layout );
// set test case specific: size hints
childWidget1->setMinimumWidth( sizeHints1.value( Qt::MinimumSize ) );
childWidget1->setPreferredWidth( sizeHints1.value( Qt::PreferredSize ) );
childWidget1->setMaximumWidth( sizeHints1.value( Qt::MaximumSize ) );
childWidget2->setMinimumWidth( sizeHints2.value( Qt::MinimumSize ) );
childWidget2->setPreferredWidth( sizeHints2.value( Qt::PreferredSize ) );
childWidget2->setMaximumWidth( sizeHints2.value( Qt::MaximumSize ) );
widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
// check results:
if ( width1 == -1.0f ) {
// invalid
QCOMPARE( layout->isValid() , false );
} else {
// valid
QCOMPARE( float(childWidget1->geometry().width()), float(width1) );
QCOMPARE( float(childWidget2->geometry().width()), float(width2) );
}
}
void tst_QGraphicsAnchorLayout1::testSizeHint()
{
QGraphicsWidget *widget[5];
for( int i = 0; i < 5; i++ ) {
widget[i] = new QGraphicsWidget;
widget[i]->setMinimumSize( 10, 10 );
widget[i]->setPreferredSize( 20, 20 );
widget[i]->setMaximumSize( 40, 40 );
}
// one, basic
{
TheAnchorLayout *layout = new TheAnchorLayout();
layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
delete layout;
}
// one, basic again
{
TheAnchorLayout *layout = new TheAnchorLayout();
layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 10 );
// layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, -10 );
layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 10 );
layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 10 );
// layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, -10 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 10 );
QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( 20, 20 ) );
QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( 20, 20 ) );
QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( 20, 20 ) );
delete layout;
}
// two, serial
{
TheAnchorLayout *layout = new TheAnchorLayout();
layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
layout->setAnchor(widget[1], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( widget[1]->minimumWidth(), 0 ) );
QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( widget[1]->preferredWidth(), 0 ) );
QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( widget[1]->maximumWidth(), 0 ) );
delete layout;
}
// two, parallel
{
TheAnchorLayout *layout = new TheAnchorLayout();
layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
layout->setAnchor(layout, Qt::AnchorLeft, widget[1], Qt::AnchorLeft, 0 );
layout->setAnchor(layout, Qt::AnchorTop, widget[1], Qt::AnchorTop, 0 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[1], Qt::AnchorBottom, 0 );
layout->setAnchor(layout, Qt::AnchorRight, widget[1], Qt::AnchorRight, 0 );
QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
delete layout;
}
// five, serial
{
TheAnchorLayout *layout = new TheAnchorLayout();
layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
layout->setAnchor(widget[1], Qt::AnchorRight, widget[2], Qt::AnchorLeft, 0 );
layout->setAnchor(widget[2], Qt::AnchorRight, widget[3], Qt::AnchorLeft, 0 );
layout->setAnchor(widget[3], Qt::AnchorRight, widget[4], Qt::AnchorLeft, 0 );
layout->setAnchor(widget[4], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() +
QSizeF( widget[1]->minimumWidth() +
widget[2]->minimumWidth() +
widget[3]->minimumWidth() +
widget[4]->minimumWidth(), 0 ) );
QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() +
QSizeF( widget[1]->preferredWidth() +
widget[2]->preferredWidth() +
widget[3]->preferredWidth() +
widget[4]->preferredWidth(), 0 ) );
QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() +
QSizeF( widget[1]->maximumWidth() +
widget[2]->maximumWidth() +
widget[3]->maximumWidth() +
widget[4]->maximumWidth(), 0 ) );
delete layout;
}
for( int i = 0; i < 5; i++ ) {
delete widget[i];
}
}
#ifdef TEST_COMPLEX_CASES
void tst_QGraphicsAnchorLayout1::testComplexCases_data()
{
QTest::addColumn<QSizeF>("size");
QTest::addColumn<BasicLayoutTestDataList>("data");
QTest::addColumn<AnchorItemSizeHintList>("sizehint");
QTest::addColumn<BasicLayoutTestResultList>("result");
typedef BasicLayoutTestData BasicData;
typedef BasicLayoutTestResult BasicResult;
// Three widgets, the same sizehint
{
BasicLayoutTestDataList theData;
AnchorItemSizeHintList theSizeHint;
BasicLayoutTestResultList theResult1;
BasicLayoutTestResultList theResult2;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
;
theSizeHint
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
;
theResult1
<< BasicResult(0, QRectF(10, 0, 30, 50) )
<< BasicResult(1, QRectF(50, 0, 30, 50) )
<< BasicResult(2, QRectF(50, 0, 30, 50) )
;
theResult2
<< BasicResult(0, QRectF(10, 0, 60, 50) )
<< BasicResult(1, QRectF(80, 0, 60, 50) )
<< BasicResult(2, QRectF(80, 0, 60, 50) )
;
QTest::newRow("Three, the same sizehint(1)") << QSizeF(90, 50) << theData << theSizeHint << theResult1;
QTest::newRow("Three, the same sizehint(2)") << QSizeF(150, 50) << theData << theSizeHint << theResult2;
}
// Three widgets, serial is bigger
{
BasicLayoutTestDataList theData;
AnchorItemSizeHintList theSizeHint;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
;
theSizeHint
<< AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
;
theResult
<< BasicResult(0, QRectF(10, 0, 70, 50) )
<< BasicResult(1, QRectF(90, 0, 35, 50) )
<< BasicResult(2, QRectF(90, 0, 35, 50) );
QTest::newRow("Three, serial is bigger") << QSizeF(135, 50) << theData << theSizeHint << theResult;
// theResult
// << BasicResult(0, QRectF(10, 0, 80, 50) )
// << BasicResult(1, QRectF(100, 0, 60, 50) )
// << BasicResult(2, QRectF(100, 0, 60, 50) )
// ;
// QTest::newRow("Three, serial is bigger") << QSizeF(170, 50) << theData << theSizeHint << theResult;
}
// Three widgets, parallel is bigger
{
BasicLayoutTestDataList theData;
AnchorItemSizeHintList theSizeHint;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
;
theSizeHint
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
;
// ### QGAL uses a different preferred size calculation algorithm.
// This algorithm was discussed with Jan-Arve and tries to grow
// items instead of shrinking them.
// In this case, the preferred size of each item becomes:
// Item 0: 50
// Item 1: 100 (grows to avoid shrinking item 2)
// Item 2: 100
// Therefore, the preferred size of the parent widget becomes
// 180 == (10 + 50 + 10 + 100 + 10)
// As we set its size to 150, each widget is shrinked in the same
// ratio, in order to achieve the width of 150 == (10 + 40 + 10 + 80 + 10)
theResult
<< BasicResult(0, QRectF(10, 0, 40, 50) )
<< BasicResult(1, QRectF(60, 0, 80, 50) )
<< BasicResult(2, QRectF(60, 0, 80, 50) )
;
QTest::newRow("Three, parallel is bigger") << QSizeF(150, 50) << theData << theSizeHint << theResult;
// #ifdef PREFERRED_IS_AVERAGE
// theResult
// << BasicResult(0, QRectF(10, 0, 50, 50) )
// << BasicResult(1, QRectF(70, 0, 75, 50) )
// << BasicResult(2, QRectF(70, 0, 75, 50) )
// ;
// QTest::newRow("Three, parallel is bigger") << QSizeF(155, 50) << theData << theSizeHint << theResult;
// #else
// theResult
// << BasicResult(0, QRectF(10, 0, 50, 50) )
// << BasicResult(1, QRectF(70, 0, 66.66666666666666, 50) )
// << BasicResult(2, QRectF(70, 0, 60.66666666666666, 50) )
// ;
// QTest::newRow("Three, parallel is bigger") << QSizeF(146.66666666666666, 50) << theData << theSizeHint << theResult;
// #endif
}
// Three widgets, the same sizehint, one center anchor
{
BasicLayoutTestDataList theData;
AnchorItemSizeHintList theSizeHint;
BasicLayoutTestResultList theResult;
theData
<< BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
<< BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorLeft, 10)
<< BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
<< BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
<< BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
;
theSizeHint
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
<< AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
;
theResult
<< BasicResult(0, QRectF(10, 0, 40, 50) )
<< BasicResult(1, QRectF(60, 0, 40, 50) )
<< BasicResult(2, QRectF(40, 0, 60, 50) )
;
;
QTest::newRow("Three, the same sizehint, one center anchor") << QSizeF(110, 50) << theData << theSizeHint << theResult;
}
}
void tst_QGraphicsAnchorLayout1::testComplexCases()
{
QFETCH(QSizeF, size);
QFETCH(BasicLayoutTestDataList, data);
QFETCH(AnchorItemSizeHintList, sizehint);
QFETCH(BasicLayoutTestResultList, result);
QGraphicsWidget *widget = new QGraphicsWidget;
// Determine amount of widgets to add.
int widgetCount = -1;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
widgetCount = qMax(widgetCount, item.firstIndex);
widgetCount = qMax(widgetCount, item.secondIndex);
}
++widgetCount; // widgetCount is max of indices.
// Create dummy widgets
QList<QGraphicsWidget *> widgets;
for (int i = 0; i < widgetCount; ++i) {
TestWidget *w = new TestWidget;
w->setMinimumWidth( sizehint[i].hmin );
w->setPreferredWidth( sizehint[i].hpref );
w->setMaximumWidth( sizehint[i].hmax );
w->setMinimumHeight( sizehint[i].vmin );
w->setPreferredHeight( sizehint[i].vpref );
w->setMaximumHeight( sizehint[i].vmax );
widgets << w;
}
// Setup anchor layout
TheAnchorLayout *layout = new TheAnchorLayout;
for (int i = 0; i < data.count(); ++i) {
const BasicLayoutTestData item = data[i];
layout->setAnchor(
getItem(item.firstIndex, widgets, layout),
item.firstEdge,
getItem(item.secondIndex, widgets, layout),
item.secondEdge,
item.spacing );
}
widget->setLayout(layout);
widget->setContentsMargins(0,0,0,0);
widget->resize(size);
QCOMPARE(widget->size(), size);
// QTest::qWait(500); // layouting is asynchronous..
// Validate
for (int i = 0; i < result.count(); ++i) {
const BasicLayoutTestResult item = result[i];
QCOMPARE(widgets[item.index]->geometry(), item.rect);
}
// Test mirrored mode
widget->setLayoutDirection(Qt::RightToLeft);
layout->activate();
// Validate
for (int j = 0; j < result.count(); ++j) {
const BasicLayoutTestResult item = result[j];
QRectF mirroredRect(item.rect);
// only valid cases are mirrored
if (mirroredRect.isValid()){
mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
}
QCOMPARE(widgets[item.index]->geometry(), mirroredRect);
delete widgets[item.index];
}
delete widget;
}
#endif //TEST_COMPLEX_CASES
QTEST_MAIN(tst_QGraphicsAnchorLayout1)
#include "tst_qgraphicsanchorlayout1.moc"
//-----------------------------------------------------------------------------