From 6c01a596f9b2bf51add0a3f69faf15435f041b4f Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 31 Aug 2009 18:33:17 +1000 Subject: Revive animated zooming. Now uses scale for transition while static uses zoomFactor. QFxPaintedItem assists by being able to freeze the cache - useful anywhere that dirty cache data is okay to use (i.e. during brief animations). --- demos/declarative/webbrowser/webbrowser.qml | 68 +++++++++++++++++++- src/declarative/fx/qfxpainteditem.cpp | 96 +++++++++++++++++------------ src/declarative/fx/qfxpainteditem.h | 2 + src/declarative/fx/qfxpainteditem_p.h | 3 +- src/declarative/fx/qfxwebview.cpp | 34 ++++++++-- src/declarative/fx/qfxwebview.h | 7 ++- 6 files changed, 159 insertions(+), 51 deletions(-) diff --git a/demos/declarative/webbrowser/webbrowser.qml b/demos/declarative/webbrowser/webbrowser.qml index 2cd9f57..4c4ad7c 100644 --- a/demos/declarative/webbrowser/webbrowser.qml +++ b/demos/declarative/webbrowser/webbrowser.qml @@ -190,7 +190,7 @@ Item { } url: fixUrl(WebBrowser.urlString) - smooth: !Flick.moving + smooth: false fillColor: "white" focus: true @@ -200,9 +200,71 @@ Item { onUrlChanged: { if (url != null) { WebBrowser.urlString = url.toString(); } } onDoubleClick: { heuristicZoom(clickX,clickY) } - onZooming: { Flick.viewportX=Math.min(MyWebView.width-Flick.width,Math.max(0,centerX-Flick.width/2)); - Flick.viewportY=Math.max(0,Math.min(MyWebView.height-Flick.height,centerY-Flick.height/2)) } + SequentialAnimation { + id: QuickZoom + PropertyAction { + target: MyWebView + property: "renderingEnabled" + value: false + } + ParallelAnimation { + NumberAnimation { + id: ScaleAnim + target: MyWebView + property: "scale" + from: 1 + to: 0 // set before calling + easing: "easeInOutQuad" + duration: 200 + } + NumberAnimation { + id: FlickVX + target: Flick + property: "viewportX" + easing: "easeInOutQuad" + duration: 200 + from: 0 // set before calling + to: 0 // set before calling + } + NumberAnimation { + id: FlickVY + target: Flick + property: "viewportY" + easing: "easeInOutQuad" + duration: 200 + from: 0 // set before calling + to: 0 // set before calling + } + } + PropertyAction { + target: MyWebView + property: "scale" + value: 1.0 + } + PropertyAction { + id: FinalZoom + target: MyWebView + property: "zoomFactor" + } + PropertyAction { + target: MyWebView + property: "renderingEnabled" + value: true + } + } + onZooming: { + if (centerX) { + sc = zoom/zoomFactor; + ScaleAnim.to = sc; + FlickVX.from = Flick.viewportX + FlickVX.to = Math.min(Math.max(0,centerX-Flick.width/2),MyWebView.width*sc-Flick.width) + FlickVY.from = Flick.viewportY + FlickVY.to = Math.min(Math.max(0,centerY-Flick.height/2),MyWebView.height*sc-Flick.height) + FinalZoom.value = zoom + QuickZoom.start() + } + } } Rectangle { id: WebViewTint diff --git a/src/declarative/fx/qfxpainteditem.cpp b/src/declarative/fx/qfxpainteditem.cpp index 13f7e58..695236d 100644 --- a/src/declarative/fx/qfxpainteditem.cpp +++ b/src/declarative/fx/qfxpainteditem.cpp @@ -187,6 +187,15 @@ void QFxPaintedItem::init() connect(this,SIGNAL(visibleChanged()),this,SLOT(clearCache())); } +void QFxPaintedItem::setCacheFrozen(bool frozen) +{ + Q_D(QFxPaintedItem); + if (d->cachefrozen == frozen) + return; + d->cachefrozen = frozen; + // XXX clear cache? +} + /*! \reimp */ @@ -222,14 +231,16 @@ void QFxPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidge QRect area = d->imagecache[i]->area; if (topaint.contains(area)) { QRectF target(area.x(), area.y(), area.width(), area.height()); - if (!d->imagecache[i]->dirty.isNull() && topaint.contains(d->imagecache[i]->dirty)) { - QPainter qp(&d->imagecache[i]->image); - qp.translate(-area.x(), -area.y()); - if (d->fillColor.isValid()) - qp.fillRect(d->imagecache[i]->dirty,d->fillColor); - qp.setClipRect(d->imagecache[i]->dirty); - drawContents(&qp, d->imagecache[i]->dirty); - d->imagecache[i]->dirty = QRect(); + if (!d->cachefrozen) { + if (!d->imagecache[i]->dirty.isNull() && topaint.contains(d->imagecache[i]->dirty)) { + QPainter qp(&d->imagecache[i]->image); + qp.translate(-area.x(), -area.y()); + if (d->fillColor.isValid()) + qp.fillRect(d->imagecache[i]->dirty,d->fillColor); + qp.setClipRect(d->imagecache[i]->dirty); + drawContents(&qp, d->imagecache[i]->dirty); + d->imagecache[i]->dirty = QRect(); + } } p->drawPixmap(target.toRect(), d->imagecache[i]->image); topaint -= area; @@ -242,41 +253,46 @@ void QFxPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidge } if (!topaint.isEmpty()) { - // Find a sensible larger area, otherwise will paint lots of tiny images. - QRect biggerrect = topaint.boundingRect().adjusted(-64,-64,128,128); - cachesize += biggerrect.width() * biggerrect.height(); - while (d->imagecache.count() && cachesize > d->max_imagecache_size) { - int oldest=-1; - int age=-1; - for (int i=0; iimagecache.count(); ++i) { - int a = d->imagecache[i]->age; - if (a > age) { - oldest = i; - age = a; + if (!d->cachefrozen) { + // Find a sensible larger area, otherwise will paint lots of tiny images. + QRect biggerrect = topaint.boundingRect().adjusted(-64,-64,128,128); + cachesize += biggerrect.width() * biggerrect.height(); + while (d->imagecache.count() && cachesize > d->max_imagecache_size) { + int oldest=-1; + int age=-1; + for (int i=0; iimagecache.count(); ++i) { + int a = d->imagecache[i]->age; + if (a > age) { + oldest = i; + age = a; + } } + cachesize -= d->imagecache[oldest]->area.width()*d->imagecache[oldest]->area.height(); + uncached += d->imagecache[oldest]->area; + d->imagecache.removeAt(oldest); } - cachesize -= d->imagecache[oldest]->area.width()*d->imagecache[oldest]->area.height(); - uncached += d->imagecache[oldest]->area; - d->imagecache.removeAt(oldest); - } - const QRegion bigger = QRegion(biggerrect) & uncached; - const QVector rects = bigger.rects(); - for (int i = 0; i < rects.count(); ++i) { - const QRect &r = rects.at(i); - QPixmap img(r.size()); - if (d->fillColor.isValid()) - img.fill(d->fillColor); - { - QPainter qp(&img); - qp.translate(-r.x(),-r.y()); - drawContents(&qp, r); + const QRegion bigger = QRegion(biggerrect) & uncached; + const QVector rects = bigger.rects(); + for (int i = 0; i < rects.count(); ++i) { + const QRect &r = rects.at(i); + QPixmap img(r.size()); + if (d->fillColor.isValid()) + img.fill(d->fillColor); + { + QPainter qp(&img); + qp.translate(-r.x(),-r.y()); + drawContents(&qp, r); + } + QFxPaintedItemPrivate::ImageCacheItem *newitem = new QFxPaintedItemPrivate::ImageCacheItem; + newitem->area = r; + newitem->image = img; + d->imagecache.append(newitem); + p->drawPixmap(r, newitem->image); } - QFxPaintedItemPrivate::ImageCacheItem *newitem = new QFxPaintedItemPrivate::ImageCacheItem; - newitem->area = r; - newitem->image = img; - d->imagecache.append(newitem); - QRectF target(r.x(), r.y(), r.width(), r.height()); - p->drawPixmap(target.toRect(), newitem->image); + } else { + const QVector rects = uncached.rects(); + for (int i = 0; i < rects.count(); ++i) + p->fillRect(rects.at(i), Qt::lightGray); } } diff --git a/src/declarative/fx/qfxpainteditem.h b/src/declarative/fx/qfxpainteditem.h index 776ef329..13c6b15 100644 --- a/src/declarative/fx/qfxpainteditem.h +++ b/src/declarative/fx/qfxpainteditem.h @@ -81,6 +81,8 @@ protected: virtual void drawContents(QPainter *p, const QRect &) = 0; + void setCacheFrozen(bool); + Q_SIGNALS: void fillColorChanged(); diff --git a/src/declarative/fx/qfxpainteditem_p.h b/src/declarative/fx/qfxpainteditem_p.h index 2718e57..179fd61 100644 --- a/src/declarative/fx/qfxpainteditem_p.h +++ b/src/declarative/fx/qfxpainteditem_p.h @@ -63,7 +63,7 @@ class QFxPaintedItemPrivate : public QFxItemPrivate public: QFxPaintedItemPrivate() - : max_imagecache_size(100000), fillColor(Qt::transparent) + : max_imagecache_size(100000), fillColor(Qt::transparent), cachefrozen(false) { } @@ -81,6 +81,7 @@ public: int max_imagecache_size; QSize contentsSize; QColor fillColor; + bool cachefrozen; }; QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxwebview.cpp b/src/declarative/fx/qfxwebview.cpp index ba39040..bcbedfb 100644 --- a/src/declarative/fx/qfxwebview.cpp +++ b/src/declarative/fx/qfxwebview.cpp @@ -169,7 +169,8 @@ public: : QFxPaintedItemPrivate(), page(0), preferredwidth(0), pagewidth(0), progress(1.0), status(QFxWebView::Null), pending(PendingNone), newWindowComponent(0), newWindowParent(0), - windowObjects(this) + windowObjects(this), + rendering(true) { } @@ -202,6 +203,8 @@ public: private: QFxWebViewPrivate *priv; } windowObjects; + + bool rendering; }; /*! @@ -355,7 +358,7 @@ void QFxWebView::pageUrlChanged() page()->mainFrame()->setZoomFactor(zf); page()->setViewportSize(QSize(-1,-1)); } - emit zooming(0,0); + emit zooming(zf,0,0); expandToWebPage(); if ((d->url.isEmpty() && page()->mainFrame()->url() != QUrl(QLatin1String("about:blank"))) @@ -493,7 +496,7 @@ void QFxWebView::focusChanged(bool hasFocus) QFxItem::focusChanged(hasFocus); } -void QFxWebView::contentsSizeChanged(const QSize& sz) +void QFxWebView::contentsSizeChanged(const QSize&) { expandToWebPage(); } @@ -645,9 +648,29 @@ void QFxWebViewPrivate::updateWindowObjects() } } +bool QFxWebView::renderingEnabled() const +{ + Q_D(const QFxWebView); + return d->rendering; +} + +void QFxWebView::setRenderingEnabled(bool enabled) +{ + Q_D(QFxWebView); + if (d->rendering == enabled) + return; + d->rendering = enabled; + setCacheFrozen(!enabled); + if (enabled) + clearCache(); +} + + void QFxWebView::drawContents(QPainter *p, const QRect &r) { - page()->mainFrame()->render(p,r); + Q_D(QFxWebView); + if (d->rendering) + page()->mainFrame()->render(p,r); } static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e) @@ -707,9 +730,8 @@ void QFxWebView::heuristicZoom(int clickX, int clickY) // zoom out z = qreal(d->preferredwidth)/d->pagewidth; } - setZoomFactor(z); QRectF r(showarea.left()/ozf*z, showarea.top()/ozf*z, showarea.width()/ozf*z, showarea.height()/ozf*z); - emit zooming(r.x()+r.width()/2, r.y()+r.height()/2); + emit zooming(z,r.x()+r.width()/2, r.y()+r.height()/2); } void QFxWebView::mousePressEvent(QGraphicsSceneMouseEvent *event) diff --git a/src/declarative/fx/qfxwebview.h b/src/declarative/fx/qfxwebview.h index 4a81be8..3dd1b65 100644 --- a/src/declarative/fx/qfxwebview.h +++ b/src/declarative/fx/qfxwebview.h @@ -115,6 +115,8 @@ class Q_DECLARATIVE_EXPORT QFxWebView : public QFxPaintedItem Q_PROPERTY(QmlComponent* newWindowComponent READ newWindowComponent WRITE setNewWindowComponent) Q_PROPERTY(QFxItem* newWindowParent READ newWindowParent WRITE setNewWindowParent) + Q_PROPERTY(bool renderingEnabled READ renderingEnabled WRITE setRenderingEnabled) + public: QFxWebView(QFxItem *parent=0); ~QFxWebView(); @@ -166,6 +168,9 @@ public: int pixelCacheSize() const; void setPixelCacheSize(int pixels); + bool renderingEnabled() const; + void setRenderingEnabled(bool); + QmlList *javaScriptWindowObjects(); static QFxWebViewAttached *qmlAttachedProperties(QObject *); @@ -192,7 +197,7 @@ Q_SIGNALS: void doubleClick(int clickX, int clickY); - void zooming(int centerX, int centerY); + void zooming(qreal zoom, int centerX, int centerY); public Q_SLOTS: QVariant evaluateJavaScript(const QString&); -- cgit v0.12