Example #1
0
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::GraphicsSceneResize), 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::GraphicsSceneResize), 1);
        QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
        QCOMPARE(c->eventCount(QEvent::GraphicsSceneResize), 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());
    }

    {
        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);
}