diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-11-05 11:12:22 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-11-05 11:16:26 (GMT) |
commit | 4bf7f90a27377f439e86d6175e5e3cdebd131be0 (patch) | |
tree | d053749ab3f3028a5fc57272ea182a805829bde6 | |
parent | b2c60696dd54656c1a0d588342cc3c7beee70876 (diff) | |
download | Qt-4bf7f90a27377f439e86d6175e5e3cdebd131be0.zip Qt-4bf7f90a27377f439e86d6175e5e3cdebd131be0.tar.gz Qt-4bf7f90a27377f439e86d6175e5e3cdebd131be0.tar.bz2 |
Always set a clip on the painter in QGraphicsView.
This allows items to check painter->clipRegion() to find out what the
imposed clip is, in order to cull elements that don't need to be
painted. This is an alternative approach to getting the same
information from QStyleOptionGraphicsItem::exposedRect. It's better
because it's a pull operation, but it's slightly worse because it
doesn't include the complete system clip, and because QRegion has
integer resolution only (whereas QGraphicsItem's coordinate uses
qreal.
A better approach may be to access QPainter's combined clip region;
this option is open for future versions of Qt.
Original patch by Warwick (which is why he's on reviewed-by), but the
patch was modified to operate in device instead of logical coordinates.
Reviewed-by: jasplin
Reviewed-by: Warwick Allison
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 72 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index c88f678..d1dd26f 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3252,10 +3252,13 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // Determine the exposed region d->exposedRegion = event->region(); + if (d->exposedRegion.isEmpty()) + d->exposedRegion = viewport()->rect(); QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect(); // Set up the painter QPainter painter(viewport()); + painter.setClipRect(event->rect(), Qt::IntersectClip); #ifndef QT_NO_RUBBERBAND if (d->rubberBanding && !d->rubberBandRect.isEmpty()) painter.save(); diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index f07453c..9c6aa39 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -217,6 +217,7 @@ private slots: void update(); void inputMethodSensitivity(); void inputContextReset(); + void defaultClipIntersectToView(); // task specific tests below me void task172231_untransformableItems(); @@ -3692,6 +3693,77 @@ void tst_QGraphicsView::inputContextReset() QCOMPARE(inputContext.resets, 0); } +class ViewClipTester : public QGraphicsView +{ +public: + ViewClipTester(QGraphicsScene *scene = 0) + : QGraphicsView(scene) + { } + QRegion clipRegion; + +protected: + void drawBackground(QPainter *painter, const QRectF &rect) + { + clipRegion = painter->clipRegion(); + } +}; + +class ItemClipTester : public QGraphicsRectItem +{ +public: + ItemClipTester() : QGraphicsRectItem(0, 0, 20, 20) + { + setBrush(Qt::blue); + } + QRegion clipRegion; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) + { + clipRegion = painter->clipRegion(); + QGraphicsRectItem::paint(painter, option, widget); + } +}; + +void tst_QGraphicsView::defaultClipIntersectToView() +{ + QGraphicsScene scene; + ItemClipTester *tester = new ItemClipTester; + scene.addItem(tester); + + ViewClipTester view(&scene); + view.setAlignment(Qt::AlignTop | Qt::AlignLeft); + view.setFrameStyle(0); + view.resize(200, 200); + view.show(); + QTRY_COMPARE(QApplication::activeWindow(), (QWidget *)&view); + + QRect viewRect(0, 0, 200, 200); + QCOMPARE(view.clipRegion, QRegion(viewRect)); + QCOMPARE(tester->clipRegion, QRegion(viewRect)); + + view.viewport()->update(0, 0, 5, 5); + view.viewport()->update(10, 10, 5, 5); + qApp->processEvents(); + viewRect = QRect(0, 0, 15, 15); + QCOMPARE(view.clipRegion, QRegion(viewRect)); + QCOMPARE(tester->clipRegion, QRegion(viewRect)); + + view.scale(2, 2); + qApp->processEvents(); + + viewRect.moveTop(-viewRect.height()); + viewRect = QRect(0, 0, 100, 100); + QCOMPARE(view.clipRegion, QRegion(viewRect)); + QCOMPARE(tester->clipRegion, QRegion(viewRect)); + + view.viewport()->update(0, 0, 5, 5); + view.viewport()->update(10, 10, 5, 5); + qApp->processEvents(); + viewRect = QRect(0, 0, 8, 8); + QCOMPARE(view.clipRegion, QRegion(viewRect)); + QCOMPARE(tester->clipRegion, QRegion(viewRect)); +} + void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() { QGraphicsView view; |