qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View 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)

View File

@ -0,0 +1,3 @@
[layoutDirection]
ubuntu-20.04
ubuntu-22.04

View File

@ -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
)

View File

@ -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
)

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
# QTBUG-74760
[sorting]
osx

View 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
)

File diff suppressed because it is too large Load Diff

View 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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View File

@ -0,0 +1,11 @@
[scrollUpdate]
android
b2qt
[windowOpacity]
macos ci
[wheelEventPropagation]
android
[forwardTouchEvent]
android
[touchEventPropagation]
android

View File

@ -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
)

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -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
)

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>Ash_European.jpg</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because it is too large Load Diff

View File

@ -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
)

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View 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

View 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
)

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
[initStyleOption]
macos ci
android
b2qt
# QTBUG-100930
[updateFocusChainWhenChildDie]
b2qt
qnx

View File

@ -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
)

File diff suppressed because it is too large Load Diff