qt 6.5.1 original
23
tests/auto/widgets/graphicsview/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qgraphicsanchorlayout)
|
||||
add_subdirectory(qgraphicsanchorlayout1)
|
||||
add_subdirectory(qgraphicsitem)
|
||||
add_subdirectory(qgraphicsscene)
|
||||
add_subdirectory(qgraphicssceneindex)
|
||||
endif()
|
||||
add_subdirectory(qgraphicseffectsource)
|
||||
add_subdirectory(qgraphicsgridlayout)
|
||||
add_subdirectory(qgraphicsitemanimation)
|
||||
add_subdirectory(qgraphicslayout)
|
||||
add_subdirectory(qgraphicslayoutitem)
|
||||
add_subdirectory(qgraphicslinearlayout)
|
||||
add_subdirectory(qgraphicsobject)
|
||||
add_subdirectory(qgraphicspixmapitem)
|
||||
add_subdirectory(qgraphicspolygonitem)
|
||||
add_subdirectory(qgraphicstransform)
|
||||
add_subdirectory(qgraphicsproxywidget)
|
||||
add_subdirectory(qgraphicswidget)
|
||||
add_subdirectory(qgraphicsview)
|
@ -0,0 +1,3 @@
|
||||
[layoutDirection]
|
||||
ubuntu-20.04
|
||||
ubuntu-22.04
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsanchorlayout Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsanchorlayout
|
||||
SOURCES
|
||||
tst_qgraphicsanchorlayout.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsanchorlayout1 Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsanchorlayout1
|
||||
SOURCES
|
||||
tst_qgraphicsanchorlayout1.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicseffectsource Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicseffectsource
|
||||
SOURCES
|
||||
tst_qgraphicseffectsource.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1,381 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
#include <QtWidgets/qgraphicseffect.h>
|
||||
#include <QtWidgets/qgraphicsview.h>
|
||||
#include <QtWidgets/qgraphicsscene.h>
|
||||
#include <QtWidgets/qgraphicsitem.h>
|
||||
#include <QtWidgets/qstyleoption.h>
|
||||
|
||||
#include <private/qgraphicseffect_p.h>
|
||||
|
||||
class CustomItem : public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
CustomItem(qreal x, qreal y, qreal width, qreal height)
|
||||
: QGraphicsRectItem(x, y, width, height), numRepaints(0),
|
||||
m_painter(0)
|
||||
{}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
|
||||
{
|
||||
m_painter = painter;
|
||||
++numRepaints;
|
||||
QGraphicsRectItem::paint(painter, option, widget);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
numRepaints = 0;
|
||||
m_painter = 0;
|
||||
}
|
||||
|
||||
int numRepaints;
|
||||
QPainter *m_painter;
|
||||
};
|
||||
|
||||
class CustomEffect : public QGraphicsEffect
|
||||
{
|
||||
public:
|
||||
CustomEffect()
|
||||
: QGraphicsEffect(), numRepaints(0), m_margin(10), m_sourceChanged(false),
|
||||
m_sourceBoundingRectChanged(false), doNothingInDraw(false),
|
||||
storeDeviceDependentStuff(false),
|
||||
m_painter(0), m_source(0)
|
||||
{}
|
||||
|
||||
QRectF boundingRectFor(const QRectF &rect) const override
|
||||
{ return rect.adjusted(-m_margin, -m_margin, m_margin, m_margin); }
|
||||
|
||||
void reset()
|
||||
{
|
||||
numRepaints = 0;
|
||||
m_sourceChanged = false;
|
||||
m_sourceBoundingRectChanged = false;
|
||||
m_painter = 0;
|
||||
m_source = 0;
|
||||
deviceCoordinatesPixmap = QPixmap();
|
||||
deviceRect = QRect();
|
||||
sourceDeviceBoundingRect = QRectF();
|
||||
}
|
||||
|
||||
void setMargin(int margin)
|
||||
{
|
||||
m_margin = margin;
|
||||
updateBoundingRect();
|
||||
}
|
||||
|
||||
int margin() const
|
||||
{ return m_margin; }
|
||||
|
||||
void draw(QPainter *painter) override
|
||||
{
|
||||
++numRepaints;
|
||||
if (storeDeviceDependentStuff) {
|
||||
deviceCoordinatesPixmap = source()->pixmap(Qt::DeviceCoordinates);
|
||||
deviceRect = QRect(0, 0, painter->device()->width(), painter->device()->height());
|
||||
sourceDeviceBoundingRect = source()->boundingRect(Qt::DeviceCoordinates);
|
||||
}
|
||||
if (doNothingInDraw)
|
||||
return;
|
||||
m_source = source();
|
||||
m_painter = painter;
|
||||
source()->draw(painter);
|
||||
}
|
||||
|
||||
void sourceChanged(ChangeFlags) override
|
||||
{ m_sourceChanged = true; }
|
||||
|
||||
void sourceBoundingRectChanged()
|
||||
{ m_sourceBoundingRectChanged = true; }
|
||||
|
||||
int numRepaints;
|
||||
int m_margin;
|
||||
bool m_sourceChanged;
|
||||
bool m_sourceBoundingRectChanged;
|
||||
bool doNothingInDraw;
|
||||
bool storeDeviceDependentStuff;
|
||||
QPainter *m_painter;
|
||||
QGraphicsEffectSource *m_source;
|
||||
QPixmap deviceCoordinatesPixmap;
|
||||
QRect deviceRect;
|
||||
QRectF sourceDeviceBoundingRect;
|
||||
};
|
||||
|
||||
class tst_QGraphicsEffectSource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
|
||||
private slots:
|
||||
void graphicsItem();
|
||||
void styleOption();
|
||||
void isPixmap();
|
||||
void draw();
|
||||
void update();
|
||||
void boundingRect();
|
||||
void clippedBoundingRect();
|
||||
void deviceRect();
|
||||
void pixmap();
|
||||
|
||||
void pixmapPadding_data();
|
||||
void pixmapPadding();
|
||||
|
||||
private:
|
||||
QGraphicsView *view;
|
||||
QGraphicsScene *scene;
|
||||
CustomItem *item;
|
||||
CustomEffect *effect;
|
||||
};
|
||||
|
||||
void tst_QGraphicsEffectSource::initTestCase()
|
||||
{
|
||||
scene = new QGraphicsScene;
|
||||
item = new CustomItem(0, 0, 100, 100);
|
||||
effect = new CustomEffect;
|
||||
item->setGraphicsEffect(effect);
|
||||
scene->addItem(item);
|
||||
view = new QGraphicsView(scene);
|
||||
view->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(view));
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::cleanupTestCase()
|
||||
{
|
||||
delete view;
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::init()
|
||||
{
|
||||
QVERIFY(effect);
|
||||
QVERIFY(item);
|
||||
QVERIFY(effect->source());
|
||||
effect->storeDeviceDependentStuff = false;
|
||||
effect->doNothingInDraw = false;
|
||||
QCoreApplication::processEvents(); // Process all queued paint events
|
||||
effect->reset();
|
||||
item->reset();
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::graphicsItem()
|
||||
{
|
||||
QVERIFY(effect->source());
|
||||
QCOMPARE(effect->source()->graphicsItem(), (const QGraphicsItem*)item);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::styleOption()
|
||||
{
|
||||
// We don't have style options unless the source is drawing.
|
||||
QVERIFY(effect->source());
|
||||
QVERIFY(!effect->source()->styleOption());
|
||||
|
||||
// Trigger an update and check that the style option in QGraphicsEffect::draw
|
||||
// was the same as the one in QGraphicsItem::paint.
|
||||
QCOMPARE(item->numRepaints, 0);
|
||||
QCOMPARE(effect->numRepaints, 0);
|
||||
item->update();
|
||||
QTRY_COMPARE(item->numRepaints, 1);
|
||||
QTRY_COMPARE(effect->numRepaints, 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::isPixmap()
|
||||
{
|
||||
// Current source is a CustomItem (which is not a pixmap item).
|
||||
QVERIFY(!effect->source()->isPixmap());
|
||||
|
||||
// Make sure isPixmap() returns true for QGraphicsPixmapItem.
|
||||
QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem;
|
||||
CustomEffect *anotherEffect = new CustomEffect;
|
||||
pixmapItem->setGraphicsEffect(anotherEffect);
|
||||
QVERIFY(anotherEffect->source());
|
||||
QCOMPARE(anotherEffect->source()->graphicsItem(), static_cast<const QGraphicsItem *>(pixmapItem));
|
||||
QVERIFY(anotherEffect->source()->isPixmap());
|
||||
delete pixmapItem;
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::draw()
|
||||
{
|
||||
// The source can only draw as a result of QGraphicsEffect::draw.
|
||||
QTest::ignoreMessage(QtWarningMsg, "QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
|
||||
QPixmap dummyPixmap(10, 10);
|
||||
QPainter dummyPainter(&dummyPixmap);
|
||||
effect->source()->draw(&dummyPainter);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::update()
|
||||
{
|
||||
QCOMPARE(item->numRepaints, 0);
|
||||
QCOMPARE(effect->numRepaints, 0);
|
||||
|
||||
effect->source()->update();
|
||||
|
||||
QTRY_COMPARE(item->numRepaints, 1);
|
||||
QTRY_COMPARE(effect->numRepaints, 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::boundingRect()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
|
||||
QCOMPARE(effect->source()->boundingRect(Qt::DeviceCoordinates), QRectF());
|
||||
|
||||
QRectF itemBoundingRect = item->boundingRect();
|
||||
if (!item->childItems().isEmpty())
|
||||
itemBoundingRect |= item->childrenBoundingRect();
|
||||
|
||||
// We can at least check that the device bounding rect was correct in QGraphicsEffect::draw.
|
||||
effect->storeDeviceDependentStuff = true;
|
||||
effect->source()->update();
|
||||
const QTransform deviceTransform = item->deviceTransform(view->viewportTransform());
|
||||
QTRY_COMPARE(effect->sourceDeviceBoundingRect, deviceTransform.mapRect(itemBoundingRect));
|
||||
|
||||
// Bounding rect in logical coordinates is of course fine.
|
||||
QTRY_COMPARE(effect->source()->boundingRect(Qt::LogicalCoordinates), itemBoundingRect);
|
||||
// Make sure default value is Qt::LogicalCoordinates.
|
||||
QTRY_COMPARE(effect->source()->boundingRect(), itemBoundingRect);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::clippedBoundingRect()
|
||||
{
|
||||
QRectF itemBoundingRect = item->boundingRect();
|
||||
item->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
|
||||
|
||||
QGraphicsRectItem *child = new QGraphicsRectItem(-1000, -1000, 2000, 2000);
|
||||
child->setBrush(Qt::red);
|
||||
child->setParentItem(item);
|
||||
|
||||
effect->storeDeviceDependentStuff = true;
|
||||
effect->source()->update();
|
||||
QTRY_COMPARE(effect->source()->boundingRect(Qt::LogicalCoordinates), itemBoundingRect);
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::deviceRect()
|
||||
{
|
||||
effect->storeDeviceDependentStuff = true;
|
||||
effect->source()->update();
|
||||
QTRY_COMPARE(effect->deviceRect, view->viewport()->rect());
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::pixmap()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
|
||||
QCOMPARE(effect->source()->pixmap(Qt::DeviceCoordinates), QPixmap());
|
||||
|
||||
// We can at least verify a valid pixmap from QGraphicsEffect::draw.
|
||||
effect->storeDeviceDependentStuff = true;
|
||||
effect->source()->update();
|
||||
QTRY_VERIFY(!effect->deviceCoordinatesPixmap.isNull());
|
||||
|
||||
// Pixmaps in logical coordinates we can do fine.
|
||||
QPixmap pixmap1 = effect->source()->pixmap(Qt::LogicalCoordinates);
|
||||
QVERIFY(!pixmap1.isNull());
|
||||
|
||||
// Make sure default value is Qt::LogicalCoordinates.
|
||||
QPixmap pixmap2 = effect->source()->pixmap();
|
||||
QCOMPARE(pixmap1, pixmap2);
|
||||
}
|
||||
|
||||
class PaddingEffect : public QGraphicsEffect
|
||||
{
|
||||
public:
|
||||
PaddingEffect(QObject *parent) : QGraphicsEffect(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QRectF boundingRectFor(const QRectF &src) const override
|
||||
{
|
||||
return src.adjusted(-10, -10, 10, 10);
|
||||
}
|
||||
|
||||
void draw(QPainter *) override
|
||||
{
|
||||
pix = source()->pixmap(coordinateMode, &offset, padMode);
|
||||
}
|
||||
|
||||
QPixmap pix;
|
||||
QPoint offset;
|
||||
QGraphicsEffect::PixmapPadMode padMode;
|
||||
Qt::CoordinateSystem coordinateMode;
|
||||
};
|
||||
|
||||
void tst_QGraphicsEffectSource::pixmapPadding_data()
|
||||
{
|
||||
QTest::addColumn<int>("coordinateMode");
|
||||
QTest::addColumn<int>("padMode");
|
||||
QTest::addColumn<QSize>("size");
|
||||
QTest::addColumn<QPoint>("offset");
|
||||
QTest::addColumn<uint>("ulPixel");
|
||||
|
||||
QTest::newRow("log,nopad") << int(Qt::LogicalCoordinates)
|
||||
<< int(QGraphicsEffect::NoPad)
|
||||
<< QSize(10, 10) << QPoint(0, 0)
|
||||
<< 0xffff0000u;
|
||||
|
||||
QTest::newRow("log,transparent") << int(Qt::LogicalCoordinates)
|
||||
<< int(QGraphicsEffect::PadToTransparentBorder)
|
||||
<< QSize(14, 14) << QPoint(-2, -2)
|
||||
<< 0x00000000u;
|
||||
|
||||
QTest::newRow("log,effectrect") << int(Qt::LogicalCoordinates)
|
||||
<< int(QGraphicsEffect::PadToEffectiveBoundingRect)
|
||||
<< QSize(20, 20) << QPoint(-5, -5)
|
||||
<< 0x00000000u;
|
||||
|
||||
QTest::newRow("dev,nopad") << int(Qt::DeviceCoordinates)
|
||||
<< int(QGraphicsEffect::NoPad)
|
||||
<< QSize(20, 20) << QPoint(40, 40)
|
||||
<< 0xffff0000u;
|
||||
|
||||
QTest::newRow("dev,transparent") << int(Qt::DeviceCoordinates)
|
||||
<< int(QGraphicsEffect::PadToTransparentBorder)
|
||||
<< QSize(24, 24) << QPoint(38, 38)
|
||||
<< 0x00000000u;
|
||||
|
||||
QTest::newRow("dev,effectrect") << int(Qt::DeviceCoordinates)
|
||||
<< int(QGraphicsEffect::PadToEffectiveBoundingRect)
|
||||
<< QSize(40, 40) << QPoint(30, 30)
|
||||
<< 0x00000000u;
|
||||
|
||||
}
|
||||
|
||||
void tst_QGraphicsEffectSource::pixmapPadding()
|
||||
{
|
||||
QPixmap dummyTarget(100, 100);
|
||||
QPainter dummyPainter(&dummyTarget);
|
||||
dummyPainter.translate(40, 40);
|
||||
dummyPainter.scale(2, 2);
|
||||
|
||||
QPixmap pm(10, 10);
|
||||
pm.fill(Qt::red);
|
||||
|
||||
QGraphicsScene *scene = new QGraphicsScene();
|
||||
PaddingEffect *effect = new PaddingEffect(scene);
|
||||
QGraphicsPixmapItem *pmItem = new QGraphicsPixmapItem(pm);
|
||||
scene->addItem(pmItem);
|
||||
pmItem->setGraphicsEffect(effect);
|
||||
|
||||
QFETCH(int, coordinateMode);
|
||||
QFETCH(int, padMode);
|
||||
QFETCH(QPoint, offset);
|
||||
QFETCH(QSize, size);
|
||||
QFETCH(uint, ulPixel);
|
||||
|
||||
effect->padMode = (QGraphicsEffect::PixmapPadMode) padMode;
|
||||
effect->coordinateMode = (Qt::CoordinateSystem) coordinateMode;
|
||||
|
||||
scene->render(&dummyPainter, scene->itemsBoundingRect(), scene->itemsBoundingRect());
|
||||
|
||||
QCOMPARE(effect->pix.size(), size);
|
||||
QCOMPARE(effect->offset, offset);
|
||||
QCOMPARE(effect->pix.toImage().pixel(0, 0), ulPixel);
|
||||
|
||||
// ### Fix corruption in scene destruction, then enable...
|
||||
// delete scene;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsEffectSource)
|
||||
#include "tst_qgraphicseffectsource.moc"
|
||||
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsgridlayout Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsgridlayout
|
||||
SOURCES
|
||||
tst_qgraphicsgridlayout.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
3
tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
# QTBUG-74760
|
||||
[sorting]
|
||||
osx
|
28
tests/auto/widgets/graphicsview/qgraphicsitem/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsitem Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsitem
|
||||
SOURCES
|
||||
tst_qgraphicsitem.cpp
|
||||
DEFINES
|
||||
QT_NO_CAST_TO_ASCII
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qgraphicsitem CONDITION WIN32
|
||||
LIBRARIES
|
||||
user32
|
||||
)
|
11883
tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsitemanimation Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsitemanimation
|
||||
SOURCES
|
||||
tst_qgraphicsitemanimation.cpp
|
||||
DEFINES
|
||||
QT_NO_CAST_TO_ASCII
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <qgraphicsitemanimation.h>
|
||||
#include <QtCore/qtimeline.h>
|
||||
|
||||
class tst_QGraphicsItemAnimation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void construction();
|
||||
void linearMove();
|
||||
void linearRotation();
|
||||
void checkReturnedLists();
|
||||
void overwriteValueForStep();
|
||||
void setTimeLine();
|
||||
};
|
||||
|
||||
void tst_QGraphicsItemAnimation::construction()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
QVERIFY(!animation.item());
|
||||
QVERIFY(!animation.timeLine());
|
||||
QCOMPARE(animation.posAt(0), QPointF());
|
||||
QCOMPARE(animation.posAt(0.5), QPointF());
|
||||
QCOMPARE(animation.posAt(1), QPointF());
|
||||
QCOMPARE(animation.transformAt(0), QTransform());
|
||||
QCOMPARE(animation.transformAt(0.5), QTransform());
|
||||
QCOMPARE(animation.transformAt(1), QTransform());
|
||||
QCOMPARE(animation.rotationAt(0), qreal(0.0));
|
||||
QCOMPARE(animation.rotationAt(0.5), qreal(0.0));
|
||||
QCOMPARE(animation.rotationAt(1), qreal(0.0));
|
||||
QCOMPARE(animation.xTranslationAt(0), qreal(0.0));
|
||||
QCOMPARE(animation.xTranslationAt(0.5), qreal(0.0));
|
||||
QCOMPARE(animation.xTranslationAt(1), qreal(0.0));
|
||||
QCOMPARE(animation.yTranslationAt(0), qreal(0.0));
|
||||
QCOMPARE(animation.yTranslationAt(0.5), qreal(0.0));
|
||||
QCOMPARE(animation.yTranslationAt(1), qreal(0.0));
|
||||
QCOMPARE(animation.verticalScaleAt(0), qreal(1.0));
|
||||
QCOMPARE(animation.horizontalScaleAt(0), qreal(1.0));
|
||||
QCOMPARE(animation.verticalShearAt(0), qreal(0.0));
|
||||
QCOMPARE(animation.horizontalShearAt(0), qreal(0.0));
|
||||
animation.clear(); // don't crash
|
||||
}
|
||||
|
||||
void tst_QGraphicsItemAnimation::linearMove()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
|
||||
for (int i = 0; i <= 10; ++i) {
|
||||
QCOMPARE(animation.posAt(i / 10.0).x(), qreal(0));
|
||||
QCOMPARE(animation.posAt(i / 10.0).y(), qreal(0));
|
||||
}
|
||||
|
||||
animation.setPosAt(1, QPointF(10, -10));
|
||||
|
||||
for (int i = 0; i <= 10; ++i) {
|
||||
QCOMPARE(animation.posAt(i / 10.0).x(), qreal(i));
|
||||
QCOMPARE(animation.posAt(i / 10.0).y(), qreal(-i));
|
||||
}
|
||||
|
||||
animation.setPosAt(2, QPointF(10, -10));
|
||||
|
||||
QCOMPARE(animation.posAt(11).x(), qreal(10));
|
||||
}
|
||||
|
||||
void tst_QGraphicsItemAnimation::linearRotation()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
animation.setRotationAt(1, 1);
|
||||
|
||||
for (int i = 0; i <= 10; ++i)
|
||||
QCOMPARE(animation.rotationAt(i / 10.0), qreal(i / 10.0));
|
||||
}
|
||||
|
||||
void tst_QGraphicsItemAnimation::checkReturnedLists()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
|
||||
animation.setPosAt(1.0, QPointF(10, -10));
|
||||
animation.setPosAt(0.5, QPointF(5, -5));
|
||||
|
||||
animation.setRotationAt(0.3, 2.3);
|
||||
animation.setTranslationAt(0.3, 15, 15);
|
||||
animation.setScaleAt(0.3, 2.5, 1.8);
|
||||
animation.setShearAt(0.3, 5, 5);
|
||||
|
||||
QCOMPARE(animation.posList().at(0), (QPair<qreal, QPointF>(0.5, QPointF(5, -5))));
|
||||
QCOMPARE(animation.posList().at(1), (QPair<qreal, QPointF>(1.0, QPointF(10, -10))));
|
||||
QCOMPARE(animation.rotationList().at(0), (QPair<qreal, qreal>(0.3, 2.3)));
|
||||
QCOMPARE(animation.translationList().at(0), (QPair<qreal, QPointF>(0.3, QPointF(15, 15))));
|
||||
QCOMPARE(animation.scaleList().at(0), (QPair<qreal, QPointF>(0.3, QPointF(2.5, 1.8))));
|
||||
QCOMPARE(animation.shearList().at(0), (QPair<qreal, QPointF>(0.3, QPointF(5, 5))));
|
||||
|
||||
QCOMPARE(animation.posList().size(), 2);
|
||||
QCOMPARE(animation.rotationList().size(), 1);
|
||||
QCOMPARE(animation.translationList().size(), 1);
|
||||
QCOMPARE(animation.scaleList().size(), 1);
|
||||
QCOMPARE(animation.shearList().size(), 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsItemAnimation::overwriteValueForStep()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
|
||||
for (int i=0; i<3; i++){
|
||||
animation.setPosAt(0.3, QPointF(3, -3.1));
|
||||
animation.setRotationAt(0.3, 2.3);
|
||||
animation.setTranslationAt(0.3, 15, 15);
|
||||
animation.setScaleAt(0.3, 2.5, 1.8);
|
||||
animation.setShearAt(0.3, 5, 5);
|
||||
|
||||
QCOMPARE(animation.posList().size(), 1);
|
||||
QCOMPARE(animation.rotationList().size(), 1);
|
||||
QCOMPARE(animation.translationList().size(), 1);
|
||||
QCOMPARE(animation.scaleList().size(), 1);
|
||||
QCOMPARE(animation.shearList().size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsItemAnimation::setTimeLine()
|
||||
{
|
||||
QGraphicsItemAnimation animation;
|
||||
QCOMPARE(animation.timeLine(), nullptr);
|
||||
|
||||
QPointer<QTimeLine> line1 = new QTimeLine;
|
||||
animation.setTimeLine(line1);
|
||||
QCOMPARE(animation.timeLine(), (QTimeLine *)line1);
|
||||
animation.setTimeLine(line1);
|
||||
QVERIFY(line1);
|
||||
QCOMPARE(animation.timeLine(), (QTimeLine *)line1);
|
||||
|
||||
animation.setTimeLine(0);
|
||||
QCOMPARE(animation.timeLine(), nullptr);
|
||||
QVERIFY(!line1);
|
||||
|
||||
QTimeLine *line2 = new QTimeLine;
|
||||
animation.setTimeLine(line2);
|
||||
QCOMPARE(animation.timeLine(), (QTimeLine *)line2);
|
||||
|
||||
delete line2;
|
||||
QCOMPARE(animation.timeLine(), nullptr);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsItemAnimation)
|
||||
#include "tst_qgraphicsitemanimation.moc"
|
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicslayout Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicslayout
|
||||
SOURCES
|
||||
tst_qgraphicslayout.cpp
|
||||
DEFINES
|
||||
QT_USE_USING_NAMESPACE
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,980 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <math.h>
|
||||
|
||||
class tst_QGraphicsLayout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QGraphicsLayout();
|
||||
virtual ~tst_QGraphicsLayout();
|
||||
|
||||
private slots:
|
||||
void sizeHints();
|
||||
void compressLayoutRequest();
|
||||
void automaticReparenting();
|
||||
void verifyActivate();
|
||||
void sizeHintOfHiddenLayout();
|
||||
void invalidate();
|
||||
void constructors();
|
||||
void alternativeLayoutItems();
|
||||
void ownership();
|
||||
};
|
||||
|
||||
tst_QGraphicsLayout::tst_QGraphicsLayout()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QGraphicsLayout::~tst_QGraphicsLayout()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayout::sizeHints()
|
||||
{
|
||||
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(window);
|
||||
lout->setContentsMargins(0,0,0,0);
|
||||
QGraphicsWidget *gw = new QGraphicsWidget(window);
|
||||
gw->setMinimumSize(QSizeF(10,10));
|
||||
gw->setPreferredSize(QSizeF(100,100));
|
||||
gw->setMaximumSize(QSizeF(500,500));
|
||||
lout->addItem(gw);
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::MinimumSize), gw->effectiveSizeHint(Qt::MinimumSize));
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::PreferredSize), gw->effectiveSizeHint(Qt::PreferredSize));
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::MaximumSize), gw->effectiveSizeHint(Qt::MaximumSize));
|
||||
|
||||
}
|
||||
|
||||
enum FunctionType {
|
||||
SetGeometry = 0,
|
||||
Invalidate,
|
||||
NumFunctionTypes
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TestGraphicsWidget : public QGraphicsWidget {
|
||||
public:
|
||||
TestGraphicsWidget(QGraphicsWidget *parent = nullptr) : QGraphicsWidget(parent)
|
||||
{ }
|
||||
|
||||
bool event(QEvent *e) override
|
||||
{
|
||||
++(m_eventCount[int(e->type())]);
|
||||
return QGraphicsWidget::event(e);
|
||||
}
|
||||
|
||||
int eventCount(QEvent::Type type) {
|
||||
return m_eventCount.value(int(type));
|
||||
}
|
||||
|
||||
void clearEventCount() {
|
||||
m_eventCount.clear();
|
||||
}
|
||||
|
||||
void clearCounters() {
|
||||
m_eventCount.clear();
|
||||
functionCount.clear();
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
QGraphicsWidget::setGeometry(rect);
|
||||
++(functionCount[SetGeometry]);
|
||||
}
|
||||
|
||||
void callUpdateGeometry()
|
||||
{
|
||||
// updateGeometry() is protected
|
||||
QGraphicsWidget::updateGeometry();
|
||||
}
|
||||
QMap<FunctionType, int> functionCount;
|
||||
private:
|
||||
QMap<int, int> m_eventCount;
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::compressLayoutRequest()
|
||||
{
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
TestGraphicsWidget *tw = new TestGraphicsWidget();
|
||||
scene.addItem(tw);
|
||||
view.show();
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||
QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
QGraphicsWidget *gw = new QGraphicsWidget(tw);
|
||||
gw->setPreferredSize(QSizeF(50, 50));
|
||||
lout->addItem(gw);
|
||||
}
|
||||
QApplication::processEvents();
|
||||
QCOMPARE(tw->eventCount(QEvent::LayoutRequest), 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayout::automaticReparenting()
|
||||
{
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
{
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l = new QGraphicsLinearLayout(w);
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget;
|
||||
l->addItem(w1);
|
||||
scene.addItem(w);
|
||||
QCOMPARE(w1->parentWidget(), w);
|
||||
delete w;
|
||||
}
|
||||
{
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l = new QGraphicsLinearLayout(w);
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget;
|
||||
l->addItem(w1);
|
||||
scene.addItem(w);
|
||||
QCOMPARE(w1->parentWidget(), w);
|
||||
|
||||
QGraphicsWidget *ww = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l1 = new QGraphicsLinearLayout(ww);
|
||||
#if !defined(Q_OS_MAC) && defined(QT_DEBUG)
|
||||
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
|
||||
" in wrong parent; moved to correct parent");
|
||||
#endif
|
||||
l1->addItem(w1);
|
||||
QCOMPARE(w1->parentWidget(), ww);
|
||||
delete w;
|
||||
}
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
view.show();
|
||||
QGraphicsLinearLayout *l1 = new QGraphicsLinearLayout();
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget();
|
||||
l1->addItem(w1);
|
||||
QGraphicsWidget *w2 = new QGraphicsWidget();
|
||||
l1->addItem(w2);
|
||||
QCOMPARE(w1->parentItem(), nullptr);
|
||||
QCOMPARE(w2->parentItem(), nullptr);
|
||||
scene.addItem(w1);
|
||||
QCOMPARE(w1->parentItem(), nullptr);
|
||||
window->setLayout(l1);
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
|
||||
// Sublayouts
|
||||
QGraphicsLinearLayout *l2 = new QGraphicsLinearLayout();
|
||||
QGraphicsWidget *w3 = new QGraphicsWidget();
|
||||
l2->addItem(w3);
|
||||
QGraphicsWidget *w4 = new QGraphicsWidget();
|
||||
l2->addItem(w4);
|
||||
QGraphicsLinearLayout *l3 = new QGraphicsLinearLayout();
|
||||
l2->addItem(l3);
|
||||
QGraphicsWidget *window2 = new QGraphicsWidget();
|
||||
scene.addItem(window2);
|
||||
window2->setLayout(l2);
|
||||
|
||||
QCOMPARE(w3->parentItem(), static_cast<QGraphicsItem*>(window2));
|
||||
QCOMPARE(w4->parentItem(), static_cast<QGraphicsItem*>(window2));
|
||||
|
||||
// graphics item with another parent
|
||||
QGraphicsLinearLayout *l5 = new QGraphicsLinearLayout();
|
||||
l5->addItem(w1);
|
||||
l5->addItem(w2);
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QGraphicsLinearLayout *l4 = new QGraphicsLinearLayout();
|
||||
l4->addItem(l5);
|
||||
QGraphicsWidget *window3 = new QGraphicsWidget();
|
||||
scene.addItem(window3);
|
||||
window3->setLayout(l4);
|
||||
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window3));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window3));
|
||||
}
|
||||
|
||||
class TestLayout : public QGraphicsLinearLayout
|
||||
{
|
||||
public:
|
||||
TestLayout(QGraphicsLayoutItem *parent = nullptr)
|
||||
: QGraphicsLinearLayout(parent)
|
||||
{
|
||||
setContentsMargins(0,0,0,0);
|
||||
setSpacing(0);
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
++(functionCount[SetGeometry]);
|
||||
QGraphicsLinearLayout::setGeometry(rect);
|
||||
}
|
||||
|
||||
void invalidate() override
|
||||
{
|
||||
++(functionCount[Invalidate]);
|
||||
QGraphicsLinearLayout::invalidate();
|
||||
}
|
||||
|
||||
void clearCounters() {
|
||||
functionCount.clear();
|
||||
}
|
||||
|
||||
QMap<FunctionType, int> functionCount;
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::verifyActivate()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
TestLayout *lout = new TestLayout(window);
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
lout->addItem(w);
|
||||
window->setLayout(lout);
|
||||
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 0);
|
||||
window->setVisible(false);
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 0);
|
||||
window->setVisible(true);
|
||||
// on polish or the first time a widget is shown, the widget is resized.
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::sizeHintOfHiddenLayout()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
|
||||
scene.addItem(window);
|
||||
TestLayout *lout = new TestLayout(window);
|
||||
lout->setContentsMargins(1,2,2,1);
|
||||
QGraphicsWidget *w = new QGraphicsWidget;
|
||||
w->setPreferredSize(20, 20);
|
||||
w->setMaximumSize(50, 50);
|
||||
lout->addItem(w);
|
||||
window->setLayout(lout);
|
||||
|
||||
for (int pass = 0; pass < 3; ++pass) {
|
||||
QCOMPARE(lout->sizeHint(Qt::MinimumSize), QSizeF(3,3));
|
||||
QCOMPARE(lout->sizeHint(Qt::PreferredSize), QSizeF(23,23));
|
||||
QCOMPARE(lout->sizeHint(Qt::MaximumSize), QSizeF(53,53));
|
||||
window->setVisible(pass % 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void clearAllCounters(TestGraphicsWidget *widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
widget->clearCounters();
|
||||
TestLayout *layout = static_cast<TestLayout *>(widget->layout());
|
||||
if (layout) {
|
||||
layout->clearCounters();
|
||||
for (int i = layout->count() - 1; i >=0; --i) {
|
||||
QGraphicsLayoutItem *item = layout->itemAt(i);
|
||||
if (item->isLayout()) {
|
||||
// ### Not used ATM
|
||||
//TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item));
|
||||
//clearAllCounters(lay);
|
||||
} else {
|
||||
TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item);
|
||||
clearAllCounters(wid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void activateAndReset(TestGraphicsWidget *widget)
|
||||
{
|
||||
QApplication::sendPostedEvents();
|
||||
QApplication::processEvents();
|
||||
if (widget->layout())
|
||||
widget->layout()->activate();
|
||||
clearAllCounters(widget);
|
||||
}
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::invalidate()
|
||||
{
|
||||
QGraphicsLayout::setInstantInvalidatePropagation(true);
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
TestGraphicsWidget *a = new TestGraphicsWidget;
|
||||
a->setData(0, QString("a"));
|
||||
scene.addItem(a);
|
||||
TestLayout *alay = new TestLayout(a);
|
||||
TestGraphicsWidget *b = new TestGraphicsWidget;
|
||||
b->setData(0, QString("b"));
|
||||
alay->addItem(b);
|
||||
TestLayout *blay = new TestLayout(b);
|
||||
TestGraphicsWidget *e = new TestGraphicsWidget;
|
||||
e->setData(0, QString("e"));
|
||||
blay->addItem(e);
|
||||
|
||||
|
||||
TestGraphicsWidget *c = new TestGraphicsWidget;
|
||||
c->setData(0, QString("c"));
|
||||
alay->addItem(c);
|
||||
TestLayout *clay = new TestLayout(c);
|
||||
TestGraphicsWidget *f = new TestGraphicsWidget;
|
||||
f->setData(0, QString("f"));
|
||||
clay->addItem(f);
|
||||
|
||||
TestGraphicsWidget *d = new TestGraphicsWidget;
|
||||
d->setData(0, QString("d"));
|
||||
alay->addItem(d);
|
||||
TestLayout *dlay = new TestLayout(d);
|
||||
TestGraphicsWidget *g = new TestGraphicsWidget;
|
||||
g->setData(0, QString("g"));
|
||||
dlay->addItem(g);
|
||||
|
||||
view.show();
|
||||
|
||||
{
|
||||
clearAllCounters(a);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
alay->activate();
|
||||
QCOMPARE(alay->isActivated(), true);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
}
|
||||
|
||||
{
|
||||
clearAllCounters(a);
|
||||
e->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), false);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
// should only invalidate ascendants of e
|
||||
QCOMPARE(blay->functionCount[Invalidate], 1);
|
||||
QCOMPARE(alay->functionCount[Invalidate], 1);
|
||||
// not siblings
|
||||
QCOMPARE(clay->functionCount[Invalidate], 0);
|
||||
QCOMPARE(dlay->functionCount[Invalidate], 0);
|
||||
|
||||
QApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
activateAndReset(a);
|
||||
f->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// Since nothing really changed, blay and dlay don't need
|
||||
// to be resized.
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 0);
|
||||
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(a->size(), QSizeF(150, 50));
|
||||
}
|
||||
|
||||
{
|
||||
activateAndReset(a);
|
||||
f->setPreferredSize(QSizeF(60,50));
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
QVERIFY(e->size().width() < f->size().width());
|
||||
QVERIFY(g->size().width() < f->size().width());
|
||||
}
|
||||
|
||||
{
|
||||
// resize f so much that it'll force a resize of the top widget
|
||||
// this will currently generate two setGeometry() calls on the child layout
|
||||
// of the top widget.
|
||||
activateAndReset(a);
|
||||
f->setPreferredSize(QSizeF());
|
||||
f->setMinimumSize(QSizeF(200,50));
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
|
||||
/* well, ideally one call to setGeometry(), but it will currently
|
||||
* get two calls to setGeometry():
|
||||
* 1. The first LayoutRequest will call activate() - that will call
|
||||
* setGeometry() on the layout. This geometry will be based on
|
||||
* the widget geometry which is not correct at this moment.
|
||||
* (it is still 150 wide)
|
||||
* 2. Next, we check if the widget is top level, and then we call
|
||||
* parentWidget->resize(parentWidget->size());
|
||||
* This will be adjusted to be minimum 200 pixels wide.
|
||||
* The new size will then be propagated down to the layout
|
||||
*
|
||||
*/
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 2);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 2);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 2);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 2);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
QVERIFY(e->size().width() < f->size().width());
|
||||
QVERIFY(g->size().width() < f->size().width());
|
||||
}
|
||||
|
||||
{
|
||||
f->setPreferredSize(QSizeF());
|
||||
f->setMinimumSize(QSizeF());
|
||||
a->adjustSize();
|
||||
activateAndReset(a);
|
||||
// update two different leaf widgets,
|
||||
// eventCount and functionCount should never be >= 2
|
||||
e->callUpdateGeometry();
|
||||
g->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), false);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), false);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
}
|
||||
|
||||
QGraphicsLayout::setInstantInvalidatePropagation(false);
|
||||
}
|
||||
|
||||
class Layout : public QGraphicsLayout
|
||||
{
|
||||
public:
|
||||
Layout(QGraphicsLayoutItem *parentItem = 0) : QGraphicsLayout(parentItem) {}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
QGraphicsLayout::setGeometry(rect);
|
||||
}
|
||||
|
||||
int count() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QGraphicsLayoutItem *itemAt(int index) const override
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void removeAt(int index) override
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override
|
||||
{
|
||||
Q_UNUSED(constraint);
|
||||
Q_UNUSED(which);
|
||||
return QSizeF(100,100);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::constructors()
|
||||
{
|
||||
// Strange test, but see the fix that was with this submit
|
||||
QList<Layout *> layouts;
|
||||
for (int pass = 0; pass < 5; ++pass) {
|
||||
Layout *lay = new Layout();
|
||||
layouts << lay;
|
||||
qreal left, top, right, bottom;
|
||||
lay->getContentsMargins(&left, &top, &right, &bottom);
|
||||
// Test if the style defaults are sane (should always be ints)
|
||||
double intpart;
|
||||
QVERIFY(modf(left, &intpart) == 0.0);
|
||||
QVERIFY(modf(top, &intpart) == 0.0);
|
||||
QVERIFY(modf(right, &intpart) == 0.0);
|
||||
QVERIFY(modf(bottom, &intpart) == 0.0);
|
||||
|
||||
lay->setContentsMargins(1, 2, 4, 8);
|
||||
lay->getContentsMargins(&left, &top, &right, &bottom);
|
||||
|
||||
QCOMPARE(int(left), 1);
|
||||
QCOMPARE(int(top), 2);
|
||||
QCOMPARE(int(right), 4);
|
||||
QCOMPARE(int(bottom), 8);
|
||||
}
|
||||
|
||||
qDeleteAll(layouts);
|
||||
}
|
||||
|
||||
class AnimatedLayoutItem : public QGraphicsLayoutItem {
|
||||
public:
|
||||
AnimatedLayoutItem(QGraphicsRectItem *item)
|
||||
: QGraphicsLayoutItem()
|
||||
{
|
||||
setGraphicsItem(item);
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &geom) override;
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
inline QGraphicsRectItem *rectItem() {
|
||||
return static_cast<QGraphicsRectItem *>(graphicsItem());
|
||||
}
|
||||
|
||||
QRectF m_geom;
|
||||
private:
|
||||
AnimatedLayoutItem() {}
|
||||
};
|
||||
|
||||
void AnimatedLayoutItem::setGeometry(const QRectF &geom)
|
||||
{
|
||||
QGraphicsLayoutItem::setGeometry(geom);
|
||||
}
|
||||
|
||||
QSizeF AnimatedLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
class AnimatedLayout : public QObject, public QGraphicsLinearLayout {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AnimatedLayout(QGraphicsWidget *widget) : QGraphicsLinearLayout(widget), m_timeline(500, this)
|
||||
{
|
||||
connect(&m_timeline, SIGNAL(valueChanged(qreal)), this, SLOT(valueChanged(qreal)));
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &geom) override
|
||||
{
|
||||
fromGeoms.clear();
|
||||
toGeoms.clear();
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
fromGeoms << itemAt(i)->geometry();
|
||||
}
|
||||
|
||||
QGraphicsLinearLayout::setGeometry(geom);
|
||||
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
toGeoms << itemAt(i)->geometry();
|
||||
}
|
||||
m_timeline.start();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void valueChanged(qreal value) {
|
||||
for (int i = 0; i < fromGeoms.size(); ++i) {
|
||||
QGraphicsLayoutItem *li = itemAt(i);
|
||||
QRectF from = fromGeoms.at(i);
|
||||
QRectF to = toGeoms.at(i);
|
||||
|
||||
QRectF geom(from.topLeft() + (to.topLeft() - from.topLeft()) * value,
|
||||
from.size() + (to.size() - from.size()) * value);
|
||||
static_cast<QGraphicsRectItem*>(li->graphicsItem())->setRect(geom);
|
||||
}
|
||||
}
|
||||
private:
|
||||
QTimeLine m_timeline;
|
||||
QList<QRectF> fromGeoms;
|
||||
QList<QRectF> toGeoms;
|
||||
};
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::alternativeLayoutItems()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget;
|
||||
scene.addItem(window);
|
||||
AnimatedLayout *lout = new AnimatedLayout(window);
|
||||
lout->setContentsMargins(0, 0, 0, 0);
|
||||
lout->setSpacing(0);
|
||||
|
||||
QGraphicsRectItem *item1 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li1 = new AnimatedLayoutItem(item1);
|
||||
lout->addItem(li1);
|
||||
|
||||
QGraphicsRectItem *item2 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li2 = new AnimatedLayoutItem(item2);
|
||||
lout->addItem(li2);
|
||||
|
||||
QGraphicsRectItem *item3 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li3 = new AnimatedLayoutItem(item3);
|
||||
lout->addItem(li3);
|
||||
|
||||
window->setLayout(lout);
|
||||
|
||||
window->setGeometry(0, 0, 99, 99);
|
||||
view.setSceneRect(QRectF(-10, -10, 110, 110));
|
||||
view.resize(150, 150);
|
||||
view.show();
|
||||
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF( 0, 0, 33, 99));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(33, 0, 33, 99));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(66, 0, 33, 99));
|
||||
|
||||
lout->setOrientation(Qt::Vertical);
|
||||
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF(0, 0, 99, 33));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(0, 33, 99, 33));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(0, 66, 99, 33));
|
||||
|
||||
}
|
||||
|
||||
class CustomLayoutItem : public QGraphicsLayoutItem {
|
||||
public:
|
||||
CustomLayoutItem(QSet<QGraphicsLayoutItem*> *destructedSet)
|
||||
: QGraphicsLayoutItem()
|
||||
{
|
||||
m_destructedSet = destructedSet;
|
||||
setOwnedByLayout(true);
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
~CustomLayoutItem() {
|
||||
m_destructedSet->insert(this);
|
||||
}
|
||||
private:
|
||||
QSet<QGraphicsLayoutItem*> *m_destructedSet;
|
||||
};
|
||||
|
||||
QSizeF CustomLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomGraphicsWidget : public QGraphicsWidget {
|
||||
public:
|
||||
CustomGraphicsWidget(QSet<QGraphicsLayoutItem*> *destructedSet = 0)
|
||||
: QGraphicsWidget()
|
||||
{
|
||||
m_destructedSet = destructedSet;
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * = 0) override
|
||||
{
|
||||
const QRect r = option->rect.adjusted(0, 0, -1, -1);
|
||||
painter->drawLine(r.topLeft(), r.bottomRight());
|
||||
painter->drawLine(r.bottomLeft(), r.topRight());
|
||||
painter->drawRect(r);
|
||||
}
|
||||
|
||||
~CustomGraphicsWidget() {
|
||||
if (m_destructedSet)
|
||||
m_destructedSet->insert(this);
|
||||
}
|
||||
private:
|
||||
QSet<QGraphicsLayoutItem*> *m_destructedSet;
|
||||
};
|
||||
|
||||
QSizeF CustomGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
static bool compareSets(const QSet<QGraphicsLayoutItem*> &actual, const QSet<QGraphicsLayoutItem*> &expected)
|
||||
{
|
||||
if (actual != expected) {
|
||||
qDebug() << "actual:" << actual << "expected:" << expected;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class CustomLayout : public QGraphicsLayout
|
||||
{
|
||||
public :
|
||||
CustomLayout(QGraphicsLayoutItem *parent)
|
||||
: QGraphicsLayout(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
~CustomLayout()
|
||||
{
|
||||
}
|
||||
|
||||
int count() const override
|
||||
{
|
||||
return items.size();
|
||||
}
|
||||
|
||||
QGraphicsLayoutItem* itemAt(int index) const override
|
||||
{
|
||||
return items.at(index);
|
||||
}
|
||||
|
||||
|
||||
void removeAt(int index) override
|
||||
{
|
||||
items.removeAt(index);
|
||||
}
|
||||
|
||||
void addItem(QGraphicsLayoutItem *item)
|
||||
{
|
||||
insertItem(items.size(), item);
|
||||
}
|
||||
|
||||
void insertItem(int index, QGraphicsLayoutItem *item)
|
||||
{
|
||||
index = qBound(0, index, items.size());
|
||||
|
||||
item->setParentLayoutItem(this);
|
||||
|
||||
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
|
||||
updateParentWidget(widget);
|
||||
|
||||
|
||||
if (index == items.size()) {
|
||||
items.append(item);
|
||||
} else {
|
||||
items.insert(index, item);
|
||||
}
|
||||
|
||||
updateGeometry();
|
||||
activate();
|
||||
}
|
||||
|
||||
void updateParentWidget(QGraphicsWidget *item)
|
||||
{
|
||||
QGraphicsLayoutItem *parentItem = parentLayoutItem();
|
||||
while (parentItem && parentItem->isLayout()) {
|
||||
parentItem = parentItem->parentLayoutItem();
|
||||
}
|
||||
|
||||
if (parentItem) {
|
||||
item->setParentItem(static_cast<QGraphicsWidget*>(parentItem));
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint /* which */, const QSizeF & /* constraint */) const override
|
||||
{
|
||||
return QSizeF(50,50);
|
||||
}
|
||||
|
||||
QList<QGraphicsLayoutItem*> items;
|
||||
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::ownership()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
{
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
QSet<QGraphicsLayoutItem*> destructedSet;
|
||||
CustomLayoutItem *li1 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li1);
|
||||
CustomLayoutItem *li2 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li2);
|
||||
CustomLayoutItem *li3 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li3);
|
||||
destructedSet.clear();
|
||||
|
||||
delete lay;
|
||||
QSet<QGraphicsLayoutItem*> expected;
|
||||
expected << li1 << li2 << li3;
|
||||
QVERIFY(compareSets(destructedSet, expected));
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *window = new QGraphicsWidget;
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
QSet<QGraphicsLayoutItem*> destructedSet;
|
||||
CustomGraphicsWidget *li1 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li1);
|
||||
CustomGraphicsWidget *li2 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li2);
|
||||
CustomGraphicsWidget *li3 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li3);
|
||||
window->setLayout(lay);
|
||||
scene.addItem(window);
|
||||
|
||||
destructedSet.clear();
|
||||
window->setLayout(0);
|
||||
QCOMPARE(destructedSet.size(), 0);
|
||||
delete window;
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
|
||||
CustomGraphicsWidget *li1 = new CustomGraphicsWidget;
|
||||
lay->addItem(li1);
|
||||
|
||||
QGraphicsLinearLayout *li2 = new QGraphicsLinearLayout;
|
||||
CustomGraphicsWidget *li2_1 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_1);
|
||||
CustomGraphicsWidget *li2_2 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_2);
|
||||
CustomGraphicsWidget *li2_3 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_3);
|
||||
lay->addItem(li2);
|
||||
|
||||
CustomGraphicsWidget *li3 = new CustomGraphicsWidget;
|
||||
lay->addItem(li3);
|
||||
|
||||
window->setLayout(lay);
|
||||
scene.addItem(window);
|
||||
view.resize(500, 200);
|
||||
view.show();
|
||||
|
||||
for (int i = li2->count(); i > 0; --i) {
|
||||
QCOMPARE(li2->count(), i);
|
||||
delete li2->itemAt(0);
|
||||
}
|
||||
|
||||
for (int i = lay->count(); i > 0; --i) {
|
||||
QCOMPARE(lay->count(), i);
|
||||
delete lay->itemAt(0);
|
||||
}
|
||||
|
||||
delete window;
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *top = new QGraphicsWidget;
|
||||
QGraphicsWidget *w = new QGraphicsWidget;
|
||||
QGraphicsWidget *w2 = new QGraphicsWidget;
|
||||
CustomLayout *layout = new CustomLayout(top);
|
||||
layout->addItem(w);
|
||||
layout->addItem(w2);
|
||||
top->setLayout(layout);
|
||||
delete top;
|
||||
//don't crash after that.
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsLayout)
|
||||
#include "tst_qgraphicslayout.moc"
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicslayoutitem Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicslayoutitem
|
||||
SOURCES
|
||||
tst_qgraphicslayoutitem.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,307 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qgraphicslayoutitem.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
|
||||
class tst_QGraphicsLayoutItem : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void qgraphicslayoutitem();
|
||||
|
||||
void contentsRect();
|
||||
void effectiveSizeHint_data();
|
||||
void effectiveSizeHint();
|
||||
void getContentsMargins();
|
||||
void isLayout_data();
|
||||
void isLayout();
|
||||
void maximumSize();
|
||||
void minimumSize();
|
||||
void parentLayoutItem_data();
|
||||
void parentLayoutItem();
|
||||
void preferredSize();
|
||||
void setMaximumSize_data();
|
||||
void setMaximumSize();
|
||||
void setMinimumSize_data();
|
||||
void setMinimumSize();
|
||||
void setPreferredSize_data();
|
||||
void setPreferredSize();
|
||||
void setSizePolicy_data();
|
||||
void setPreferredSize2();
|
||||
void setSizePolicy();
|
||||
};
|
||||
|
||||
// Subclass that exposes the protected functions.
|
||||
class SubQGraphicsLayoutItem : public QGraphicsLayoutItem {
|
||||
public:
|
||||
SubQGraphicsLayoutItem(QGraphicsLayoutItem *par = 0, bool layout = false)
|
||||
: QGraphicsLayoutItem(par, layout), updateGeometryCalled(0)
|
||||
{}
|
||||
|
||||
// QGraphicsLayoutItem::geometry is a pure virtual function
|
||||
QRectF geometry() const
|
||||
{ return QRectF(); }
|
||||
|
||||
// QGraphicsLayoutItem::setGeometry is a pure virtual function
|
||||
void setGeometry(QRectF const&) override {}
|
||||
|
||||
// QGraphicsLayoutItem::sizeHint is a pure virtual function
|
||||
QSizeF sizeHint(Qt::SizeHint, QSizeF const& = QSizeF()) const override
|
||||
{ return QSizeF(); }
|
||||
|
||||
void updateGeometry() override
|
||||
{ updateGeometryCalled++; QGraphicsLayoutItem::updateGeometry(); }
|
||||
int updateGeometryCalled;
|
||||
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayoutItem::qgraphicslayoutitem()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
layoutItem.contentsRect();
|
||||
layoutItem.effectiveSizeHint(Qt::MinimumSize);
|
||||
layoutItem.geometry();
|
||||
QCOMPARE(layoutItem.isLayout(), false);
|
||||
layoutItem.maximumSize();
|
||||
layoutItem.minimumSize();
|
||||
QCOMPARE(layoutItem.parentLayoutItem(), nullptr);
|
||||
layoutItem.preferredSize();
|
||||
layoutItem.sizePolicy();
|
||||
layoutItem.sizeHint(Qt::MinimumSize);
|
||||
}
|
||||
|
||||
// QRectF contentsRect() const public
|
||||
void tst_QGraphicsLayoutItem::contentsRect()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QRectF f = layoutItem.contentsRect();
|
||||
QCOMPARE(f, QRectF(QPoint(), QSizeF(0, 0)));
|
||||
}
|
||||
Q_DECLARE_METATYPE(Qt::SizeHint)
|
||||
void tst_QGraphicsLayoutItem::effectiveSizeHint_data()
|
||||
{
|
||||
QTest::addColumn<Qt::SizeHint>("sizeHint");
|
||||
QTest::addColumn<QSizeF>("constraint");
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
QTestData &data = QTest::newRow(QByteArray::number(i).constData());
|
||||
switch(i % 5) {
|
||||
case 0: data << Qt::MinimumSize; break;
|
||||
case 1: data << Qt::PreferredSize; break;
|
||||
case 2: data << Qt::MaximumSize; break;
|
||||
case 3: data << Qt::MinimumDescent; break;
|
||||
case 4: data << Qt::NSizeHints; break;
|
||||
}
|
||||
switch(i % 3) {
|
||||
case 0: data << QSizeF(-1, -1); break;
|
||||
case 1: data << QSizeF(0, 0); break;
|
||||
case 2: data << QSizeF(10, 10); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// QSizeF effectiveSizeHint(Qt::SizeHint which, QSizeF const& constraint = QSize()) const public
|
||||
void tst_QGraphicsLayoutItem::effectiveSizeHint()
|
||||
{
|
||||
QFETCH(Qt::SizeHint, sizeHint);
|
||||
QFETCH(QSizeF, constraint);
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QSizeF r = layoutItem.effectiveSizeHint(sizeHint, constraint);
|
||||
if (constraint.width() != -1)
|
||||
QCOMPARE(r.width(), constraint.width());
|
||||
if (constraint.height() != -1)
|
||||
QCOMPARE(r.height(), constraint.height());
|
||||
}
|
||||
|
||||
// void getContentsMargins(qreal* left, qreal* top, qreal* right, qreal* bottom) const public
|
||||
void tst_QGraphicsLayoutItem::getContentsMargins()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
qreal left;
|
||||
qreal top;
|
||||
qreal right;
|
||||
qreal bottom;
|
||||
layoutItem.getContentsMargins(&left, &top, &right, &bottom);
|
||||
QCOMPARE(left, (qreal)0);
|
||||
QCOMPARE(top, (qreal)0);
|
||||
QCOMPARE(right, (qreal)0);
|
||||
QCOMPARE(bottom, (qreal)0);
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::isLayout_data()
|
||||
{
|
||||
QTest::addColumn<bool>("isLayout");
|
||||
QTest::newRow("no") << false;
|
||||
QTest::newRow("yes") << true;
|
||||
}
|
||||
|
||||
// bool isLayout() const public
|
||||
void tst_QGraphicsLayoutItem::isLayout()
|
||||
{
|
||||
QFETCH(bool, isLayout);
|
||||
SubQGraphicsLayoutItem layoutItem(0, isLayout);
|
||||
QCOMPARE(layoutItem.isLayout(), isLayout);
|
||||
}
|
||||
|
||||
// QSizeF maximumSize() const public
|
||||
void tst_QGraphicsLayoutItem::maximumSize()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QCOMPARE(layoutItem.maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
||||
// layoutItem.effectiveSizeHint(Qt::MaximumSize);
|
||||
}
|
||||
|
||||
// QSizeF minimumSize() const public
|
||||
void tst_QGraphicsLayoutItem::minimumSize()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QCOMPARE(layoutItem.minimumSize(), QSizeF(0, 0));
|
||||
// layoutItem.effectiveSizeHint(Qt::MinimumSize);
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::parentLayoutItem_data()
|
||||
{
|
||||
QTest::addColumn<bool>("parent");
|
||||
QTest::newRow("no") << false;
|
||||
QTest::newRow("yes") << true;
|
||||
}
|
||||
|
||||
// QGraphicsLayoutItem* parentLayoutItem() const public
|
||||
void tst_QGraphicsLayoutItem::parentLayoutItem()
|
||||
{
|
||||
QFETCH(bool, parent);
|
||||
SubQGraphicsLayoutItem parentLayout;
|
||||
SubQGraphicsLayoutItem layoutItem(parent ? &parentLayout : 0);
|
||||
QCOMPARE(layoutItem.parentLayoutItem(), static_cast<QGraphicsLayoutItem*>( parent ? &parentLayout : 0));
|
||||
}
|
||||
|
||||
// QSizeF preferredSize() const public
|
||||
void tst_QGraphicsLayoutItem::preferredSize()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QCOMPARE(layoutItem.preferredSize(), QSizeF(0, 0));
|
||||
// layoutItem.effectiveSizeHint(Qt::PreferredSize));
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::setMaximumSize_data()
|
||||
{
|
||||
QTest::addColumn<QSizeF>("size");
|
||||
QTest::addColumn<QSizeF>("outputSize");
|
||||
QTest::newRow("-1") << QSizeF(-1, -1) << QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
QTest::newRow("0") << QSizeF(0, 0) << QSizeF(0, 0);
|
||||
QTest::newRow("10") << QSizeF(10, 10) << QSizeF(10, 10);
|
||||
}
|
||||
|
||||
// void setMaximumSize(QSizeF const& size) public
|
||||
void tst_QGraphicsLayoutItem::setMaximumSize()
|
||||
{
|
||||
QFETCH(QSizeF, size);
|
||||
QFETCH(QSizeF, outputSize);
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QSizeF oldSize = layoutItem.maximumSize();
|
||||
layoutItem.setMaximumSize(size);
|
||||
if (size.isValid())
|
||||
QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
|
||||
else
|
||||
QVERIFY(!layoutItem.updateGeometryCalled);
|
||||
layoutItem.setMinimumSize(1, 1);
|
||||
|
||||
QVERIFY(layoutItem.maximumSize().width() <= outputSize.width());
|
||||
QVERIFY(layoutItem.maximumSize().height() <= outputSize.height());
|
||||
QVERIFY(layoutItem.minimumSize().width() <= outputSize.width());
|
||||
QVERIFY(layoutItem.minimumSize().height() <= outputSize.height());
|
||||
QVERIFY(layoutItem.preferredSize().width() <= outputSize.width());
|
||||
QVERIFY(layoutItem.preferredSize().height() <= outputSize.height());
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::setMinimumSize_data()
|
||||
{
|
||||
QTest::addColumn<QSizeF>("size");
|
||||
QTest::newRow("-1") << QSizeF(-1, -1);
|
||||
QTest::newRow("0") << QSizeF(0, 0);
|
||||
QTest::newRow("10") << QSizeF(10, 10);
|
||||
}
|
||||
|
||||
// void setMinimumSize(QSizeF const& size) public
|
||||
void tst_QGraphicsLayoutItem::setMinimumSize()
|
||||
{
|
||||
QFETCH(QSizeF, size);
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QSizeF oldSize = layoutItem.minimumSize();
|
||||
|
||||
layoutItem.setMinimumSize(size);
|
||||
if (size.isValid()) {
|
||||
QEXPECT_FAIL("0", "updateGeometry() is called when it doesn't have to be.", Continue);
|
||||
QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
|
||||
} else {
|
||||
QVERIFY(!layoutItem.updateGeometryCalled);
|
||||
}
|
||||
layoutItem.setMaximumSize(5, 5);
|
||||
QEXPECT_FAIL("10", "layoutItem.maximumSize().width() < size.width()", Abort);
|
||||
QVERIFY(layoutItem.maximumSize().width() >= size.width());
|
||||
QVERIFY(layoutItem.maximumSize().height() >= size.height());
|
||||
QVERIFY(layoutItem.minimumSize().width() >= size.width());
|
||||
QVERIFY(layoutItem.minimumSize().height() >= size.height());
|
||||
QVERIFY(layoutItem.preferredSize().width() >= size.width());
|
||||
QVERIFY(layoutItem.preferredSize().height() >= size.height());
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::setPreferredSize_data()
|
||||
{
|
||||
QTest::addColumn<QSizeF>("size");
|
||||
QTest::newRow("-1") << QSizeF(-1, -1);
|
||||
QTest::newRow("0") << QSizeF(0, 0);
|
||||
QTest::newRow("10") << QSizeF(10, 10);
|
||||
}
|
||||
|
||||
// void setPreferredSize(QSizeF const& size) public
|
||||
void tst_QGraphicsLayoutItem::setPreferredSize()
|
||||
{
|
||||
QFETCH(QSizeF, size);
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QSizeF oldSize = layoutItem.preferredSize();
|
||||
layoutItem.setPreferredSize(size);
|
||||
if (size.isValid())
|
||||
QCOMPARE(layoutItem.preferredSize(), size);
|
||||
|
||||
if (size.isValid()) {
|
||||
QEXPECT_FAIL("0", "updateGeometry() is called when it doesn't have to be.", Continue);
|
||||
QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
|
||||
} else {
|
||||
QVERIFY(!layoutItem.updateGeometryCalled);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::setPreferredSize2()
|
||||
{
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
layoutItem.setPreferredSize(QSizeF(30, -1));
|
||||
QCOMPARE(layoutItem.preferredWidth(), qreal(30));
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayoutItem::setSizePolicy_data()
|
||||
{
|
||||
QTest::addColumn<QSizePolicy>("policy");
|
||||
QTest::newRow("default") << QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, QSizePolicy::DefaultType);
|
||||
QTest::newRow("rand") << QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||
}
|
||||
|
||||
// void setSizePolicy(QSizePolicy const& policy) public
|
||||
void tst_QGraphicsLayoutItem::setSizePolicy()
|
||||
{
|
||||
QFETCH(QSizePolicy, policy);
|
||||
SubQGraphicsLayoutItem layoutItem;
|
||||
QSizePolicy defaultPolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType);
|
||||
QCOMPARE(layoutItem.sizePolicy(), defaultPolicy);
|
||||
|
||||
layoutItem.setSizePolicy(policy);
|
||||
QCOMPARE(layoutItem.sizePolicy(), policy);
|
||||
QCOMPARE(layoutItem.updateGeometryCalled, (defaultPolicy == policy) ? 0 : 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsLayoutItem)
|
||||
#include "tst_qgraphicslayoutitem.moc"
|
||||
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicslinearlayout Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicslinearlayout
|
||||
SOURCES
|
||||
tst_qgraphicslinearlayout.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsobject Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsobject
|
||||
SOURCES
|
||||
tst_qgraphicsobject.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,231 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qgraphicsscene.h>
|
||||
#include <qgraphicssceneevent.h>
|
||||
#include <qgraphicsview.h>
|
||||
#include <qstyleoption.h>
|
||||
#include <private/qobject_p.h>
|
||||
|
||||
class tst_QGraphicsObject : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void pos();
|
||||
void x();
|
||||
void y();
|
||||
void z();
|
||||
void opacity();
|
||||
void enabled();
|
||||
void visible();
|
||||
void deleted();
|
||||
};
|
||||
|
||||
class MyGraphicsObject : public QGraphicsObject
|
||||
{
|
||||
public:
|
||||
MyGraphicsObject() : QGraphicsObject() {}
|
||||
virtual QRectF boundingRect() const override { return QRectF(); }
|
||||
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override {}
|
||||
};
|
||||
|
||||
void tst_QGraphicsObject::pos()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy xSpy(&object, SIGNAL(xChanged()));
|
||||
QSignalSpy ySpy(&object, SIGNAL(yChanged()));
|
||||
QVERIFY(object.pos() == QPointF(0, 0));
|
||||
object.setPos(10, 10);
|
||||
QCOMPARE(xSpy.size(), 1);
|
||||
QCOMPARE(ySpy.size(), 1);
|
||||
|
||||
QCOMPARE(object.pos(), QPointF(10,10));
|
||||
|
||||
object.setPos(10, 10);
|
||||
QCOMPARE(xSpy.size(), 1);
|
||||
QCOMPARE(ySpy.size(), 1);
|
||||
|
||||
object.setProperty("pos", QPointF(0, 0));
|
||||
QCOMPARE(xSpy.size(), 2);
|
||||
QCOMPARE(ySpy.size(), 2);
|
||||
QCOMPARE(object.property("pos").toPointF(), QPointF(0,0));
|
||||
|
||||
object.setProperty("pos", QPointF(10, 0));
|
||||
QCOMPARE(xSpy.size(), 3);
|
||||
QCOMPARE(ySpy.size(), 2);
|
||||
QCOMPARE(object.property("pos").toPointF(), QPointF(10,0));
|
||||
|
||||
object.setProperty("pos", QPointF(10, 10));
|
||||
QCOMPARE(xSpy.size(), 3);
|
||||
QCOMPARE(ySpy.size(), 3);
|
||||
QVERIFY(object.property("pos") == QPointF(10, 10));
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::x()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy xSpy(&object, SIGNAL(xChanged()));
|
||||
QSignalSpy ySpy(&object, SIGNAL(yChanged()));
|
||||
QVERIFY(object.pos() == QPointF(0, 0));
|
||||
object.setX(10);
|
||||
QCOMPARE(xSpy.size(), 1);
|
||||
QCOMPARE(ySpy.size(), 0);
|
||||
|
||||
QVERIFY(object.pos() == QPointF(10, 0));
|
||||
QCOMPARE(object.x(), qreal(10));
|
||||
|
||||
object.setX(10);
|
||||
QCOMPARE(xSpy.size(), 1);
|
||||
QCOMPARE(ySpy.size(), 0);
|
||||
|
||||
object.setProperty("x", 0);
|
||||
QCOMPARE(xSpy.size(), 2);
|
||||
QCOMPARE(ySpy.size(), 0);
|
||||
QCOMPARE(object.property("x").toDouble(), double(0));
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::y()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy xSpy(&object, SIGNAL(xChanged()));
|
||||
QSignalSpy ySpy(&object, SIGNAL(yChanged()));
|
||||
QVERIFY(object.pos() == QPointF(0, 0));
|
||||
object.setY(10);
|
||||
QCOMPARE(xSpy.size(), 0);
|
||||
QCOMPARE(ySpy.size(), 1);
|
||||
|
||||
QVERIFY(object.pos() == QPointF(0, 10));
|
||||
QCOMPARE(object.y(), qreal(10));
|
||||
|
||||
object.setY(10);
|
||||
QCOMPARE(xSpy.size(), 0);
|
||||
QCOMPARE(ySpy.size(), 1);
|
||||
|
||||
object.setProperty("y", 0);
|
||||
QCOMPARE(xSpy.size(), 0);
|
||||
QCOMPARE(ySpy.size(), 2);
|
||||
QCOMPARE(object.property("y").toDouble(), qreal(0));
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::z()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy zSpy(&object, SIGNAL(zChanged()));
|
||||
QCOMPARE(object.zValue(), qreal(0));
|
||||
object.setZValue(10);
|
||||
QCOMPARE(zSpy.size(), 1);
|
||||
|
||||
QCOMPARE(object.zValue(), qreal(10));
|
||||
|
||||
object.setZValue(10);
|
||||
QCOMPARE(zSpy.size(), 1);
|
||||
|
||||
object.setProperty("z", 0);
|
||||
QCOMPARE(zSpy.size(), 2);
|
||||
QCOMPARE(object.property("z").toDouble(), double(0));
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::opacity()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy spy(&object, SIGNAL(opacityChanged()));
|
||||
QCOMPARE(object.opacity(), 1.);
|
||||
object.setOpacity(0);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
QCOMPARE(object.opacity(), 0.);
|
||||
|
||||
object.setOpacity(0);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
object.setProperty("opacity", .5);
|
||||
QCOMPARE(spy.size(), 2);
|
||||
QCOMPARE(object.property("opacity").toDouble(), .5);
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::enabled()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy spy(&object, SIGNAL(enabledChanged()));
|
||||
QVERIFY(object.isEnabled());
|
||||
object.setEnabled(false);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
QVERIFY(!object.isEnabled());
|
||||
|
||||
object.setEnabled(false);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
object.setProperty("enabled", true);
|
||||
QCOMPARE(spy.size(), 2);
|
||||
QVERIFY(object.property("enabled").toBool());
|
||||
}
|
||||
|
||||
void tst_QGraphicsObject::visible()
|
||||
{
|
||||
MyGraphicsObject object;
|
||||
QSignalSpy spy(&object, SIGNAL(visibleChanged()));
|
||||
QVERIFY(object.isVisible());
|
||||
object.setVisible(false);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
QVERIFY(!object.isVisible());
|
||||
|
||||
object.setVisible(false);
|
||||
QCOMPARE(spy.size(), 1);
|
||||
|
||||
object.setProperty("visible", true);
|
||||
QCOMPARE(spy.size(), 2);
|
||||
QVERIFY(object.property("visible").toBool());
|
||||
}
|
||||
|
||||
class DeleteTester : public QGraphicsObject
|
||||
{
|
||||
public:
|
||||
DeleteTester(bool *w, bool *pw, QGraphicsItem *parent = nullptr)
|
||||
: QGraphicsObject(parent), wasDeleted(w), parentWasDeleted(pw)
|
||||
{ }
|
||||
|
||||
~DeleteTester()
|
||||
{
|
||||
*wasDeleted = QObjectPrivate::get(this)->wasDeleted;
|
||||
if (QGraphicsItem *p = parentItem()) {
|
||||
if (QGraphicsObject *o = p->toGraphicsObject())
|
||||
*parentWasDeleted = QObjectPrivate::get(o)->wasDeleted;
|
||||
}
|
||||
}
|
||||
|
||||
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = nullptr) override
|
||||
{ }
|
||||
QRectF boundingRect() const override
|
||||
{ return QRectF(); }
|
||||
|
||||
bool *wasDeleted;
|
||||
bool *parentWasDeleted;
|
||||
};
|
||||
|
||||
void tst_QGraphicsObject::deleted()
|
||||
{
|
||||
bool item1_parentWasDeleted = false;
|
||||
bool item1_wasDeleted = false;
|
||||
bool item2_parentWasDeleted = false;
|
||||
bool item2_wasDeleted = false;
|
||||
DeleteTester *item1 = new DeleteTester(&item1_wasDeleted, &item1_parentWasDeleted);
|
||||
DeleteTester *item2 = new DeleteTester(&item2_wasDeleted, &item2_parentWasDeleted, item1);
|
||||
Q_UNUSED(item2);
|
||||
delete item1;
|
||||
|
||||
QVERIFY(!item1_wasDeleted); // destructor not called yet
|
||||
QVERIFY(!item1_parentWasDeleted); // no parent
|
||||
QVERIFY(!item2_wasDeleted); // destructor not called yet
|
||||
QVERIFY(item2_parentWasDeleted);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsObject)
|
||||
#include "tst_qgraphicsobject.moc"
|
||||
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicspixmapitem Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicspixmapitem
|
||||
SOURCES
|
||||
tst_qgraphicspixmapitem.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,372 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qgraphicsscene.h>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qpainterpath.h>
|
||||
|
||||
class tst_QGraphicsPixmapItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void qgraphicspixmapitem_data();
|
||||
void qgraphicspixmapitem();
|
||||
void boundingRect_data();
|
||||
void boundingRect();
|
||||
void contains_data();
|
||||
void contains();
|
||||
void isObscuredBy_data();
|
||||
void isObscuredBy();
|
||||
void offset_data();
|
||||
void offset();
|
||||
void opaqueArea_data();
|
||||
void opaqueArea();
|
||||
void pixmap_data();
|
||||
void pixmap();
|
||||
void setPixmap_data();
|
||||
void setPixmap();
|
||||
void setShapeMode_data();
|
||||
void setShapeMode();
|
||||
void setTransformationMode_data();
|
||||
void setTransformationMode();
|
||||
void shape_data();
|
||||
void shape();
|
||||
void extension_data();
|
||||
void extension();
|
||||
void setExtension_data();
|
||||
void setExtension();
|
||||
void supportsExtension_data();
|
||||
void supportsExtension();
|
||||
};
|
||||
|
||||
// Subclass that exposes the protected functions.
|
||||
class SubQGraphicsPixmapItem : public QGraphicsPixmapItem
|
||||
{
|
||||
public:
|
||||
enum Extension {
|
||||
UserExtension = QGraphicsItem::UserExtension
|
||||
};
|
||||
SubQGraphicsPixmapItem(QGraphicsItem *parent = nullptr) : QGraphicsPixmapItem(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SubQGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = nullptr) : QGraphicsPixmapItem(pixmap, parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant call_extension(QVariant const& variant) const
|
||||
{ return SubQGraphicsPixmapItem::extension(variant); }
|
||||
|
||||
void call_setExtension(Extension extension, QVariant const& variant)
|
||||
{ return SubQGraphicsPixmapItem::setExtension((QGraphicsItem::Extension)extension, variant); }
|
||||
|
||||
bool call_supportsExtension(Extension extension) const
|
||||
{ return SubQGraphicsPixmapItem::supportsExtension((QGraphicsItem::Extension)extension); }
|
||||
};
|
||||
|
||||
void tst_QGraphicsPixmapItem::qgraphicspixmapitem_data()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::qgraphicspixmapitem()
|
||||
{
|
||||
SubQGraphicsPixmapItem item;
|
||||
item.boundingRect();
|
||||
item.contains(QPoint());
|
||||
item.isObscuredBy(0);
|
||||
item.opaqueArea();
|
||||
//item.paint();
|
||||
QCOMPARE(item.offset(), QPointF());
|
||||
QCOMPARE(item.pixmap(), QPixmap());
|
||||
QCOMPARE(item.shapeMode(), QGraphicsPixmapItem::MaskShape);
|
||||
QCOMPARE(item.transformationMode(), Qt::FastTransformation);
|
||||
item.setOffset(0, 0);
|
||||
item.setOffset(QPointF(0, 0));
|
||||
item.setPixmap(QPixmap());
|
||||
item.setShapeMode(QGraphicsPixmapItem::MaskShape);
|
||||
item.setTransformationMode(Qt::FastTransformation);
|
||||
item.shape();
|
||||
item.type();
|
||||
item.call_extension(QVariant());
|
||||
item.call_setExtension(SubQGraphicsPixmapItem::UserExtension, QVariant());
|
||||
item.call_supportsExtension(SubQGraphicsPixmapItem::UserExtension);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::boundingRect_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QRectF>("boundingRect");
|
||||
QTest::newRow("null") << QPixmap() << QRectF();
|
||||
QTest::newRow("10x10") << QPixmap(10, 10) << QRectF(0, 0, 10, 10);
|
||||
}
|
||||
|
||||
// public QRectF boundingRect() const
|
||||
void tst_QGraphicsPixmapItem::boundingRect()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QRectF, boundingRect);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
QCOMPARE(item.boundingRect(), boundingRect);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::contains_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QPointF>("point");
|
||||
QTest::addColumn<bool>("contains");
|
||||
QTest::newRow("null") << QPixmap() << QPointF() << false;
|
||||
QTest::newRow("10x10, 100x100") << QPixmap(10, 10) << QPointF(100, 100) << false;
|
||||
QTest::newRow("10x10, 5x5") << QPixmap(10, 10) << QPointF(5, 5) << true;
|
||||
QTest::newRow("border-1") << QPixmap(10, 10) << QPointF(10.5, 10.5) << false;
|
||||
QTest::newRow("border-2") << QPixmap(10, 10) << QPointF(-0.5, -0.5) << false;
|
||||
}
|
||||
|
||||
// public bool contains(QPointF const& point) const
|
||||
void tst_QGraphicsPixmapItem::contains()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This fails. Figure out why.");
|
||||
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QPointF, point);
|
||||
QFETCH(bool, contains);
|
||||
|
||||
// At the time of writing, by default pixmaps will have:
|
||||
// - The same pixel format of the primary screen (which is platform dependent and may contain alpha)
|
||||
// - Uninitialized pixels, potentially including an alpha channel
|
||||
// - A ShapeMode of Mask (which mean it will use the alpha channel as a mask for contains())
|
||||
// This means that in order to prevent undefined behavior in this test, we either need to set
|
||||
// the shapeMode to something else, or set the pixels of the pixmap.
|
||||
pixmap.fill(); // Filling the pixmap to be on the safe side.
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
QCOMPARE(item.contains(point), contains);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::isObscuredBy_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QPixmap>("otherPixmap");
|
||||
QTest::addColumn<bool>("isObscuredBy");
|
||||
QTest::newRow("null") << QPixmap() << QPixmap() << false;
|
||||
QTest::newRow("(10, 10) vs. (5, 5)") << QPixmap(10, 10) << QPixmap(5, 5) << false;
|
||||
QTest::newRow("(5, 5) vs. (10, 10)") << QPixmap(5, 5) << QPixmap(10, 10) << true;
|
||||
QTest::newRow("(10, 10) vs. (10, 10)") << QPixmap(10, 10) << QPixmap(10, 10) << false;
|
||||
QTest::newRow("(9, 9) vs. (10, 10)") << QPixmap(8, 8) << QPixmap(10, 10) << true;
|
||||
QTest::newRow("(10, 10) vs. (9, 9)") << QPixmap(10, 10) << QPixmap(8, 8) << false;
|
||||
}
|
||||
|
||||
// public bool isObscuredBy(QGraphicsItem const* item) const
|
||||
void tst_QGraphicsPixmapItem::isObscuredBy()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QPixmap, otherPixmap);
|
||||
QFETCH(bool, isObscuredBy);
|
||||
pixmap.fill();
|
||||
otherPixmap.fill();
|
||||
|
||||
SubQGraphicsPixmapItem *item = new SubQGraphicsPixmapItem(pixmap);
|
||||
SubQGraphicsPixmapItem *otherItem = new SubQGraphicsPixmapItem(otherPixmap);
|
||||
|
||||
item->setOffset(-pixmap.width() / 2.0, -pixmap.height() / 2.0);
|
||||
otherItem->setOffset(-otherPixmap.width() / 2.0, -otherPixmap.height() / 2.0);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.addItem(item);
|
||||
scene.addItem(otherItem);
|
||||
otherItem->setZValue(1);
|
||||
|
||||
QCOMPARE(item->isObscuredBy(otherItem), isObscuredBy);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::offset_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QPointF>("offset");
|
||||
QTest::newRow("null") << QPixmap() << QPointF();
|
||||
QTest::newRow("10x10, 1x1") << QPixmap(10, 10) << QPointF(1, 1);
|
||||
}
|
||||
|
||||
// public QPointF offset() const
|
||||
void tst_QGraphicsPixmapItem::offset()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QPointF, offset);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
item.setOffset(offset);
|
||||
QCOMPARE(item.offset(), offset);
|
||||
|
||||
// ### test actual painting and compare pixmap with offseted one?
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QPainterPath)
|
||||
void tst_QGraphicsPixmapItem::opaqueArea_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QPainterPath>("opaqueArea");
|
||||
QTest::newRow("null") << QPixmap() << QPainterPath();
|
||||
// Currently QGraphicsPixmapItem just calls QGraphicsItem test there
|
||||
}
|
||||
|
||||
// public QPainterPath opaqueArea() const
|
||||
void tst_QGraphicsPixmapItem::opaqueArea()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QPainterPath, opaqueArea);
|
||||
|
||||
SubQGraphicsPixmapItem item;
|
||||
QCOMPARE(item.opaqueArea(), opaqueArea);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::pixmap_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::newRow("null") << QPixmap();
|
||||
QTest::newRow("10x10") << QPixmap(10, 10);
|
||||
}
|
||||
|
||||
// public QPixmap pixmap() const
|
||||
void tst_QGraphicsPixmapItem::pixmap()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
QCOMPARE(item.pixmap(), pixmap);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::setPixmap_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::newRow("null") << QPixmap();
|
||||
QTest::newRow("10x10") << QPixmap(10, 10);
|
||||
}
|
||||
|
||||
// public void setPixmap(QPixmap const& pixmap)
|
||||
void tst_QGraphicsPixmapItem::setPixmap()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
|
||||
SubQGraphicsPixmapItem item;
|
||||
item.setPixmap(pixmap);
|
||||
QCOMPARE(item.pixmap(), pixmap);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QGraphicsPixmapItem::ShapeMode)
|
||||
void tst_QGraphicsPixmapItem::setShapeMode_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QGraphicsPixmapItem::ShapeMode>("mode");
|
||||
QTest::newRow("MaskShape") << QPixmap() << QGraphicsPixmapItem::MaskShape;
|
||||
QTest::newRow("BoundingRectShape") << QPixmap() << QGraphicsPixmapItem::BoundingRectShape;
|
||||
QTest::newRow("HeuristicMaskShape") << QPixmap() << QGraphicsPixmapItem::HeuristicMaskShape;
|
||||
}
|
||||
|
||||
// public void setShapeMode(QGraphicsPixmapItem::ShapeMode mode)
|
||||
void tst_QGraphicsPixmapItem::setShapeMode()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QGraphicsPixmapItem::ShapeMode, mode);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
item.setShapeMode(mode);
|
||||
QCOMPARE(item.shapeMode(), mode);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::TransformationMode)
|
||||
void tst_QGraphicsPixmapItem::setTransformationMode_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<Qt::TransformationMode>("mode");
|
||||
QTest::newRow("FastTransformation") << QPixmap() << Qt::FastTransformation;
|
||||
QTest::newRow("SmoothTransformation") << QPixmap() << Qt::SmoothTransformation;
|
||||
}
|
||||
|
||||
// public void setTransformationMode(Qt::TransformationMode mode)
|
||||
void tst_QGraphicsPixmapItem::setTransformationMode()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(Qt::TransformationMode, mode);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
item.setTransformationMode(mode);
|
||||
QCOMPARE(item.transformationMode(), mode);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::shape_data()
|
||||
{
|
||||
QTest::addColumn<QPixmap>("pixmap");
|
||||
QTest::addColumn<QPainterPath>("shape");
|
||||
QTest::newRow("null") << QPixmap() << QPainterPath();
|
||||
// ### what does a normal shape look like?
|
||||
}
|
||||
|
||||
// public QPainterPath shape() const
|
||||
void tst_QGraphicsPixmapItem::shape()
|
||||
{
|
||||
QFETCH(QPixmap, pixmap);
|
||||
QFETCH(QPainterPath, shape);
|
||||
|
||||
SubQGraphicsPixmapItem item(pixmap);
|
||||
QCOMPARE(item.shape(), shape);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(SubQGraphicsPixmapItem::Extension)
|
||||
void tst_QGraphicsPixmapItem::extension_data()
|
||||
{
|
||||
QTest::addColumn<QVariant>("variant");
|
||||
QTest::addColumn<QVariant>("extension");
|
||||
QTest::newRow("null") << QVariant() << QVariant();
|
||||
}
|
||||
|
||||
// protected QVariant extension(QVariant const& variant) const
|
||||
void tst_QGraphicsPixmapItem::extension()
|
||||
{
|
||||
QFETCH(QVariant, variant);
|
||||
QFETCH(QVariant, extension);
|
||||
|
||||
SubQGraphicsPixmapItem item;
|
||||
QCOMPARE(item.call_extension(variant), extension);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::setExtension_data()
|
||||
{
|
||||
QTest::addColumn<SubQGraphicsPixmapItem::Extension>("extension");
|
||||
QTest::addColumn<QVariant>("variant");
|
||||
QTest::newRow("null") << SubQGraphicsPixmapItem::UserExtension << QVariant();
|
||||
}
|
||||
|
||||
// protected void setExtension(QGraphicsItem::Extension extension, QVariant const& variant)
|
||||
void tst_QGraphicsPixmapItem::setExtension()
|
||||
{
|
||||
QFETCH(SubQGraphicsPixmapItem::Extension, extension);
|
||||
QFETCH(QVariant, variant);
|
||||
|
||||
SubQGraphicsPixmapItem item;
|
||||
item.call_setExtension(extension, variant);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPixmapItem::supportsExtension_data()
|
||||
{
|
||||
QTest::addColumn<SubQGraphicsPixmapItem::Extension>("extension");
|
||||
QTest::addColumn<bool>("supportsExtension");
|
||||
QTest::newRow("null") << SubQGraphicsPixmapItem::UserExtension << false;
|
||||
}
|
||||
|
||||
// protected bool supportsExtension(QGraphicsItem::Extension extension) const
|
||||
void tst_QGraphicsPixmapItem::supportsExtension()
|
||||
{
|
||||
QFETCH(SubQGraphicsPixmapItem::Extension, extension);
|
||||
QFETCH(bool, supportsExtension);
|
||||
|
||||
SubQGraphicsPixmapItem item;
|
||||
QCOMPARE(item.call_supportsExtension(extension), supportsExtension);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsPixmapItem)
|
||||
#include "tst_qgraphicspixmapitem.moc"
|
||||
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicspolygonitem Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicspolygonitem
|
||||
SOURCES
|
||||
tst_qgraphicspolygonitem.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,284 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qpainterpath.h>
|
||||
#include <qpen.h>
|
||||
|
||||
|
||||
class tst_QGraphicsPolygonItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void qgraphicspolygonitem_data();
|
||||
void qgraphicspolygonitem();
|
||||
void boundingRect_data();
|
||||
void boundingRect();
|
||||
void contains_data();
|
||||
void contains();
|
||||
void fillRule_data();
|
||||
void fillRule();
|
||||
void isObscuredBy_data();
|
||||
void isObscuredBy();
|
||||
void opaqueArea_data();
|
||||
void opaqueArea();
|
||||
void polygon_data();
|
||||
void polygon();
|
||||
void shape_data();
|
||||
void shape();
|
||||
void extension_data();
|
||||
void extension();
|
||||
void setExtension_data();
|
||||
void setExtension();
|
||||
void supportsExtension_data();
|
||||
void supportsExtension();
|
||||
};
|
||||
|
||||
// Subclass that exposes the protected functions.
|
||||
class SubQGraphicsPolygonItem : public QGraphicsPolygonItem
|
||||
{
|
||||
public:
|
||||
enum Extension {
|
||||
UserExtension = QGraphicsItem::UserExtension
|
||||
};
|
||||
|
||||
SubQGraphicsPolygonItem(QGraphicsItem *parent = nullptr) : QGraphicsPolygonItem(parent)
|
||||
{
|
||||
}
|
||||
|
||||
SubQGraphicsPolygonItem(const QPolygonF &polygon, QGraphicsItem *parent = nullptr) : QGraphicsPolygonItem(polygon, parent)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant call_extension(QVariant const& variant) const
|
||||
{ return SubQGraphicsPolygonItem::extension(variant); }
|
||||
|
||||
void call_setExtension(SubQGraphicsPolygonItem::Extension extension, QVariant const& variant)
|
||||
{ return SubQGraphicsPolygonItem::setExtension((QGraphicsItem::Extension)extension, variant); }
|
||||
|
||||
bool call_supportsExtension(SubQGraphicsPolygonItem::Extension extension) const
|
||||
{ return SubQGraphicsPolygonItem::supportsExtension((QGraphicsItem::Extension)extension); }
|
||||
};
|
||||
|
||||
void tst_QGraphicsPolygonItem::qgraphicspolygonitem_data()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::qgraphicspolygonitem()
|
||||
{
|
||||
SubQGraphicsPolygonItem item;
|
||||
|
||||
item.boundingRect();
|
||||
item.contains(QPoint());
|
||||
item.isObscuredBy(0);
|
||||
item.opaqueArea();
|
||||
//item.paint();
|
||||
item.shape();
|
||||
item.type();
|
||||
item.call_extension(QVariant());
|
||||
item.call_setExtension(SubQGraphicsPolygonItem::UserExtension, QVariant());
|
||||
item.call_supportsExtension(SubQGraphicsPolygonItem::UserExtension);
|
||||
item.fillRule();
|
||||
item.polygon();
|
||||
item.setFillRule(Qt::OddEvenFill);
|
||||
item.setPolygon(QPolygonF());
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::boundingRect_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::addColumn<QRectF>("boundingRect");
|
||||
QTest::newRow("null") << QPolygonF() << QRectF();
|
||||
QPolygonF example;
|
||||
example << QPointF(10.4, 20.5) << QPointF(20.2, 30.2);
|
||||
QTest::newRow("example") << example << example.boundingRect();
|
||||
// ### set pen width?
|
||||
}
|
||||
|
||||
// public QRectF boundingRect() const
|
||||
void tst_QGraphicsPolygonItem::boundingRect()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
QFETCH(QRectF, boundingRect);
|
||||
|
||||
SubQGraphicsPolygonItem item(polygon);
|
||||
item.setPen(QPen(Qt::black, 0));
|
||||
QCOMPARE(item.boundingRect(), boundingRect);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::contains_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::addColumn<QPointF>("point");
|
||||
QTest::addColumn<bool>("contains");
|
||||
QTest::newRow("null") << QPolygonF() << QPointF() << false;
|
||||
}
|
||||
|
||||
// public bool contains(QPointF const& point) const
|
||||
void tst_QGraphicsPolygonItem::contains()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
QFETCH(QPointF, point);
|
||||
QFETCH(bool, contains);
|
||||
|
||||
SubQGraphicsPolygonItem item(polygon);
|
||||
|
||||
QCOMPARE(item.contains(point), contains);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::FillRule)
|
||||
void tst_QGraphicsPolygonItem::fillRule_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::addColumn<Qt::FillRule>("fillRule");
|
||||
QTest::newRow("OddEvenFill") << QPolygonF() << Qt::OddEvenFill;
|
||||
QTest::newRow("WindingFill") << QPolygonF() << Qt::WindingFill;
|
||||
}
|
||||
|
||||
// public Qt::FillRule fillRule() const
|
||||
void tst_QGraphicsPolygonItem::fillRule()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
QFETCH(Qt::FillRule, fillRule);
|
||||
|
||||
SubQGraphicsPolygonItem item(polygon);
|
||||
|
||||
item.setFillRule(fillRule);
|
||||
QCOMPARE(item.fillRule(), fillRule);
|
||||
// ### Check that the painting is different?
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::isObscuredBy_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::addColumn<QPolygonF>("otherPolygon");
|
||||
QTest::addColumn<bool>("isObscuredBy");
|
||||
QTest::newRow("null") << QPolygonF() << QPolygonF() << false;
|
||||
//QTest::newRow("ontop-inside") << QPixmap(10, 10) << QPixmap(5, 5) << false;
|
||||
//QTest::newRow("ontop-larger") << QPixmap(10, 10) << QPixmap(11, 11) << true;
|
||||
}
|
||||
|
||||
// public bool isObscuredBy(QGraphicsItem const* item) const
|
||||
void tst_QGraphicsPolygonItem::isObscuredBy()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
QFETCH(QPolygonF, otherPolygon);
|
||||
QFETCH(bool, isObscuredBy);
|
||||
SubQGraphicsPolygonItem item(polygon);
|
||||
SubQGraphicsPolygonItem otherItem(otherPolygon);
|
||||
QCOMPARE(item.isObscuredBy(&otherItem), isObscuredBy);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QPainterPath)
|
||||
void tst_QGraphicsPolygonItem::opaqueArea_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::addColumn<QPainterPath>("opaqueArea");
|
||||
QTest::newRow("null") << QPolygonF() << QPainterPath();
|
||||
// Currently QGraphicsPolygonItem just calls QGraphicsItem test there
|
||||
}
|
||||
|
||||
// public QPainterPath opaqueArea() const
|
||||
void tst_QGraphicsPolygonItem::opaqueArea()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
QFETCH(QPainterPath, opaqueArea);
|
||||
|
||||
SubQGraphicsPolygonItem item(polygon);
|
||||
QCOMPARE(item.opaqueArea(), opaqueArea);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::polygon_data()
|
||||
{
|
||||
QTest::addColumn<QPolygonF>("polygon");
|
||||
QTest::newRow("null") << QPolygonF();
|
||||
QPolygonF example;
|
||||
example << QPointF(10.4, 20.5) << QPointF(20.2, 30.2);
|
||||
QTest::newRow("example") << example;
|
||||
}
|
||||
|
||||
// public QPolygonF polygon() const
|
||||
void tst_QGraphicsPolygonItem::polygon()
|
||||
{
|
||||
QFETCH(QPolygonF, polygon);
|
||||
|
||||
SubQGraphicsPolygonItem item;
|
||||
item.setPolygon(polygon);
|
||||
QCOMPARE(item.polygon(), polygon);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::shape_data()
|
||||
{
|
||||
QTest::addColumn<QPainterPath>("shape");
|
||||
QTest::newRow("null") << QPainterPath();
|
||||
// ### what should a normal shape look like?
|
||||
}
|
||||
|
||||
// public QPainterPath shape() const
|
||||
void tst_QGraphicsPolygonItem::shape()
|
||||
{
|
||||
QFETCH(QPainterPath, shape);
|
||||
|
||||
SubQGraphicsPolygonItem item;
|
||||
QCOMPARE(item.shape(), shape);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::extension_data()
|
||||
{
|
||||
QTest::addColumn<QVariant>("variant");
|
||||
QTest::addColumn<QVariant>("extension");
|
||||
QTest::newRow("null") << QVariant() << QVariant();
|
||||
}
|
||||
|
||||
// protected QVariant extension(QVariant const& variant) const
|
||||
void tst_QGraphicsPolygonItem::extension()
|
||||
{
|
||||
QFETCH(QVariant, variant);
|
||||
QFETCH(QVariant, extension);
|
||||
|
||||
SubQGraphicsPolygonItem item;
|
||||
|
||||
QCOMPARE(item.call_extension(variant), extension);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(SubQGraphicsPolygonItem::Extension)
|
||||
void tst_QGraphicsPolygonItem::setExtension_data()
|
||||
{
|
||||
QTest::addColumn<SubQGraphicsPolygonItem::Extension>("extension");
|
||||
QTest::addColumn<QVariant>("variant");
|
||||
QTest::newRow("null") << SubQGraphicsPolygonItem::Extension() << QVariant();
|
||||
}
|
||||
|
||||
// protected void setExtension(SubQGraphicsPolygonItem::Extension extension, QVariant const& variant)
|
||||
void tst_QGraphicsPolygonItem::setExtension()
|
||||
{
|
||||
QFETCH(SubQGraphicsPolygonItem::Extension, extension);
|
||||
QFETCH(QVariant, variant);
|
||||
|
||||
SubQGraphicsPolygonItem item;
|
||||
item.call_setExtension(extension, variant);
|
||||
}
|
||||
|
||||
void tst_QGraphicsPolygonItem::supportsExtension_data()
|
||||
{
|
||||
QTest::addColumn<SubQGraphicsPolygonItem::Extension>("extension");
|
||||
QTest::addColumn<bool>("supportsExtension");
|
||||
QTest::newRow("null") << SubQGraphicsPolygonItem::Extension() << false;
|
||||
}
|
||||
|
||||
// protected bool supportsExtension(SubQGraphicsPolygonItem::Extension extension) const
|
||||
void tst_QGraphicsPolygonItem::supportsExtension()
|
||||
{
|
||||
QFETCH(SubQGraphicsPolygonItem::Extension, extension);
|
||||
QFETCH(bool, supportsExtension);
|
||||
|
||||
SubQGraphicsPolygonItem item;
|
||||
QCOMPARE(item.call_supportsExtension(extension), supportsExtension);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsPolygonItem)
|
||||
#include "tst_qgraphicspolygonitem.moc"
|
||||
|
@ -0,0 +1,11 @@
|
||||
[scrollUpdate]
|
||||
android
|
||||
b2qt
|
||||
[windowOpacity]
|
||||
macos ci
|
||||
[wheelEventPropagation]
|
||||
android
|
||||
[forwardTouchEvent]
|
||||
android
|
||||
[touchEventPropagation]
|
||||
android
|
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsproxywidget Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsproxywidget
|
||||
SOURCES
|
||||
tst_qgraphicsproxywidget.cpp
|
||||
DEFINES
|
||||
QTEST_QPA_MOUSE_HANDLING
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
BIN
tests/auto/widgets/graphicsview/qgraphicsscene/Ash_European.jpg
Normal file
After Width: | Height: | Size: 4.6 KiB |
@ -0,0 +1,64 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsscene Test:
|
||||
#####################################################################
|
||||
|
||||
# Resources:
|
||||
|
||||
set(testdata_resource_files
|
||||
"Ash_European.jpg"
|
||||
"testData/render/all-all-45-deg-left.png"
|
||||
"testData/render/all-all-45-deg-right.png"
|
||||
"testData/render/all-all-scale-2x.png"
|
||||
"testData/render/all-all-translate-0-50.png"
|
||||
"testData/render/all-all-translate-50-0.png"
|
||||
"testData/render/all-all-untransformed-clip-ellipse.png"
|
||||
"testData/render/all-all-untransformed-clip-rect.png"
|
||||
"testData/render/all-all-untransformed.png"
|
||||
"testData/render/all-bottomleft-untransformed.png"
|
||||
"testData/render/all-bottomright-untransformed.png"
|
||||
"testData/render/all-topleft-untransformed.png"
|
||||
"testData/render/all-topright-untransformed.png"
|
||||
"testData/render/bottom-bottomright-untransformed.png"
|
||||
"testData/render/bottom-topleft-untransformed.png"
|
||||
"testData/render/bottomleft-all-untransformed.png"
|
||||
"testData/render/bottomleft-topleft-untransformed.png"
|
||||
"testData/render/bottomright-all-untransformed.png"
|
||||
"testData/render/bottomright-topleft-untransformed.png"
|
||||
"testData/render/left-bottomright-untransformed.png"
|
||||
"testData/render/left-topleft-untransformed.png"
|
||||
"testData/render/right-bottomright-untransformed.png"
|
||||
"testData/render/right-topleft-untransformed.png"
|
||||
"testData/render/top-bottomright-untransformed.png"
|
||||
"testData/render/top-topleft-untransformed.png"
|
||||
"testData/render/topleft-all-untransformed.png"
|
||||
"testData/render/topleft-topleft-untransformed.png"
|
||||
"testData/render/topright-all-untransformed.png"
|
||||
"testData/render/topright-topleft-untransformed.png"
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsscene
|
||||
LOWDPI
|
||||
SOURCES
|
||||
tst_qgraphicsscene.cpp
|
||||
DEFINES
|
||||
QT_NO_CAST_TO_ASCII
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
TESTDATA ${testdata_resource_files}
|
||||
BUILTIN_TESTDATA
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qgraphicsscene CONDITION WIN32
|
||||
LIBRARIES
|
||||
user32
|
||||
)
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>Ash_European.jpg</file>
|
||||
</qresource>
|
||||
</RCC>
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT QT_FEATURE_private_tests)
|
||||
return()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicssceneindex Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicssceneindex
|
||||
SOURCES
|
||||
tst_qgraphicssceneindex.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1,339 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QtGui/QPainterPath>
|
||||
#include <QtWidgets/qgraphicsscene.h>
|
||||
#include <private/qgraphicsscenebsptreeindex_p.h>
|
||||
#include <private/qgraphicssceneindex_p.h>
|
||||
#include <private/qgraphicsscenelinearindex_p.h>
|
||||
#include <QtWidgets/private/qapplication_p.h>
|
||||
|
||||
class tst_QGraphicsSceneIndex : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void initTestCase();
|
||||
|
||||
private slots:
|
||||
void scatteredItems_data();
|
||||
void scatteredItems();
|
||||
void overlappedItems_data();
|
||||
void overlappedItems();
|
||||
void movingItems_data();
|
||||
void movingItems();
|
||||
void connectedToSceneRectChanged();
|
||||
void items();
|
||||
void boundingRectPointIntersection_data();
|
||||
void boundingRectPointIntersection();
|
||||
void removeItems();
|
||||
void clear();
|
||||
|
||||
private:
|
||||
void common_data();
|
||||
QGraphicsSceneIndex *createIndex(const QString &name);
|
||||
};
|
||||
|
||||
void tst_QGraphicsSceneIndex::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::common_data()
|
||||
{
|
||||
QTest::addColumn<QString>("indexMethod");
|
||||
|
||||
QTest::newRow("BSP") << QString("bsp");
|
||||
QTest::newRow("Linear") << QString("linear");
|
||||
}
|
||||
|
||||
QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod)
|
||||
{
|
||||
QGraphicsSceneIndex *index = nullptr;
|
||||
QGraphicsScene *scene = new QGraphicsScene();
|
||||
if (indexMethod == "bsp")
|
||||
index = new QGraphicsSceneBspTreeIndex(scene);
|
||||
|
||||
if (indexMethod == "linear")
|
||||
index = new QGraphicsSceneLinearIndex(scene);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::scatteredItems_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::scatteredItems()
|
||||
{
|
||||
QFETCH(QString, indexMethod);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
scene.addRect(i*50, i*50, 40, 35);
|
||||
|
||||
QCOMPARE(scene.items(QPointF(5, 5)).size(), 1);
|
||||
QCOMPARE(scene.items(QPointF(55, 55)).size(), 1);
|
||||
QCOMPARE(scene.items(QPointF(-100, -100)).size(), 0);
|
||||
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).size(), 1);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).size(), 10);
|
||||
QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).size(), 0);
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::overlappedItems_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::overlappedItems()
|
||||
{
|
||||
QFETCH(QString, indexMethod);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
for (int j = 0; j < 10; ++j)
|
||||
scene.addRect(i*50, j*50, 200, 200)->setPen(QPen(Qt::black, 0));
|
||||
|
||||
QCOMPARE(scene.items(QPointF(5, 5)).size(), 1);
|
||||
QCOMPARE(scene.items(QPointF(55, 55)).size(), 4);
|
||||
QCOMPARE(scene.items(QPointF(105, 105)).size(), 9);
|
||||
QCOMPARE(scene.items(QPointF(-100, -100)).size(), 0);
|
||||
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).size(), 100);
|
||||
QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).size(), 0);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).size(), 16);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 100, 100)).size(), 4);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1, 100)).size(), 2);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).size(), 10);
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::movingItems_data()
|
||||
{
|
||||
common_data();
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::movingItems()
|
||||
{
|
||||
QFETCH(QString, indexMethod);
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
scene.addRect(i*50, i*50, 40, 35);
|
||||
|
||||
QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10);
|
||||
QCOMPARE(scene.items(QPointF(5, 5)).size(), 2);
|
||||
QCOMPARE(scene.items(QPointF(-1, -1)).size(), 0);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).size(), 2);
|
||||
|
||||
box->setPos(10, 10);
|
||||
QCOMPARE(scene.items(QPointF(9, 9)).size(), 1);
|
||||
QCOMPARE(scene.items(QPointF(15, 15)).size(), 2);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).size(), 1);
|
||||
|
||||
box->setPos(-5, -5);
|
||||
QCOMPARE(scene.items(QPointF(-1, -1)).size(), 1);
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).size(), 2);
|
||||
|
||||
QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).size(), 11);
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::connectedToSceneRectChanged()
|
||||
{
|
||||
|
||||
class MyScene : public QGraphicsScene
|
||||
{
|
||||
public:
|
||||
using QGraphicsScene::receivers;
|
||||
};
|
||||
|
||||
MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default.
|
||||
QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(QRectF))), 1);
|
||||
|
||||
scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex
|
||||
QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(QRectF))), 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::items()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10);
|
||||
QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10);
|
||||
QCOMPARE(scene.items().size(), 2);
|
||||
|
||||
// Move from unindexed items into bsp tree.
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(scene.items().size(), 2);
|
||||
|
||||
// Add untransformable item.
|
||||
QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10));
|
||||
item3->setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||
scene.addItem(item3);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
|
||||
// Move from unindexed items into untransformable items.
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
|
||||
// Move from untransformable items into unindexed items.
|
||||
item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
|
||||
// Make all items untransformable.
|
||||
item1->setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||
item2->setParentItem(item1);
|
||||
item3->setParentItem(item2);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
|
||||
// Move from unindexed items into untransformable items.
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(scene.items().size(), 3);
|
||||
}
|
||||
|
||||
class CustomShapeItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
CustomShapeItem(const QPainterPath &shape) : QGraphicsItem(0), mShape(shape) {}
|
||||
|
||||
QPainterPath shape() const override { return mShape; }
|
||||
QRectF boundingRect() const override { return mShape.boundingRect(); }
|
||||
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override {}
|
||||
private:
|
||||
QPainterPath mShape;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::ItemSelectionMode)
|
||||
Q_DECLARE_METATYPE(QPainterPath)
|
||||
|
||||
void tst_QGraphicsSceneIndex::boundingRectPointIntersection_data()
|
||||
{
|
||||
QTest::addColumn<QPainterPath>("itemShape");
|
||||
QTest::addColumn<Qt::ItemSelectionMode>("mode");
|
||||
|
||||
QTest::newRow("zero shape - intersects rect") << QPainterPath() << Qt::IntersectsItemBoundingRect;
|
||||
QTest::newRow("zero shape - contains rect") << QPainterPath() << Qt::ContainsItemBoundingRect;
|
||||
|
||||
QPainterPath triangle;
|
||||
triangle.moveTo(50, 0);
|
||||
triangle.lineTo(0, 50);
|
||||
triangle.lineTo(100, 50);
|
||||
triangle.lineTo(50, 0);
|
||||
QTest::newRow("triangle shape - intersects rect") << triangle << Qt::IntersectsItemBoundingRect;
|
||||
QTest::newRow("triangle shape - contains rect") << triangle << Qt::ContainsItemBoundingRect;
|
||||
|
||||
QPainterPath rect;
|
||||
rect.addRect(QRectF(0, 0, 100, 100));
|
||||
QTest::newRow("rectangle shape - intersects rect") << rect << Qt::IntersectsItemBoundingRect;
|
||||
QTest::newRow("rectangle shape - contains rect") << rect << Qt::ContainsItemBoundingRect;
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::boundingRectPointIntersection()
|
||||
{
|
||||
QFETCH(QPainterPath, itemShape);
|
||||
QFETCH(Qt::ItemSelectionMode, mode);
|
||||
|
||||
QGraphicsScene scene;
|
||||
CustomShapeItem *item = new CustomShapeItem(itemShape);
|
||||
scene.addItem(item);
|
||||
QList<QGraphicsItem*> items = scene.items(QPointF(0, 0), mode, Qt::AscendingOrder);
|
||||
QVERIFY(!items.isEmpty());
|
||||
QCOMPARE(items.first(), item);
|
||||
}
|
||||
|
||||
class RectWidget : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RectWidget(QGraphicsItem *parent = nullptr) : QGraphicsWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option */, QWidget * /* widget */) override
|
||||
{
|
||||
painter->setBrush(brush);
|
||||
painter->drawRect(boundingRect());
|
||||
}
|
||||
public:
|
||||
QBrush brush;
|
||||
};
|
||||
|
||||
void tst_QGraphicsSceneIndex::removeItems()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
|
||||
RectWidget *parent = new RectWidget;
|
||||
parent->brush = QBrush(QColor(Qt::magenta));
|
||||
parent->setGeometry(250, 250, 400, 400);
|
||||
|
||||
RectWidget *widget = new RectWidget(parent);
|
||||
widget->brush = QBrush(QColor(Qt::blue));
|
||||
widget->setGeometry(10, 10, 200, 200);
|
||||
|
||||
RectWidget *widgetChild1 = new RectWidget(widget);
|
||||
widgetChild1->brush = QBrush(QColor(Qt::green));
|
||||
widgetChild1->setGeometry(20, 20, 100, 100);
|
||||
|
||||
RectWidget *widgetChild2 = new RectWidget(widgetChild1);
|
||||
widgetChild2->brush = QBrush(QColor(Qt::yellow));
|
||||
widgetChild2->setGeometry(25, 25, 50, 50);
|
||||
|
||||
scene.addItem(parent);
|
||||
|
||||
QGraphicsView view(&scene);
|
||||
view.resize(600, 600);
|
||||
view.show();
|
||||
QApplicationPrivate::setActiveWindow(&view);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&view));
|
||||
|
||||
scene.removeItem(widgetChild1);
|
||||
|
||||
delete widgetChild1;
|
||||
|
||||
//We move the parent
|
||||
scene.items(QRectF(295, 295, 50, 50));
|
||||
|
||||
//This should not crash
|
||||
}
|
||||
|
||||
void tst_QGraphicsSceneIndex::clear()
|
||||
{
|
||||
class MyItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
MyItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent), numPaints(0) {}
|
||||
int numPaints;
|
||||
protected:
|
||||
QRectF boundingRect() const override { return QRectF(0, 0, 10, 10); }
|
||||
void paint(QPainter * /* painter */, const QStyleOptionGraphicsItem *, QWidget *) override
|
||||
{ ++numPaints; }
|
||||
};
|
||||
|
||||
QGraphicsScene scene;
|
||||
scene.setSceneRect(0, 0, 100, 100);
|
||||
scene.addItem(new MyItem);
|
||||
|
||||
QGraphicsView view(&scene);
|
||||
view.show();
|
||||
QApplicationPrivate::setActiveWindow(&view);
|
||||
QVERIFY(QTest::qWaitForWindowActive(&view));
|
||||
scene.clear();
|
||||
|
||||
// Make sure the index is re-generated after QGraphicsScene::clear();
|
||||
// otherwise no items will be painted.
|
||||
MyItem *item = new MyItem;
|
||||
scene.addItem(item);
|
||||
qApp->processEvents();
|
||||
QTRY_VERIFY(item->numPaints > 0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsSceneIndex)
|
||||
#include "tst_qgraphicssceneindex.moc"
|
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicstransform Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicstransform
|
||||
SOURCES
|
||||
tst_qgraphicstransform.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,336 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qgraphicsitem.h>
|
||||
#include <qgraphicstransform.h>
|
||||
|
||||
class tst_QGraphicsTransform : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void scale();
|
||||
void rotation();
|
||||
void rotation3d_data();
|
||||
void rotation3d();
|
||||
void rotation3dArbitraryAxis_data();
|
||||
void rotation3dArbitraryAxis();
|
||||
|
||||
private:
|
||||
QString toString(QTransform const&);
|
||||
};
|
||||
|
||||
static QTransform transform2D(const QGraphicsTransform& t)
|
||||
{
|
||||
QMatrix4x4 m;
|
||||
t.applyTo(&m);
|
||||
return m.toTransform();
|
||||
}
|
||||
|
||||
void tst_QGraphicsTransform::scale()
|
||||
{
|
||||
QGraphicsScale scale;
|
||||
|
||||
// check initial conditions
|
||||
QCOMPARE(scale.xScale(), qreal(1));
|
||||
QCOMPARE(scale.yScale(), qreal(1));
|
||||
QCOMPARE(scale.zScale(), qreal(1));
|
||||
QCOMPARE(scale.origin(), QVector3D(0, 0, 0));
|
||||
|
||||
scale.setOrigin(QVector3D(10, 10, 0));
|
||||
|
||||
QCOMPARE(scale.xScale(), qreal(1));
|
||||
QCOMPARE(scale.yScale(), qreal(1));
|
||||
QCOMPARE(scale.zScale(), qreal(1));
|
||||
QCOMPARE(scale.origin(), QVector3D(10, 10, 0));
|
||||
|
||||
QMatrix4x4 t;
|
||||
scale.applyTo(&t);
|
||||
|
||||
QCOMPARE(t, QMatrix4x4());
|
||||
QCOMPARE(transform2D(scale), QTransform());
|
||||
|
||||
scale.setXScale(10);
|
||||
scale.setOrigin(QVector3D(0, 0, 0));
|
||||
|
||||
QCOMPARE(scale.xScale(), qreal(10));
|
||||
QCOMPARE(scale.yScale(), qreal(1));
|
||||
QCOMPARE(scale.zScale(), qreal(1));
|
||||
QCOMPARE(scale.origin(), QVector3D(0, 0, 0));
|
||||
|
||||
QTransform res;
|
||||
res.scale(10, 1);
|
||||
|
||||
QCOMPARE(transform2D(scale), res);
|
||||
QCOMPARE(transform2D(scale).map(QPointF(10, 10)), QPointF(100, 10));
|
||||
|
||||
scale.setOrigin(QVector3D(10, 10, 0));
|
||||
QCOMPARE(transform2D(scale).map(QPointF(10, 10)), QPointF(10, 10));
|
||||
QCOMPARE(transform2D(scale).map(QPointF(11, 10)), QPointF(20, 10));
|
||||
|
||||
scale.setYScale(2);
|
||||
scale.setZScale(4.5);
|
||||
scale.setOrigin(QVector3D(1, 2, 3));
|
||||
|
||||
QCOMPARE(scale.xScale(), qreal(10));
|
||||
QCOMPARE(scale.yScale(), qreal(2));
|
||||
QCOMPARE(scale.zScale(), qreal(4.5));
|
||||
QCOMPARE(scale.origin(), QVector3D(1, 2, 3));
|
||||
|
||||
QMatrix4x4 t2;
|
||||
scale.applyTo(&t2);
|
||||
|
||||
QCOMPARE(t2.map(QVector3D(4, 5, 6)), QVector3D(31, 8, 16.5));
|
||||
|
||||
// Because the origin has a non-zero z, mapping (4, 5) in 2D
|
||||
// will introduce a projective component into the result.
|
||||
QTransform t3 = t2.toTransform();
|
||||
QCOMPARE(t3.map(QPointF(4, 5)), QPointF(31 / t3.m33(), 8 / t3.m33()));
|
||||
}
|
||||
|
||||
// fuzzyCompareNonZero is a very slightly looser version of qFuzzyCompare
|
||||
// for use with values that are not very close to zero
|
||||
constexpr static inline bool fuzzyCompareNonZero(float p1, float p2)
|
||||
{
|
||||
return (qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2)));
|
||||
}
|
||||
|
||||
// This is a more tolerant version of qFuzzyCompare that also handles the case
|
||||
// where one or more of the values being compare are close to zero
|
||||
static inline bool fuzzyCompare(float p1, float p2)
|
||||
{
|
||||
if (qFuzzyIsNull(p1))
|
||||
return qFuzzyIsNull(p2);
|
||||
else if (qFuzzyIsNull(p2))
|
||||
return false;
|
||||
else
|
||||
return fuzzyCompareNonZero(p1, p2);
|
||||
}
|
||||
|
||||
// This compares two QTransforms by casting the elements to float. This is
|
||||
// necessary here because in this test one of the transforms is created from
|
||||
// a QMatrix4x4 which uses float storage.
|
||||
static bool fuzzyCompareAsFloat(const QTransform& t1, const QTransform& t2)
|
||||
{
|
||||
return fuzzyCompare(float(t1.m11()), float(t2.m11())) &&
|
||||
fuzzyCompare(float(t1.m12()), float(t2.m12())) &&
|
||||
fuzzyCompare(float(t1.m13()), float(t2.m13())) &&
|
||||
fuzzyCompare(float(t1.m21()), float(t2.m21())) &&
|
||||
fuzzyCompare(float(t1.m22()), float(t2.m22())) &&
|
||||
fuzzyCompare(float(t1.m23()), float(t2.m23())) &&
|
||||
fuzzyCompare(float(t1.m31()), float(t2.m31())) &&
|
||||
fuzzyCompare(float(t1.m32()), float(t2.m32())) &&
|
||||
fuzzyCompare(float(t1.m33()), float(t2.m33()));
|
||||
}
|
||||
|
||||
static inline bool fuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2)
|
||||
{
|
||||
bool ok = true;
|
||||
for (int y = 0; y < 4; ++y)
|
||||
for (int x = 0; x < 4; ++x)
|
||||
ok &= fuzzyCompare(m1(y, x), m2(y, x));
|
||||
return ok;
|
||||
}
|
||||
|
||||
void tst_QGraphicsTransform::rotation()
|
||||
{
|
||||
QGraphicsRotation rotation;
|
||||
QCOMPARE(rotation.axis(), QVector3D(0, 0, 1));
|
||||
QCOMPARE(rotation.origin(), QVector3D(0, 0, 0));
|
||||
QCOMPARE(rotation.angle(), (qreal)0);
|
||||
|
||||
rotation.setOrigin(QVector3D(10, 10, 0));
|
||||
|
||||
QCOMPARE(rotation.axis(), QVector3D(0, 0, 1));
|
||||
QCOMPARE(rotation.origin(), QVector3D(10, 10, 0));
|
||||
QCOMPARE(rotation.angle(), (qreal)0);
|
||||
|
||||
QMatrix4x4 t;
|
||||
rotation.applyTo(&t);
|
||||
|
||||
QCOMPARE(t, QMatrix4x4());
|
||||
QCOMPARE(transform2D(rotation), QTransform());
|
||||
|
||||
rotation.setAngle(40);
|
||||
rotation.setOrigin(QVector3D(0, 0, 0));
|
||||
|
||||
QCOMPARE(rotation.axis(), QVector3D(0, 0, 1));
|
||||
QCOMPARE(rotation.origin(), QVector3D(0, 0, 0));
|
||||
QCOMPARE(rotation.angle(), (qreal)40);
|
||||
|
||||
QTransform res;
|
||||
res.rotate(40);
|
||||
|
||||
QVERIFY(fuzzyCompareAsFloat(transform2D(rotation), res));
|
||||
|
||||
rotation.setOrigin(QVector3D(10, 10, 0));
|
||||
rotation.setAngle(90);
|
||||
QCOMPARE(transform2D(rotation).map(QPointF(10, 10)), QPointF(10, 10));
|
||||
QCOMPARE(transform2D(rotation).map(QPointF(20, 10)), QPointF(10, 20));
|
||||
|
||||
rotation.setOrigin(QVector3D(0, 0, 0));
|
||||
rotation.setAngle(qQNaN());
|
||||
QCOMPARE(transform2D(rotation).map(QPointF(20, 10)), QPointF(20, 10));
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(Qt::Axis);
|
||||
void tst_QGraphicsTransform::rotation3d_data()
|
||||
{
|
||||
QTest::addColumn<Qt::Axis>("axis");
|
||||
QTest::addColumn<qreal>("angle");
|
||||
|
||||
for (int angle = 0; angle <= 360; angle++) {
|
||||
QTest::newRow("test rotation on X") << Qt::XAxis << qreal(angle);
|
||||
QTest::newRow("test rotation on Y") << Qt::YAxis << qreal(angle);
|
||||
QTest::newRow("test rotation on Z") << Qt::ZAxis << qreal(angle);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsTransform::rotation3d()
|
||||
{
|
||||
QFETCH(Qt::Axis, axis);
|
||||
QFETCH(qreal, angle);
|
||||
|
||||
QGraphicsRotation rotation;
|
||||
rotation.setAxis(axis);
|
||||
|
||||
QMatrix4x4 t;
|
||||
rotation.applyTo(&t);
|
||||
|
||||
QVERIFY(t.isIdentity());
|
||||
QVERIFY(transform2D(rotation).isIdentity());
|
||||
|
||||
rotation.setAngle(angle);
|
||||
|
||||
// QGraphicsRotation uses a correct mathematical rotation in 3D.
|
||||
// QTransform's Qt::YAxis rotation is inverted from the mathematical
|
||||
// version of rotation. We correct for that here.
|
||||
QTransform expected;
|
||||
if (axis == Qt::YAxis && angle != 180.)
|
||||
expected.rotate(-angle, axis);
|
||||
else
|
||||
expected.rotate(angle, axis);
|
||||
|
||||
QVERIFY(fuzzyCompareAsFloat(transform2D(rotation), expected));
|
||||
|
||||
// Check that "rotation" produces the 4x4 form of the 3x3 matrix.
|
||||
// i.e. third row and column are 0 0 1 0.
|
||||
t.setToIdentity();
|
||||
rotation.applyTo(&t);
|
||||
QMatrix4x4 r(expected);
|
||||
QVERIFY(fuzzyCompare(t, r));
|
||||
|
||||
//now let's check that a null vector will not change the transform
|
||||
rotation.setAxis(QVector3D(0, 0, 0));
|
||||
rotation.setOrigin(QVector3D(10, 10, 0));
|
||||
|
||||
t.setToIdentity();
|
||||
rotation.applyTo(&t);
|
||||
|
||||
QVERIFY(t.isIdentity());
|
||||
QVERIFY(transform2D(rotation).isIdentity());
|
||||
|
||||
rotation.setAngle(angle);
|
||||
|
||||
QVERIFY(t.isIdentity());
|
||||
QVERIFY(transform2D(rotation).isIdentity());
|
||||
|
||||
rotation.setOrigin(QVector3D(0, 0, 0));
|
||||
|
||||
QVERIFY(t.isIdentity());
|
||||
QVERIFY(transform2D(rotation).isIdentity());
|
||||
}
|
||||
|
||||
QByteArray labelForTest(QVector3D const& axis, int angle) {
|
||||
return QString("rotation of %1 on (%2, %3, %4)")
|
||||
.arg(angle)
|
||||
.arg(axis.x())
|
||||
.arg(axis.y())
|
||||
.arg(axis.z())
|
||||
.toLatin1();
|
||||
}
|
||||
|
||||
void tst_QGraphicsTransform::rotation3dArbitraryAxis_data()
|
||||
{
|
||||
QTest::addColumn<QVector3D>("axis");
|
||||
QTest::addColumn<qreal>("angle");
|
||||
|
||||
QVector3D axis1 = QVector3D(1.0f, 1.0f, 1.0f);
|
||||
QVector3D axis2 = QVector3D(2.0f, -3.0f, 0.5f);
|
||||
QVector3D axis3 = QVector3D(-2.0f, 0.0f, -0.5f);
|
||||
QVector3D axis4 = QVector3D(0.0001f, 0.0001f, 0.0001f);
|
||||
QVector3D axis5 = QVector3D(0.01f, 0.01f, 0.01f);
|
||||
|
||||
for (int angle = 0; angle <= 360; angle++) {
|
||||
QTest::newRow(labelForTest(axis1, angle).constData()) << axis1 << qreal(angle);
|
||||
QTest::newRow(labelForTest(axis2, angle).constData()) << axis2 << qreal(angle);
|
||||
QTest::newRow(labelForTest(axis3, angle).constData()) << axis3 << qreal(angle);
|
||||
QTest::newRow(labelForTest(axis4, angle).constData()) << axis4 << qreal(angle);
|
||||
QTest::newRow(labelForTest(axis5, angle).constData()) << axis5 << qreal(angle);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QGraphicsTransform::rotation3dArbitraryAxis()
|
||||
{
|
||||
QFETCH(QVector3D, axis);
|
||||
QFETCH(qreal, angle);
|
||||
|
||||
QGraphicsRotation rotation;
|
||||
rotation.setAxis(axis);
|
||||
|
||||
QMatrix4x4 t;
|
||||
rotation.applyTo(&t);
|
||||
|
||||
QVERIFY(t.isIdentity());
|
||||
QVERIFY(transform2D(rotation).isIdentity());
|
||||
|
||||
rotation.setAngle(angle);
|
||||
|
||||
// Compute the expected answer using QMatrix4x4 and a projection.
|
||||
// These two steps are performed in one hit by QGraphicsRotation.
|
||||
QMatrix4x4 exp;
|
||||
exp.rotate(angle, axis);
|
||||
QTransform expected = exp.toTransform(1024.0f);
|
||||
|
||||
QTransform actual = transform2D(rotation);
|
||||
QVERIFY2(fuzzyCompareAsFloat(actual, expected), qPrintable(
|
||||
QString("\nactual: %1\n"
|
||||
"expected: %2")
|
||||
.arg(toString(actual))
|
||||
.arg(toString(expected))
|
||||
));
|
||||
|
||||
// Check that "rotation" produces the 4x4 form of the 3x3 matrix.
|
||||
// i.e. third row and column are 0 0 1 0.
|
||||
t.setToIdentity();
|
||||
rotation.applyTo(&t);
|
||||
QMatrix4x4 r(expected);
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
for (int col = 0; col < 4; ++col) {
|
||||
float a = t(row, col);
|
||||
float b = r(row, col);
|
||||
QVERIFY2(fuzzyCompare(a, b), QString("%1 is not equal to %2").arg(a).arg(b).toLatin1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString tst_QGraphicsTransform::toString(QTransform const& t)
|
||||
{
|
||||
return QString("[ [ %1 %2 %3 ]; [ %4 %5 %6 ]; [ %7 %8 %9 ] ]")
|
||||
.arg(t.m11())
|
||||
.arg(t.m12())
|
||||
.arg(t.m13())
|
||||
.arg(t.m21())
|
||||
.arg(t.m22())
|
||||
.arg(t.m23())
|
||||
.arg(t.m31())
|
||||
.arg(t.m32())
|
||||
.arg(t.m33())
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsTransform)
|
||||
#include "tst_qgraphicstransform.moc"
|
||||
|
37
tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST
Normal file
@ -0,0 +1,37 @@
|
||||
[cursor2]
|
||||
osx
|
||||
[resizeAnchor]
|
||||
rhel
|
||||
# QTBUG-87397
|
||||
[itemsAtPoint]
|
||||
android
|
||||
[itemsInRect_cosmeticAdjust]
|
||||
android
|
||||
[itemAt]
|
||||
android
|
||||
[mapToScenePath]
|
||||
android
|
||||
[mapFromScenePoly]
|
||||
android
|
||||
[mapFromScenePath]
|
||||
android
|
||||
[viewportUpdateMode]
|
||||
android
|
||||
[scrollBarRanges]
|
||||
android
|
||||
[moveItemWhileScrolling]
|
||||
android
|
||||
[exposeRegion]
|
||||
android
|
||||
[update2]
|
||||
android
|
||||
[update_ancestorClipsChildrenToShape]
|
||||
android
|
||||
[update_ancestorClipsChildrenToShape2]
|
||||
android
|
||||
[QTBUG_70255_scrollTo]
|
||||
android # QTBUG-87397
|
||||
[embeddedViewsWithFocus]
|
||||
android # QTBUG-87397
|
||||
[viewportUpdateMode2]
|
||||
android # QTBUG-87397
|
30
tests/auto/widgets/graphicsview/qgraphicsview/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicsview Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicsview
|
||||
SOURCES
|
||||
tst_qgraphicsview.cpp tst_qgraphicsview.h
|
||||
tst_qgraphicsview_2.cpp
|
||||
DEFINES
|
||||
QT_NO_CAST_TO_ASCII
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::TestPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_qgraphicsview CONDITION QT_FEATURE_opengl
|
||||
LIBRARIES
|
||||
Qt::OpenGL
|
||||
Qt::OpenGLWidgets
|
||||
)
|
5072
tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#ifndef TST_QGRAPHICSVIEW_H
|
||||
#define TST_QGRAPHICSVIEW_H
|
||||
|
||||
// This file contains structs used in tst_qgraphicsview::scrollBarRanges.
|
||||
// Whenever these mention scrollbars or spacing it is about the number of
|
||||
// scrollbars or spacings to use as these are style dependent so that the real
|
||||
// value to add/remove has to be obtained in test run using the actual style.
|
||||
|
||||
struct ExpectedValueDescription {
|
||||
constexpr ExpectedValueDescription(int v = 0, int sbeta = 0, int sta = 0)
|
||||
: value(v)
|
||||
, scrollBarExtentsToAdd(sbeta)
|
||||
, spacingsToAdd(sta)
|
||||
{
|
||||
}
|
||||
|
||||
int value;
|
||||
// Describes how often the scrollbar widht/height has to be added to or
|
||||
// removed from the value.
|
||||
int scrollBarExtentsToAdd;
|
||||
|
||||
// Describes how often the scrollbar spacing has to be added to or removed
|
||||
// from the value if the used style has SH_ScrollView_FrameOnlyAroundContents
|
||||
// set
|
||||
int spacingsToAdd;
|
||||
};
|
||||
|
||||
// Describes how often the scroll bar width/height has to be added to/removed
|
||||
// from the according side of the sceneRect.
|
||||
struct ScrollBarCount {
|
||||
constexpr ScrollBarCount(int l = 0, int t = 0, int r = 0, int b = 0 )
|
||||
: left(l)
|
||||
, top(t)
|
||||
, right(r)
|
||||
, bottom(b)
|
||||
{
|
||||
}
|
||||
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
};
|
||||
|
||||
#endif // TST_QGRAPHICSVIEW_H
|
@ -0,0 +1,8 @@
|
||||
[initStyleOption]
|
||||
macos ci
|
||||
android
|
||||
b2qt
|
||||
# QTBUG-100930
|
||||
[updateFocusChainWhenChildDie]
|
||||
b2qt
|
||||
qnx
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicswidget Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicswidget
|
||||
SOURCES
|
||||
tst_qgraphicswidget.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|