--- a/src/gui/graphicsview/qgraphicsscene.cpp Mon Mar 15 12:43:09 2010 +0200
+++ b/src/gui/graphicsview/qgraphicsscene.cpp Thu Apr 08 14:19:33 2010 +0300
@@ -251,6 +251,7 @@
#endif
#include <private/qgraphicseffect_p.h>
#include <private/qgesturemanager_p.h>
+#include <private/qpathclipper_p.h>
// #define GESTURE_DEBUG
#ifndef GESTURE_DEBUG
@@ -372,7 +373,10 @@
}
}
} else {
- updateAll = false;
+ if (views.isEmpty()) {
+ updateAll = false;
+ return;
+ }
for (int i = 0; i < views.size(); ++i)
views.at(i)->d_func()->processPendingUpdates();
// It's important that we update all views before we dispatch, hence two for-loops.
@@ -797,7 +801,8 @@
// do it ourselves.
if (item) {
for (int i = 0; i < views.size(); ++i)
- views.at(i)->inputContext()->reset();
+ if (views.at(i)->inputContext())
+ views.at(i)->inputContext()->reset();
}
}
#endif //QT_NO_IM
@@ -4280,6 +4285,7 @@
if (!subPix.isNull()) {
// Blit the subpixmap into the main pixmap.
pixmapPainter.begin(pix);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
pixmapPainter.setClipRegion(pixmapExposed);
pixmapPainter.drawPixmap(br.topLeft(), subPix);
pixmapPainter.end();
@@ -4445,6 +4451,8 @@
}
// Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
+ // If the world transform is rotated we always recreate the cache to avoid
+ // wrong blending.
bool pixModified = false;
QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
bool invertable = true;
@@ -4452,7 +4460,9 @@
if (invertable)
diff *= painter->worldTransform();
deviceData->lastTransform = painter->worldTransform();
- if (!invertable || diff.type() > QTransform::TxTranslate) {
+ if (!invertable
+ || diff.type() > QTransform::TxTranslate
+ || painter->worldTransform().type() > QTransform::TxScale) {
pixModified = true;
itemCache->allExposed = true;
itemCache->exposed.clear();
@@ -4603,6 +4613,7 @@
if (!unpolishedItems.isEmpty())
_q_polishItems();
+ updateAll = false;
QRectF exposedSceneRect;
if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
@@ -4630,7 +4641,7 @@
return; // Item has neither contents nor children!(?)
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
return;
@@ -4673,7 +4684,8 @@
if (widget)
item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
viewBoundingRect.adjust(-1, -1, 1, 1);
- drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty();
+ drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
+ : !viewBoundingRect.normalized().isEmpty();
if (!drawItem) {
if (!itemHasChildren)
return;
@@ -4707,31 +4719,18 @@
if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
&& sourced->lastEffectTransform != painter->worldTransform())
{
- bool unclipped = false;
if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
&& painter->worldTransform().type() <= QTransform::TxTranslate)
{
- QRectF itemRect = item->boundingRect();
- if (!item->d_ptr->children.isEmpty())
- itemRect |= item->childrenBoundingRect();
-
- QRectF oldSourceRect = sourced->lastEffectTransform.mapRect(itemRect);
- QRectF newSourceRect = painter->worldTransform().mapRect(itemRect);
-
- QRect oldEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), oldSourceRect);
- QRect newEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), newSourceRect);
-
- QRect deviceRect(0, 0, painter->device()->width(), painter->device()->height());
- if (deviceRect.contains(oldEffectRect) && deviceRect.contains(newEffectRect)) {
- sourced->setCachedOffset(newEffectRect.topLeft());
- unclipped = true;
- }
+ QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
+ QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
+
+ sourced->setCachedOffset(effectRect.topLeft());
+ } else {
+ sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
}
sourced->lastEffectTransform = painter->worldTransform();
-
- if (!unclipped)
- sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
}
item->d_ptr->graphicsEffect->draw(painter);
@@ -4750,7 +4749,7 @@
qreal opacity, const QTransform *effectTransform,
bool wasDirtyParentSceneTransform, bool drawItem)
{
- const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
const bool itemHasChildren = !item->d_ptr->children.isEmpty();
@@ -4765,7 +4764,12 @@
painter->setWorldTransform(*transformPtr * *effectTransform);
else
painter->setWorldTransform(*transformPtr);
- painter->setClipPath(item->shape(), Qt::IntersectClip);
+ QRectF clipRect;
+ const QPainterPath clipPath(item->shape());
+ if (QPathClipper::pathToRect(clipPath, &clipRect))
+ painter->setClipRect(clipRect, Qt::IntersectClip);
+ else
+ painter->setClipPath(clipPath, Qt::IntersectClip);
}
// Draw children behind
@@ -4801,8 +4805,14 @@
painter->setWorldTransform(*transformPtr);
}
- if (itemClipsToShape)
- painter->setClipPath(item->shape(), Qt::IntersectClip);
+ if (itemClipsToShape) {
+ QRectF clipRect;
+ const QPainterPath clipPath(item->shape());
+ if (QPathClipper::pathToRect(clipPath, &clipRect))
+ painter->setClipRect(clipRect, Qt::IntersectClip);
+ else
+ painter->setClipPath(clipPath, Qt::IntersectClip);
+ }
painter->setOpacity(opacity);
if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
@@ -4980,7 +4990,8 @@
}
const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001;
+ const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
+ && QGraphicsItemPrivate::isOpacityNull(opacity);
if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
resetDirtyItem(item, /*recursive=*/itemHasChildren);
return;
@@ -5115,6 +5126,8 @@
}
/*!
+ \obsolete
+
Paints the given \a items using the provided \a painter, after the
background has been drawn, and before the foreground has been
drawn. All painting is done in \e scene coordinates. Before
@@ -5137,7 +5150,7 @@
\snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
- \obsolete Since Qt 4.6, this function is not called anymore unless
+ Since Qt 4.6, this function is not called anymore unless
the QGraphicsView::IndirectPainting flag is given as an Optimization
flag.
@@ -5153,6 +5166,7 @@
if (!d->unpolishedItems.isEmpty())
d->_q_polishItems();
+ d->updateAll = false;
QTransform viewTransform = painter->worldTransform();
Q_UNUSED(options);
@@ -5692,8 +5706,15 @@
item->d_ptr->acceptedTouchBeginEvent = true;
bool res = sendTouchBeginEvent(item, &touchEvent)
&& touchEvent.isAccepted();
- if (!res)
+ if (!res) {
+ // forget about these touch points, we didn't handle them
+ for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
+ itemForTouchPointId.remove(touchPoint.id());
+ sceneCurrentTouchPoints.remove(touchPoint.id());
+ }
ignoreSceneTouchEvent = false;
+ }
break;
}
default:
@@ -5884,13 +5905,21 @@
QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
QList<QGraphicsObject *> result;
for (int j = 0; j < items.size(); ++j) {
- QGraphicsObject *item = items.at(j)->toGraphicsObject();
- if (!item)
- continue;
- QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
- if (d->gestureContext.contains(gestureType)) {
- result.append(item);
+ QGraphicsItem *item = items.at(j);
+
+ // Check if the item is blocked by a modal panel and use it as
+ // a target instead of this item.
+ (void) item->isBlockedByModalPanel(&item);
+
+ if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
+ QGraphicsItemPrivate *d = item->d_func();
+ if (d->gestureContext.contains(gestureType)) {
+ result.append(itemobj);
+ }
}
+ // Don't propagate through panels.
+ if (item->isPanel())
+ break;
}
DEBUG() << "QGraphicsScenePrivate::getGestureTargets:"
<< gesture << result;