diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-05-11 17:06:12 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-05-21 13:19:04 (GMT) |
commit | 1a0c51ffed4f7d86620b00adc3e22d044deef0c0 (patch) | |
tree | c0421de53e7eb766c7ba11e48fc5b3301eb44b38 /tests/auto/qgraphicsitem | |
parent | abc0bd321356907dafc4a5cbca57a335a9f6ae3e (diff) | |
download | Qt-1a0c51ffed4f7d86620b00adc3e22d044deef0c0.zip Qt-1a0c51ffed4f7d86620b00adc3e22d044deef0c0.tar.gz Qt-1a0c51ffed4f7d86620b00adc3e22d044deef0c0.tar.bz2 |
Fixes QGraphicsItem::scroll issues
The biggest and most important issue was that QGraphicsItem::scroll
always accelerated the scroll without taking overlapping items or
opacity into account, which caused drawing artifacts. We can only do
accelerated scrolling if the item is opaque and not overlapped by
other items. There's no (sane) way to detect whether an item is
opaque or not (similar to Qt::WA_OpaquePaintEvent), which means we
cannot support accelerated scrolling unless the item is cached into
a pixmap (QGraphicsItem::setCacheMode).
The second issue was that QStyleOptionGraphicsItem::exposedRect always
contained the whole boundinRect() after an accelerated scroll
(even with the QGraphicsItem::ItemUsesExtendedStyleOption flag enabled).
Auto test included.
Task-number: QTBUG-8378, QTBUG-7703
Reviewed-by: yoann
Diffstat (limited to 'tests/auto/qgraphicsitem')
-rw-r--r-- | tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 5a5a821..300afc3 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -236,11 +236,12 @@ public: QRectF boundingRect() const { return br; } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + void paint(QPainter *painter, const QStyleOptionGraphicsItem *o, QWidget *) { hints = painter->renderHints(); painter->setBrush(brush); painter->drawRect(boundingRect()); + lastExposedRect = o->exposedRect; ++repaints; } @@ -250,10 +251,19 @@ public: return QGraphicsItem::sceneEvent(event); } + void reset() + { + events.clear(); + hints = QPainter::RenderHints(0); + repaints = 0; + lastExposedRect = QRectF(); + } + QList<QEvent::Type> events; QPainter::RenderHints hints; int repaints; QRectF br; + QRectF lastExposedRect; QBrush brush; }; @@ -430,6 +440,7 @@ private slots: void scenePosChange(); void updateMicroFocus(); void textItem_shortcuts(); + void scroll(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -10155,6 +10166,78 @@ void tst_QGraphicsItem::textItem_shortcuts() QTRY_COMPARE(item->textCursor().selectedText(), item->toPlainText()); } +void tst_QGraphicsItem::scroll() +{ + // Create two overlapping rectangles in the scene: + // +-------+ + // | | <- item1 + // | +-------+ + // | | | + // +---| | <- item2 + // | | + // +-------+ + + EventTester *item1 = new EventTester; + item1->br = QRectF(0, 0, 200, 200); + item1->brush = Qt::red; + item1->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); + + EventTester *item2 = new EventTester; + item2->br = QRectF(0, 0, 200, 200); + item2->brush = Qt::blue; + item2->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption); + item2->setPos(100, 100); + + QGraphicsScene scene(0, 0, 300, 300); + scene.addItem(item1); + scene.addItem(item2); + + MyGraphicsView view(&scene); + view.setFrameStyle(0); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.repaints > 0); + + view.reset(); + item1->reset(); + item2->reset(); + + const QRectF item1BoundingRect = item1->boundingRect(); + const QRectF item2BoundingRect = item2->boundingRect(); + + // Scroll item1: + // Item1 should get full exposure + // Item2 should get exposure for the part that overlaps item1. + item1->scroll(0, -10); + QTRY_VERIFY(view.repaints > 0); + QCOMPARE(item1->lastExposedRect, item1BoundingRect); + + QRectF expectedItem2Expose = item2BoundingRect; + // NB! Adjusted by 2 pixels for antialiasing + expectedItem2Expose &= item1->mapRectToItem(item2, item1BoundingRect.adjusted(-2, -2, 2, 2)); + QCOMPARE(item2->lastExposedRect, expectedItem2Expose); + + // Enable ItemCoordinateCache on item1. + view.reset(); + item1->setCacheMode(QGraphicsItem::ItemCoordinateCache); + QTRY_VERIFY(view.repaints > 0); + view.reset(); + item1->reset(); + item2->reset(); + + // Scroll item1: + // Item1 should only get expose for the newly exposed area (accelerated scroll). + // Item2 should get exposure for the part that overlaps item1. + item1->scroll(0, -10, QRectF(50, 50, 100, 100)); + QTRY_VERIFY(view.repaints > 0); + QCOMPARE(item1->lastExposedRect, QRectF(50, 140, 100, 10)); + + expectedItem2Expose = item2BoundingRect; + // NB! Adjusted by 2 pixels for antialiasing + expectedItem2Expose &= item1->mapRectToItem(item2, QRectF(50, 50, 100, 100).adjusted(-2, -2, 2, 2)); + QCOMPARE(item2->lastExposedRect, expectedItem2Expose); +} + void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() { struct Item : public QGraphicsTextItem |