summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-11-05 11:12:22 (GMT)
committerAndreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com>2009-11-05 11:16:26 (GMT)
commit4bf7f90a27377f439e86d6175e5e3cdebd131be0 (patch)
treed053749ab3f3028a5fc57272ea182a805829bde6
parentb2c60696dd54656c1a0d588342cc3c7beee70876 (diff)
downloadQt-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.cpp3
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp72
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;