279 #include <QtGui/qpainter.h> |
279 #include <QtGui/qpainter.h> |
280 #include <QtGui/qscrollbar.h> |
280 #include <QtGui/qscrollbar.h> |
281 #include <QtGui/qstyleoption.h> |
281 #include <QtGui/qstyleoption.h> |
282 #include <QtGui/qinputcontext.h> |
282 #include <QtGui/qinputcontext.h> |
283 #ifdef Q_WS_X11 |
283 #ifdef Q_WS_X11 |
|
284 #include <QtGui/qpaintengine.h> |
284 #include <private/qt_x11_p.h> |
285 #include <private/qt_x11_p.h> |
285 #endif |
286 #endif |
286 |
287 |
287 #include <private/qevent_p.h> |
288 #include <private/qevent_p.h> |
288 |
289 |
542 return scrollY; |
543 return scrollY; |
543 } |
544 } |
544 |
545 |
545 /*! |
546 /*! |
546 \internal |
547 \internal |
|
548 |
|
549 Maps the given rectangle to the scene using QTransform::mapRect() |
|
550 */ |
|
551 QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const |
|
552 { |
|
553 if (dirtyScroll) |
|
554 const_cast<QGraphicsViewPrivate *>(this)->updateScroll(); |
|
555 QRectF scrolled = QRectF(rect.translated(scrollX, scrollY)); |
|
556 return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled); |
|
557 } |
|
558 |
|
559 |
|
560 /*! |
|
561 \internal |
|
562 |
|
563 Maps the given rectangle from the scene using QTransform::mapRect() |
|
564 */ |
|
565 QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const |
|
566 { |
|
567 if (dirtyScroll) |
|
568 const_cast<QGraphicsViewPrivate *>(this)->updateScroll(); |
|
569 return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY); |
|
570 } |
|
571 |
|
572 /*! |
|
573 \internal |
547 */ |
574 */ |
548 void QGraphicsViewPrivate::updateScroll() |
575 void QGraphicsViewPrivate::updateScroll() |
549 { |
576 { |
550 Q_Q(QGraphicsView); |
577 Q_Q(QGraphicsView); |
551 scrollX = qint64(-leftIndent); |
578 scrollX = qint64(-leftIndent); |
975 } |
1002 } |
976 |
1003 |
977 // Step 2) If the expose region is a simple rect and the view is only |
1004 // Step 2) If the expose region is a simple rect and the view is only |
978 // translated or scaled, search for items using |
1005 // translated or scaled, search for items using |
979 // QGraphicsScene::items(QRectF). |
1006 // QGraphicsScene::items(QRectF). |
980 bool simpleRectLookup = exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale; |
1007 bool simpleRectLookup = exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale; |
981 if (simpleRectLookup) { |
1008 if (simpleRectLookup) { |
982 return scene->items(exposedRegionSceneBounds, |
1009 return scene->items(exposedRegionSceneBounds, |
983 Qt::IntersectsItemBoundingRect, |
1010 Qt::IntersectsItemBoundingRect, |
984 Qt::AscendingOrder, viewTransform); |
1011 Qt::AscendingOrder, viewTransform); |
985 } |
1012 } |
1179 } |
1206 } |
1180 void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor) |
1207 void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor) |
1181 { |
1208 { |
1182 Q_D(QGraphicsView); |
1209 Q_D(QGraphicsView); |
1183 d->transformationAnchor = anchor; |
1210 d->transformationAnchor = anchor; |
|
1211 |
|
1212 // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse |
|
1213 // in order to have up-to-date information for centering the view. |
|
1214 if (d->transformationAnchor == AnchorUnderMouse) |
|
1215 d->viewport->setMouseTracking(true); |
1184 } |
1216 } |
1185 |
1217 |
1186 /*! |
1218 /*! |
1187 \property QGraphicsView::resizeAnchor |
1219 \property QGraphicsView::resizeAnchor |
1188 \brief how the view should position the scene when the view is resized. |
1220 \brief how the view should position the scene when the view is resized. |
1206 } |
1238 } |
1207 void QGraphicsView::setResizeAnchor(ViewportAnchor anchor) |
1239 void QGraphicsView::setResizeAnchor(ViewportAnchor anchor) |
1208 { |
1240 { |
1209 Q_D(QGraphicsView); |
1241 Q_D(QGraphicsView); |
1210 d->resizeAnchor = anchor; |
1242 d->resizeAnchor = anchor; |
|
1243 |
|
1244 // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse |
|
1245 // in order to have up-to-date information for centering the view. |
|
1246 if (d->resizeAnchor == AnchorUnderMouse) |
|
1247 d->viewport->setMouseTracking(true); |
1211 } |
1248 } |
1212 |
1249 |
1213 /*! |
1250 /*! |
1214 \property QGraphicsView::viewportUpdateMode |
1251 \property QGraphicsView::viewportUpdateMode |
1215 \brief how the viewport should update its contents. |
1252 \brief how the viewport should update its contents. |
1509 this, SLOT(updateScene(QList<QRectF>))); |
1546 this, SLOT(updateScene(QList<QRectF>))); |
1510 disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)), |
1547 disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)), |
1511 this, SLOT(updateSceneRect(QRectF))); |
1548 this, SLOT(updateSceneRect(QRectF))); |
1512 d->scene->d_func()->removeView(this); |
1549 d->scene->d_func()->removeView(this); |
1513 d->connectedToScene = false; |
1550 d->connectedToScene = false; |
|
1551 |
|
1552 if (isActiveWindow() && isVisible()) { |
|
1553 QEvent windowDeactivate(QEvent::WindowDeactivate); |
|
1554 QApplication::sendEvent(d->scene, &windowDeactivate); |
|
1555 } |
|
1556 if(hasFocus()) |
|
1557 d->scene->clearFocus(); |
1514 } |
1558 } |
1515 |
1559 |
1516 // Assign the new scene and update the contents (scrollbars, etc.)). |
1560 // Assign the new scene and update the contents (scrollbars, etc.)). |
1517 if ((d->scene = scene)) { |
1561 if ((d->scene = scene)) { |
1518 connect(d->scene, SIGNAL(sceneRectChanged(QRectF)), |
1562 connect(d->scene, SIGNAL(sceneRectChanged(QRectF)), |
1530 } |
1574 } |
1531 |
1575 |
1532 // enable touch events if any items is interested in them |
1576 // enable touch events if any items is interested in them |
1533 if (!d->scene->d_func()->allItemsIgnoreTouchEvents) |
1577 if (!d->scene->d_func()->allItemsIgnoreTouchEvents) |
1534 d->viewport->setAttribute(Qt::WA_AcceptTouchEvents); |
1578 d->viewport->setAttribute(Qt::WA_AcceptTouchEvents); |
|
1579 |
|
1580 if (isActiveWindow() && isVisible()) { |
|
1581 QEvent windowActivate(QEvent::WindowActivate); |
|
1582 QApplication::sendEvent(d->scene, &windowActivate); |
|
1583 } |
1535 } else { |
1584 } else { |
1536 d->recalculateContentSize(); |
1585 d->recalculateContentSize(); |
1537 } |
1586 } |
1538 |
1587 |
1539 d->updateInputMethodSensitivity(); |
1588 d->updateInputMethodSensitivity(); |
2556 // autoFillBackground enables scroll acceleration. |
2605 // autoFillBackground enables scroll acceleration. |
2557 widget->setAutoFillBackground(true); |
2606 widget->setAutoFillBackground(true); |
2558 } |
2607 } |
2559 |
2608 |
2560 // We are only interested in mouse tracking if items |
2609 // We are only interested in mouse tracking if items |
2561 // accept hover events or use non-default cursors. |
2610 // accept hover events or use non-default cursors or if |
2562 if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents |
2611 // AnchorUnderMouse is used as transformation or resize anchor. |
2563 || !d->scene->d_func()->allItemsUseDefaultCursor)) { |
2612 if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents |
|
2613 || !d->scene->d_func()->allItemsUseDefaultCursor)) |
|
2614 || d->transformationAnchor == AnchorUnderMouse |
|
2615 || d->resizeAnchor == AnchorUnderMouse) { |
2564 widget->setMouseTracking(true); |
2616 widget->setMouseTracking(true); |
2565 } |
2617 } |
2566 |
2618 |
2567 // enable touch events if any items is interested in them |
2619 // enable touch events if any items is interested in them |
2568 if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents) |
2620 if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents) |
2635 // Remove all popups when the scene loses focus. |
2687 // Remove all popups when the scene loses focus. |
2636 if (!d->scene->d_func()->popupWidgets.isEmpty()) |
2688 if (!d->scene->d_func()->popupWidgets.isEmpty()) |
2637 d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first()); |
2689 d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first()); |
2638 QApplication::sendEvent(d->scene, event); |
2690 QApplication::sendEvent(d->scene, event); |
2639 break; |
2691 break; |
|
2692 case QEvent::Show: |
|
2693 if (d->scene && isActiveWindow()) { |
|
2694 QEvent windowActivate(QEvent::WindowActivate); |
|
2695 QApplication::sendEvent(d->scene, &windowActivate); |
|
2696 } |
|
2697 break; |
|
2698 case QEvent::Hide: |
|
2699 // spontaneous event will generate a WindowDeactivate. |
|
2700 if (!event->spontaneous() && d->scene && isActiveWindow()) { |
|
2701 QEvent windowDeactivate(QEvent::WindowDeactivate); |
|
2702 QApplication::sendEvent(d->scene, &windowDeactivate); |
|
2703 } |
|
2704 break; |
2640 case QEvent::Leave: |
2705 case QEvent::Leave: |
2641 // ### This is a temporary fix for until we get proper mouse grab |
2706 // ### This is a temporary fix for until we get proper mouse grab |
2642 // events. activeMouseGrabberItem should be set to 0 if we lose the |
2707 // events. activeMouseGrabberItem should be set to 0 if we lose the |
2643 // mouse grab. |
2708 // mouse grab. |
2644 if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window()) |
2709 if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window()) |
3292 if (!d->backgroundPixmapExposed.isEmpty()) { |
3357 if (!d->backgroundPixmapExposed.isEmpty()) { |
3293 QPainter backgroundPainter(&d->backgroundPixmap); |
3358 QPainter backgroundPainter(&d->backgroundPixmap); |
3294 backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip); |
3359 backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip); |
3295 if (viewTransformed) |
3360 if (viewTransformed) |
3296 backgroundPainter.setTransform(viewTransform); |
3361 backgroundPainter.setTransform(viewTransform); |
3297 backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source); |
3362 #ifdef Q_WS_X11 |
|
3363 #undef X11 |
|
3364 if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11) |
|
3365 #define X11 qt_x11Data |
|
3366 #endif |
|
3367 backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source); |
3298 drawBackground(&backgroundPainter, exposedSceneRect); |
3368 drawBackground(&backgroundPainter, exposedSceneRect); |
3299 d->backgroundPixmapExposed = QRegion(); |
3369 d->backgroundPixmapExposed = QRegion(); |
3300 } |
3370 } |
3301 |
3371 |
3302 // Blit the background from the background pixmap |
3372 // Blit the background from the background pixmap |
3317 |
3387 |
3318 // Items |
3388 // Items |
3319 if (!(d->optimizationFlags & IndirectPainting)) { |
3389 if (!(d->optimizationFlags & IndirectPainting)) { |
3320 d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, |
3390 d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, |
3321 &d->exposedRegion, viewport()); |
3391 &d->exposedRegion, viewport()); |
|
3392 // Make sure the painter's world transform is restored correctly when |
|
3393 // drawing without painter state protection (DontSavePainterState). |
|
3394 // We only change the worldTransform() so there's no need to do a full-blown |
|
3395 // save() and restore(). Also note that we don't have to do this in case of |
|
3396 // IndirectPainting (the else branch), because in that case we always save() |
|
3397 // and restore() in QGraphicsScene::drawItems(). |
|
3398 if (!d->scene->d_func()->painterStateProtection) |
|
3399 painter.setWorldTransform(viewTransform); |
3322 } else { |
3400 } else { |
3323 // Find all exposed items |
3401 // Find all exposed items |
3324 bool allItems = false; |
3402 bool allItems = false; |
3325 QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform); |
3403 QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform); |
3326 if (!itemList.isEmpty()) { |
3404 if (!itemList.isEmpty()) { |