diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-10 07:32:52 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-10 07:32:52 (GMT) |
commit | 6fa05b234e2bb6fdabcaf5eb4550b0b32a434fd1 (patch) | |
tree | 101e6b16cec0998ffafc0f5e89ebc20527588b18 | |
parent | e54341b9677d2708c2db286ad6548069d7af6e57 (diff) | |
parent | 4225a25efb46c9f5a3fbb8197286663b8cb21e27 (diff) | |
download | Qt-6fa05b234e2bb6fdabcaf5eb4550b0b32a434fd1.zip Qt-6fa05b234e2bb6fdabcaf5eb4550b0b32a434fd1.tar.gz Qt-6fa05b234e2bb6fdabcaf5eb4550b0b32a434fd1.tar.bz2 |
Merge branch '4.7' of git://scm.dev.nokia.troll.no/qt/qt-water-team
* '4.7' of git://scm.dev.nokia.troll.no/qt/qt-water-team:
Fixes to how resize event and layout request are posted.
-rw-r--r-- | src/gui/graphicsview/qgraphicslayout.cpp | 14 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.cpp | 16 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget.h | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.cpp | 14 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicswidget_p.h | 5 | ||||
-rw-r--r-- | tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp | 192 |
6 files changed, 201 insertions, 42 deletions
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index b37dfd4..f983955 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -269,18 +269,8 @@ void QGraphicsLayout::activate() return; Q_ASSERT(!parentItem->isLayout()); - if (QGraphicsLayout::instantInvalidatePropagation()) { - QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem); - if (!parentWidget->parentLayoutItem()) { - // we've reached the topmost widget, resize it - bool wasResized = parentWidget->testAttribute(Qt::WA_Resized); - parentWidget->resize(parentWidget->size()); - parentWidget->setAttribute(Qt::WA_Resized, wasResized); - } - - setGeometry(parentItem->contentsRect()); // relayout children - } else { - setGeometry(parentItem->contentsRect()); // relayout children + setGeometry(parentItem->contentsRect()); // relayout children + if (!QGraphicsLayout::instantInvalidatePropagation()) { parentLayoutItem()->updateGeometry(); } } diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 7048fcc..965b1b34 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -404,14 +404,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) emit widthChanged(); if (oldSize.height() != newGeom.size().height()) emit heightChanged(); - QGraphicsLayout *lay = wd->layout; - if (QGraphicsLayout::instantInvalidatePropagation()) { - if (!lay || lay->isActivated()) { - QApplication::sendEvent(this, &re); - } - } else { - QApplication::sendEvent(this, &re); - } + QApplication::sendEvent(this, &re); } } @@ -1090,8 +1083,11 @@ void QGraphicsWidget::updateGeometry() * When the event is received, it will start flowing all the way down to the leaf * widgets in one go. This will make a relayout flicker-free. */ - if (QGraphicsLayout::instantInvalidatePropagation()) - QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest)); + if (QGraphicsLayout::instantInvalidatePropagation()) { + Q_D(QGraphicsWidget); + ++d->refCountInvokeRelayout; + QMetaObject::invokeMethod(this, "_q_relayout", Qt::QueuedConnection); + } } if (!QGraphicsLayout::instantInvalidatePropagation()) { bool wasResized = testAttribute(Qt::WA_Resized); diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 063be2d..5085817 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -234,6 +234,8 @@ protected: private: Q_DISABLE_COPY(QGraphicsWidget) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget) + Q_PRIVATE_SLOT(d_func(), void _q_relayout()) + friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsView; diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 059051e..dc0f7c0 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -232,6 +232,18 @@ void QGraphicsWidgetPrivate::resolveLayoutDirection() } } +/* private slot */ +void QGraphicsWidgetPrivate::_q_relayout() +{ + --refCountInvokeRelayout; + if (refCountInvokeRelayout == 0) { + Q_Q(QGraphicsWidget); + bool wasResized = q->testAttribute(Qt::WA_Resized); + q->resize(q->size()); // this will restrict the size + q->setAttribute(Qt::WA_Resized, wasResized); + } +} + QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const { Q_Q(const QGraphicsWidget); @@ -897,4 +909,6 @@ void QGraphicsWidgetPrivate::setGeometryFromSetPos() QT_END_NAMESPACE +#include "moc_qgraphicswidget.cpp" + #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 398abc3..6ea2586 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -81,6 +81,7 @@ public: polished(0), inSetPos(0), autoFillBackground(0), + refCountInvokeRelayout(0), focusPolicy(Qt::NoFocus), focusNext(0), focusPrev(0), @@ -106,6 +107,7 @@ public: QGraphicsLayout *layout; void setLayoutDirection_helper(Qt::LayoutDirection direction); void resolveLayoutDirection(); + void _q_relayout(); // Style QPalette palette; @@ -179,11 +181,14 @@ public: return false; return (attributes & (1 << bit)) != 0; } + // 32 bits + quint32 refCountInvokeRelayout : 16; quint32 attributes : 10; quint32 inSetGeometry : 1; quint32 polished: 1; quint32 inSetPos : 1; quint32 autoFillBackground : 1; + quint32 padding : 2; // feel free to use // Focus Qt::FocusPolicy focusPolicy; diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index 9411f97..cd91008 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -63,6 +63,12 @@ private slots: void automaticReparenting(); void verifyActivate(); void invalidate(); + void moveAndResize_data(); + void moveAndResize(); + void moveAndResizeWidgetInWidget_data(); + void moveAndResizeWidgetInWidget(); + void changingMinimumSize_data(); + void changingMinimumSize(); void invalidateAndMove_data(); void invalidateAndMove(); void constructors(); @@ -445,7 +451,7 @@ void tst_QGraphicsLayout::invalidate() QCoreApplication::sendPostedEvents(); QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); - QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::GraphicsSceneResize), 1); QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); QCOMPARE(a->functionCount[SetGeometry], 1); @@ -481,30 +487,18 @@ void tst_QGraphicsLayout::invalidate() QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); QCoreApplication::sendPostedEvents(); - QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(a->eventCount(QEvent::GraphicsSceneResize), 1); QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); - QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::GraphicsSceneResize), 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); + 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); @@ -557,7 +551,165 @@ void tst_QGraphicsLayout::invalidate() QGraphicsLayout::setInstantInvalidatePropagation(false); } +void tst_QGraphicsLayout::changingMinimumSize_data() +{ + QTest::addColumn<bool>("instantInvalidatePropagation"); + QTest::newRow("Without instantInvalidatePropagation") << false; + QTest::newRow("With instantInvalidatePropagation") << true; +} +void tst_QGraphicsLayout::changingMinimumSize() +{ + QFETCH(bool, instantInvalidatePropagation); + QGraphicsLayout::setInstantInvalidatePropagation(instantInvalidatePropagation); + QGraphicsWidget *widget = new QGraphicsWidget; + qApp->processEvents(); + widget->setMinimumSize(300,300); + qApp->processEvents(); + QCOMPARE(widget->size(), QSizeF(300,300)); + QGraphicsLayout::setInstantInvalidatePropagation(false); +} + +struct WidgetToTestResizeEvents : public QGraphicsWidget +{ + virtual void resizeEvent ( QGraphicsSceneResizeEvent * event ) + { + QGraphicsWidget::resizeEvent(event); + resizeEventCalled = true; + } + + bool resizeEventCalled; +}; +void tst_QGraphicsLayout::moveAndResizeWidgetInWidget_data() +{ + QTest::addColumn<bool>("instantInvalidatePropagation"); + + QTest::newRow("Without instantInvalidatePropagation") << false; + QTest::newRow("With instantInvalidatePropagation") << true; +} +void tst_QGraphicsLayout::moveAndResizeWidgetInWidget() +{ + QFETCH(bool, instantInvalidatePropagation); + + QGraphicsLayout::setInstantInvalidatePropagation(instantInvalidatePropagation); + QGraphicsScene scene; + + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); + layout->setContentsMargins(0,0,0,0); + WidgetToTestResizeEvents *innerWidget = new WidgetToTestResizeEvents; + QGraphicsLinearLayout *innerLayout = new QGraphicsLinearLayout(innerWidget); + innerLayout->setContentsMargins(0,0,0,0); + QCOMPARE(widget->maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)); + layout->addItem(innerWidget); + widget->setMinimumSize(1,1); + widget->setPreferredSize(1000,1000); + widget->setMaximumSize(2000,2000); + widget->resize(widget->preferredSize()); + innerWidget->setMinimumSize(1,1); + qApp->processEvents(); + innerWidget->resizeEventCalled = false; + + QCOMPARE(widget->size(), QSizeF(1000, 1000)); + QCOMPARE(layout->geometry().size(), QSizeF(1000, 1000)); + QCOMPARE(innerWidget->size(), QSizeF(1000, 1000)); + + innerLayout->invalidate(); + widget->setMaximumHeight(500); + widget->setX(1); + qApp->processEvents(); + QCOMPARE(widget->size(), QSizeF(1000, 500)); + QCOMPARE(innerWidget->size(), QSizeF(1000, 500)); + QVERIFY(innerWidget->resizeEventCalled); +} +void tst_QGraphicsLayout::moveAndResize_data() +{ + QTest::addColumn<bool>("instantInvalidatePropagation"); + QTest::addColumn<bool>("insideLayout"); + QTest::addColumn<bool>("insideLayoutInLayout"); + QTest::addColumn<bool>("insideWidget"); + QTest::newRow("Without instantInvalidatePropagation") << false << false << false << false; + QTest::newRow("With instantInvalidatePropagation") << true << false << false << false; + QTest::newRow("Without instantInvalidatePropagation, inside widget with no layout") << false << false << false << true; + QTest::newRow("With instantInvalidatePropagation, inside widget with no layout") << true << false << false << true; + QTest::newRow("Without instantInvalidatePropagation, inside widget with layout") << false << true << false << true; + QTest::newRow("With instantInvalidatePropagation, inside widget with layout") << true << true << false << true; + QTest::newRow("Without instantInvalidatePropagation, inside widget with layout in layout") << false << true << true << true; + QTest::newRow("With instantInvalidatePropagation, inside widget with layout in layout") << true << true << true << true; + +} +void tst_QGraphicsLayout::moveAndResize() +{ + QFETCH(bool, instantInvalidatePropagation); + QFETCH(bool, insideLayout); + QFETCH(bool, insideLayoutInLayout); + QFETCH(bool, insideWidget); + QGraphicsLayout::setInstantInvalidatePropagation(instantInvalidatePropagation); + QGraphicsScene scene; + + WidgetToTestResizeEvents *widget = new WidgetToTestResizeEvents; + + /* Setup its parent if we want them */ + QGraphicsWidget *parent = NULL; + if (insideWidget) + parent = new QGraphicsWidget; + if (insideLayout) { + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(parent); + QGraphicsLinearLayout *innerLayout = NULL; + if (insideLayoutInLayout) { + innerLayout = new QGraphicsLinearLayout; + layout->addItem(innerLayout); + innerLayout->addItem(widget); + } else + layout->addItem(widget); + } else if (insideWidget) { + widget->setParentItem(parent); + } + + new QGraphicsLinearLayout(widget); + widget->setGeometry(0,0,100,100); + qApp->processEvents(); + widget->resizeEventCalled = false; + + /* Force it grow by changing the minimum size */ + widget->setMinimumSize(200,200); + qApp->processEvents(); + qApp->processEvents(); + qApp->processEvents(); + QCOMPARE(widget->size(), QSizeF(200,200)); + QVERIFY(widget->resizeEventCalled); + widget->resizeEventCalled = false; + + /* Call setPos followed by a resize. We should get a resize event */ + widget->setPos(10,10); + widget->resize(300,300); + qApp->processEvents(); + QVERIFY(widget->resizeEventCalled); + widget->resizeEventCalled = false; + + /* Check that just calling setGeometry gives us a resize event */ + widget->setGeometry(10,10, 400, 400); + qApp->processEvents(); + QVERIFY(widget->resizeEventCalled); + widget->resizeEventCalled = false; + + /* Now call setPos followed by increasing the size using setGeometry,*/ + widget->setPos(30,30); + widget->setGeometry(10,10, 500, 500); + qApp->processEvents(); + QVERIFY(widget->resizeEventCalled); + widget->resizeEventCalled = false; + + /* Now call setPos followed by increasing the minimum size, to force it to grow */ + widget->setMinimumSize(600,600); + widget->setPos(30,30); + qApp->processEvents(); + QCOMPARE(widget->size(), QSizeF(600,600)); + QVERIFY(widget->resizeEventCalled); + widget->resizeEventCalled = false; + + QGraphicsLayout::setInstantInvalidatePropagation(false); +} void tst_QGraphicsLayout::invalidateAndMove_data() { QTest::addColumn<bool>("instantInvalidatePropagation"); |