diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-13 07:21:52 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-05-13 07:21:52 (GMT) |
commit | 7180ccf653af6370fedc43debcfbf2386f0a4b3d (patch) | |
tree | a8364c746c9cd9045ac711b6ba05d33aa39a23fc /src/gui/graphicsview | |
parent | 50711dd7aa22052eff58431d9f4e95e1a688047e (diff) | |
parent | 2555221bbcb33e0d12e786eb0b3d08bd9260eeb7 (diff) | |
download | Qt-7180ccf653af6370fedc43debcfbf2386f0a4b3d.zip Qt-7180ccf653af6370fedc43debcfbf2386f0a4b3d.tar.gz Qt-7180ccf653af6370fedc43debcfbf2386f0a4b3d.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (35 commits)
Avoid running animation when loopCount == 0
Set the pictures for the examples of multitouch
Compile fix on Windows.
Remove an unnecessary assert.
Documentation for the Pad Navigator Example.
New Pad Nagivator example implementation.
Skip definition of wintab functions in case of QT_NO_TABLETEVENT.
Made curve tesselation be dynamically adjusted based on transform.
Modified QPainter and QPixmap benchmarks to use raster pixmaps.
Stabilize tst_QWidgetAction::visibilityUpdate
Fix compiler warning in QT_REQUIRE_VERSION
Stabilize tst_QColumnView::parentCurrentIndex
Really fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux
Fix typos in Elastic Nodes example documentation.
Made paint engine texture drawing work in GL ES 2 and updated docs.
Opt out of visual-config size checks with extension
Fix off-by-one in text layouts and widget size hints on Mac
Stabilize tst_QDockWidget::taskQTBUG_9758_undockedGeometry
Mark QFileDialog::Options as a Q_FLAGS
fix tst_QDockWidget::taskQTBUG_9758_undockedGeometry on Linux
...
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 33 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 1 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 30 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 40 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 76 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview_p.h | 33 |
6 files changed, 156 insertions, 57 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b2bdc5c..b491ab9 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1813,7 +1813,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); if (fullUpdate) - d_ptr->paintedViewBoundingRectsNeedRepaint = 1; + d_ptr->updatePaintedViewBoundingRects(/*children=*/true); // Keep the old flags to compare the diff. GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); @@ -5433,6 +5433,24 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } +void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren) +{ + if (!scene) + return; + + for (int i = 0; i < scene->d_func()->views.size(); ++i) { + QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func(); + QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport); + rect.translate(viewPrivate->dirtyScrollOffset); + viewPrivate->updateRect(rect); + } + + if (updateChildren) { + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updatePaintedViewBoundingRects(true); + } +} + // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -5636,8 +5654,9 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) // Adjust with 2 pixel margin. Notice the loss of precision // when converting to QRect. int adjust = 2; + QRectF scrollRect = !rect.isNull() ? rect : boundingRect(); QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust); - QRect irect = rect.toRect().translated(-br.x(), -br.y()); + QRect irect = scrollRect.toRect().translated(-br.x(), -br.y()); pix.scroll(dx, dy, irect); @@ -5645,11 +5664,11 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) // Translate the existing expose. foreach (QRectF exposedRect, c->exposed) - c->exposed += exposedRect.translated(dx, dy) & rect; + c->exposed += exposedRect.translated(dx, dy) & scrollRect; // Calculate exposure. QRegion exposed; - QRect r = rect.toRect(); + QRect r = scrollRect.toRect(); exposed += r; exposed -= r.translated(dx, dy); foreach (QRect rect, exposed.rects()) @@ -7132,7 +7151,11 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) // calculate their diff by mapping viewport coordinates // directly to parent coordinates. // COMBINE - QTransform viewToParentTransform = (item->d_func()->transformData->computedFullTransform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y())) + QTransform itemTransform; + if (item->d_ptr->transformData) + itemTransform = item->d_ptr->transformData->computedFullTransform(); + itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()); + QTransform viewToParentTransform = itemTransform * (item->sceneTransform() * view->viewportTransform()).inverted(); currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))); buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 569a329..e812f29 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -377,6 +377,7 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); + void updatePaintedViewBoundingRects(bool updateChildren); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7abd5f6..9b7cf12 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -290,13 +290,19 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() updateAll(false), calledEmitUpdated(false), processDirtyItemsEmitted(false), - selectionChanging(0), needSortTopLevelItems(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), stickyFocus(false), hasFocus(false), + lastMouseGrabberItemHasImplicitMouseGrab(false), + allItemsIgnoreHoverEvents(true), + allItemsUseDefaultCursor(true), + painterStateProtection(true), + sortCacheEnabled(false), + allItemsIgnoreTouchEvents(true), + selectionChanging(0), rectAdjust(2), focusItem(0), lastFocusItem(0), @@ -306,16 +312,10 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() activationRefCount(0), childExplicitActivation(0), lastMouseGrabberItem(0), - lastMouseGrabberItemHasImplicitMouseGrab(false), dragDropItem(0), enterWidget(0), lastDropAction(Qt::IgnoreAction), - allItemsIgnoreHoverEvents(true), - allItemsUseDefaultCursor(true), - painterStateProtection(true), - sortCacheEnabled(false), - style(0), - allItemsIgnoreTouchEvents(true) + style(0) { } @@ -5120,9 +5120,15 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool // Process children. if (itemHasChildren && item->d_ptr->dirtyChildren) { + const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; + if (itemClipsChildrenToShape) { + // Make sure child updates are clipped to the item's bounding rect. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->setUpdateClip(item); + } if (!dirtyAncestorContainsChildren) { dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending - && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + && itemClipsChildrenToShape; } const bool allChildrenDirty = item->d_ptr->allChildrenDirty; const bool parentIgnoresVisible = item->d_ptr->ignoreVisible; @@ -5145,6 +5151,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool } processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity); } + + if (itemClipsChildrenToShape) { + // Reset updateClip. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->setUpdateClip(0); + } } else if (wasDirtyParentSceneTransform) { item->d_ptr->invalidateChildrenSceneTransform(); } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 0a85f0e..77bf450 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -97,24 +97,36 @@ public: int lastItemCount; QRectF sceneRect; - bool hasSceneRect; - bool dirtyGrowingItemsBoundingRect; + + quint32 hasSceneRect : 1; + quint32 dirtyGrowingItemsBoundingRect : 1; + quint32 updateAll : 1; + quint32 calledEmitUpdated : 1; + quint32 processDirtyItemsEmitted : 1; + quint32 needSortTopLevelItems : 1; + quint32 holesInTopLevelSiblingIndex : 1; + quint32 topLevelSequentialOrdering : 1; + quint32 scenePosDescendantsUpdatePending : 1; + quint32 stickyFocus : 1; + quint32 hasFocus : 1; + quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1; + quint32 allItemsIgnoreHoverEvents : 1; + quint32 allItemsUseDefaultCursor : 1; + quint32 painterStateProtection : 1; + quint32 sortCacheEnabled : 1; // for compatibility + quint32 allItemsIgnoreTouchEvents : 1; + quint32 padding : 15; + QRectF growingItemsBoundingRect; void _q_emitUpdated(); QList<QRectF> updatedRects; - bool updateAll; - bool calledEmitUpdated; - bool processDirtyItemsEmitted; QPainterPath selectionArea; int selectionChanging; QSet<QGraphicsItem *> selectedItems; QVector<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; - bool needSortTopLevelItems; - bool holesInTopLevelSiblingIndex; - bool topLevelSequentialOrdering; QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions; void registerTopLevelItem(QGraphicsItem *item); @@ -125,7 +137,6 @@ public: void _q_processDirtyItems(); QSet<QGraphicsItem *> scenePosItems; - bool scenePosDescendantsUpdatePending; void setScenePosItemEnabled(QGraphicsItem *item, bool enabled); void registerScenePosItem(QGraphicsItem *item); void unregisterScenePosItem(QGraphicsItem *item); @@ -136,9 +147,6 @@ public: QBrush backgroundBrush; QBrush foregroundBrush; - quint32 stickyFocus : 1; - quint32 hasFocus : 1; - quint32 padding : 30; quint32 rectAdjust; QGraphicsItem *focusItem; QGraphicsItem *lastFocusItem; @@ -155,7 +163,6 @@ public: void removePopup(QGraphicsWidget *widget, bool itemIsDying = false); QGraphicsItem *lastMouseGrabberItem; - bool lastMouseGrabberItemHasImplicitMouseGrab; QList<QGraphicsItem *> mouseGrabberItems; void grabMouse(QGraphicsItem *item, bool implicit = false); void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false); @@ -172,8 +179,6 @@ public: QList<QGraphicsItem *> cachedItemsUnderMouse; QList<QGraphicsItem *> hoverItems; QPointF lastSceneMousePos; - bool allItemsIgnoreHoverEvents; - bool allItemsUseDefaultCursor; void enableMouseTrackingOnViews(); QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos; QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos; @@ -187,8 +192,6 @@ public: void addView(QGraphicsView *view); void removeView(QGraphicsView *view); - bool painterStateProtection; - QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters; void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); @@ -210,8 +213,6 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; - bool sortCacheEnabled; // for compatibility - void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); @@ -295,7 +296,6 @@ public: int findClosestTouchPointId(const QPointF &scenePos); void touchEventHandler(QTouchEvent *touchEvent); bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent); - bool allItemsIgnoreTouchEvents; void enableTouchEventsOnViews(); QList<QGraphicsObject *> cachedTargetItems; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 9519ca0..d2964ca 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -327,16 +327,21 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() dragMode(QGraphicsView::NoDrag), sceneInteractionAllowed(true), hasSceneRect(false), connectedToScene(false), - mousePressButton(Qt::NoButton), + useLastMouseEvent(false), identityMatrix(true), dirtyScroll(true), accelerateScrolling(true), + keepLastCenterPoint(true), + transforming(false), + handScrolling(false), + mustAllocateStyleOptions(false), + mustResizeBackgroundPixmap(true), + fullUpdatePending(true), + hasUpdateClip(false), + mousePressButton(Qt::NoButton), leftIndent(0), topIndent(0), lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), - useLastMouseEvent(false), - keepLastCenterPoint(true), alignment(Qt::AlignCenter), - transforming(false), transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor), viewportUpdateMode(QGraphicsView::MinimalViewportUpdate), optimizationFlags(0), @@ -345,14 +350,11 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() rubberBanding(false), rubberBandSelectionMode(Qt::IntersectsItemShape), #endif - handScrolling(false), handScrollMotions(0), cacheMode(0), - mustAllocateStyleOptions(false), - mustResizeBackgroundPixmap(true), + handScrollMotions(0), cacheMode(0), #ifndef QT_NO_CURSOR hasStoredOriginalCursor(false), #endif lastDragDropEvent(0), - fullUpdatePending(true), updateSceneSlotReimplementedChecked(false) { styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS); @@ -879,6 +881,52 @@ static inline void QRect_unite(QRect *rect, const QRect &other) } } +/* + Calling this function results in update rects being clipped to the item's + bounding rect. Note that updates prior to this function call is not clipped. + The clip is removed by passing 0. +*/ +void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item) +{ + Q_Q(QGraphicsView); + // We simply ignore the request if the update mode is either FullViewportUpdate + // or NoViewportUpdate; in that case there's no point in clipping anything. + if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate + || viewportUpdateMode == QGraphicsView::FullViewportUpdate) { + hasUpdateClip = false; + return; + } + + // Calculate the clip (item's bounding rect in view coordinates). + // Optimized version of: + // QRect clip = item->deviceTransform(q->viewportTransform()) + // .mapRect(item->boundingRect()).toAlignedRect(); + QRect clip; + if (item->d_ptr->itemIsUntransformable()) { + QTransform xform = item->deviceTransform(q->viewportTransform()); + clip = xform.mapRect(item->boundingRect()).toAlignedRect(); + } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) { + QRectF r(item->boundingRect()); + r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(), + item->d_ptr->sceneTransform.dy() - verticalScroll()); + clip = r.toAlignedRect(); + } else if (!q->isTransformed()) { + clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect(); + } else { + QTransform xform = item->d_ptr->sceneTransform; + xform *= q->viewportTransform(); + clip = xform.mapRect(item->boundingRect()).toAlignedRect(); + } + + if (hasUpdateClip) { + // Intersect with old clip. + updateClip &= clip; + } else { + updateClip = clip; + hasUpdateClip = true; + } +} + bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform) { if (rect.isEmpty()) @@ -909,6 +957,8 @@ bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xf viewRect.adjust(-1, -1, 1, 1); else viewRect.adjust(-2, -2, 2, 2); + if (hasUpdateClip) + viewRect &= updateClip; dirtyRegion += viewRect; } @@ -930,7 +980,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) viewport->update(); break; case QGraphicsView::BoundingRectViewportUpdate: - QRect_unite(&dirtyBoundingRect, r); + if (hasUpdateClip) + QRect_unite(&dirtyBoundingRect, r & updateClip); + else + QRect_unite(&dirtyBoundingRect, r); if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { fullUpdatePending = true; viewport->update(); @@ -938,7 +991,10 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) break; case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE case QGraphicsView::MinimalViewportUpdate: - dirtyRegion += r; + if (hasUpdateClip) + dirtyRegion += r & updateClip; + else + dirtyRegion += r; break; default: break; diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index aeff28a..7bd9ecb 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -77,11 +77,25 @@ public: QPainter::RenderHints renderHints; QGraphicsView::DragMode dragMode; - bool sceneInteractionAllowed; + + quint32 sceneInteractionAllowed : 1; + quint32 hasSceneRect : 1; + quint32 connectedToScene : 1; + quint32 useLastMouseEvent : 1; + quint32 identityMatrix : 1; + quint32 dirtyScroll : 1; + quint32 accelerateScrolling : 1; + quint32 keepLastCenterPoint : 1; + quint32 transforming : 1; + quint32 handScrolling : 1; + quint32 mustAllocateStyleOptions : 1; + quint32 mustResizeBackgroundPixmap : 1; + quint32 fullUpdatePending : 1; + quint32 hasUpdateClip : 1; + quint32 padding : 18; + QRectF sceneRect; - bool hasSceneRect; void updateLastCenterPoint(); - bool connectedToScene; qint64 horizontalScroll() const; qint64 verticalScroll() const; @@ -89,6 +103,7 @@ public: QRectF mapRectToScene(const QRect &rect) const; QRectF mapRectFromScene(const QRectF &rect) const; + QRect updateClip; QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; @@ -98,26 +113,20 @@ public: QPoint dirtyScrollOffset; Qt::MouseButton mousePressButton; QTransform matrix; - bool identityMatrix; qint64 scrollX, scrollY; - bool dirtyScroll; void updateScroll(); - bool accelerateScrolling; qreal leftIndent; qreal topIndent; // Replaying mouse events QMouseEvent lastMouseEvent; - bool useLastMouseEvent; void replayLastMouseEvent(); void storeMouseEvent(QMouseEvent *event); void mouseMoveEventHandler(QMouseEvent *event); QPointF lastCenterPoint; - bool keepLastCenterPoint; Qt::Alignment alignment; - bool transforming; QGraphicsView::ViewportAnchor transformationAnchor; QGraphicsView::ViewportAnchor resizeAnchor; @@ -131,20 +140,17 @@ public: bool rubberBanding; Qt::ItemSelectionMode rubberBandSelectionMode; #endif - bool handScrolling; int handScrollMotions; QGraphicsView::CacheMode cacheMode; QVector<QStyleOptionGraphicsItem> styleOptions; - bool mustAllocateStyleOptions; QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems); void freeStyleOptionsArray(QStyleOptionGraphicsItem *array); QBrush backgroundBrush; QBrush foregroundBrush; QPixmap backgroundPixmap; - bool mustResizeBackgroundPixmap; QRegion backgroundPixmapExposed; #ifndef QT_NO_CURSOR @@ -161,7 +167,6 @@ public: QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const; QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const; - bool fullUpdatePending; QRegion dirtyRegion; QRect dirtyBoundingRect; void processPendingUpdates(); @@ -192,6 +197,8 @@ public: #endif } + void setUpdateClip(QGraphicsItem *); + inline bool updateRectF(const QRectF &rect) { if (rect.isEmpty()) |