diff options
5 files changed, 82 insertions, 71 deletions
diff --git a/demos/declarative/webbrowser/webbrowser.qml b/demos/declarative/webbrowser/webbrowser.qml index 6be3e09..8a01af5 100644 --- a/demos/declarative/webbrowser/webbrowser.qml +++ b/demos/declarative/webbrowser/webbrowser.qml @@ -191,15 +191,37 @@ Item { } url: fixUrl(webBrowser.urlString) - smooth: true + smooth: false // We don't want smooth scaling, since we only scale during (fast) transitions + smoothCache: true // We do want smooth rendering fillColor: "white" focus: true + function doZoom(zoom,centerX,centerY) + { + if (centerX) { + var sc = zoom/zoomFactor; + scaleAnim.to = sc; + flickVX.from = flickable.viewportX + flickVX.to = Math.min(Math.max(0,centerX-flickable.width/2),webView.width*sc-flickable.width) + finalX.value = Math.min(Math.max(0,centerX-flickable.width/2),webView.width*sc-flickable.width) + flickVY.from = flickable.viewportY + flickVY.to = Math.min(Math.max(0,centerY-flickable.height/2),webView.height*sc-flickable.height) + finalY.value = Math.min(Math.max(0,centerY-flickable.height/2),webView.height*sc-flickable.height) + finalZoom.value = zoom + quickZoom.start() + } + } + preferredWidth: flickable.width - webPageWidth: 980 + preferredHeight: flickable.height + zoomFactor: flickable.width > 980 ? flickable.width : flickable.width/980 onUrlChanged: { if (url != null) { webBrowser.urlString = url.toString(); } } - onDoubleClick: { heuristicZoom(clickX,clickY) } + onDoubleClick: { if (!heuristicZoom(clickX,clickY,2.5)) { + var zf = flickable.width > 980 ? flickable.width : flickable.width/980; + doZoom(zf,clickX/zoomFactor*zf,clickY/zoomFactor*zf) + } + } SequentialAnimation { id: quickZoom @@ -269,20 +291,7 @@ Item { value: true } } - onZooming: { - if (centerX) { - var sc = zoom/zoomFactor; - scaleAnim.to = sc; - flickVX.from = flickable.viewportX - flickVX.to = Math.min(Math.max(0,centerX-flickable.width/2),webView.width*sc-flickable.width) - finalX.value = Math.min(Math.max(0,centerX-flickable.width/2),webView.width*sc-flickable.width) - flickVY.from = flickable.viewportY - flickVY.to = Math.min(Math.max(0,centerY-flickable.height/2),webView.height*sc-flickable.height) - finalY.value = Math.min(Math.max(0,centerY-flickable.height/2),webView.height*sc-flickable.height) - finalZoom.value = zoom - quickZoom.start() - } - } + onZoomTo: doZoom(zoom,centerX,centerY) } Rectangle { id: webViewTint diff --git a/examples/declarative/webview/qml-in-html.qml b/examples/declarative/webview/qml-in-html.qml index 43cc61b..a2f2f2a 100644 --- a/examples/declarative/webview/qml-in-html.qml +++ b/examples/declarative/webview/qml-in-html.qml @@ -12,8 +12,8 @@ Rectangle { id: web width: 250 height: 420 - scale: 0.75 - smooth: true + zoomFactor: 0.75 + smoothCache: true settings.pluginsEnabled: true html: "<html>\ <body bgcolor=white>\ diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index f706d77..b580116 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -1238,7 +1238,8 @@ PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent()); else parentWidget = 0; // The plug-in won't be fully functional because the QWebView doesn't exist. - widget->setParent(parentWidget); + if (parentWidget) // don't reparent to nothing (i.e. keep whatever parent createPlugin() chose. + widget->setParent(parentWidget); RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget()); w->setPlatformWidget(widget); // Make sure it's invisible until properly placed into the layout diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp index 332e5ea..14c4352 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp @@ -166,7 +166,7 @@ class QmlGraphicsWebViewPrivate : public QmlGraphicsPaintedItemPrivate public: QmlGraphicsWebViewPrivate() - : QmlGraphicsPaintedItemPrivate(), page(0), preferredwidth(0), pagewidth(0), + : QmlGraphicsPaintedItemPrivate(), page(0), preferredwidth(0), preferredheight(0), progress(1.0), status(QmlGraphicsWebView::Null), pending(PendingNone), newWindowComponent(0), newWindowParent(0), windowObjects(this), @@ -177,8 +177,7 @@ public: QUrl url; // page url might be different if it has not loaded yet QWebPage *page; - int preferredwidth; - int pagewidth; + int preferredwidth, preferredheight; qreal progress; QmlGraphicsWebView::Status status; QString statusText; @@ -227,7 +226,8 @@ public: width: 490 height: 400 scale: 0.5 - smooth: true + smooth: false + smoothCache: true } \endqml @@ -341,18 +341,11 @@ void QmlGraphicsWebView::pageUrlChanged() { Q_D(QmlGraphicsWebView); - // Reset zooming to full - qreal zf = 1.0; if (d->preferredwidth) { - if (d->pagewidth) - zf = qreal(d->preferredwidth)/d->pagewidth; - page()->mainFrame()->setZoomFactor(zf); page()->setViewportSize(QSize(d->preferredwidth,-1)); } else { - page()->mainFrame()->setZoomFactor(zf); page()->setViewportSize(QSize(-1,-1)); } - emit zooming(zf,0,0); expandToWebPage(); if ((d->url.isEmpty() && page()->mainFrame()->url() != QUrl(QLatin1String("about:blank"))) @@ -406,15 +399,11 @@ void QmlGraphicsWebView::setUrl(const QUrl &url) if (isComponentComplete()) { d->url = url; - qreal zf = 1.0; if (d->preferredwidth) { - if (d->pagewidth) - zf = qreal(d->preferredwidth)/d->pagewidth; page()->setViewportSize(QSize(d->preferredwidth,-1)); } else { page()->setViewportSize(QSize(-1,-1)); } - page()->mainFrame()->setZoomFactor(zf); QUrl seturl = url; if (seturl.isEmpty()) seturl = QUrl(QLatin1String("about:blank")); @@ -444,35 +433,27 @@ void QmlGraphicsWebView::setPreferredWidth(int iw) { Q_D(QmlGraphicsWebView); if (d->preferredwidth == iw) return; - if (d->pagewidth) { - if (d->preferredwidth) { - setZoomFactor(zoomFactor()*iw/d->preferredwidth); - } else { - setZoomFactor(qreal(iw)/d->pagewidth); - } - } d->preferredwidth = iw; expandToWebPage(); emit preferredWidthChanged(); } /*! - \qmlproperty int WebView::webPageWidth - This property holds the page width suggested to the web engine. The zoomFactor - will be changed to fit this with in preferredWidth. + \qmlproperty int WebView::preferredHeight + This property holds the ideal height for displaying the current URL. + This only affects the area zoomed by heuristicZoom(). */ -int QmlGraphicsWebView::webPageWidth() const +int QmlGraphicsWebView::preferredHeight() const { Q_D(const QmlGraphicsWebView); - return d->pagewidth; + return d->preferredheight; } - -void QmlGraphicsWebView::setWebPageWidth(int pw) +void QmlGraphicsWebView::setPreferredHeight(int ih) { Q_D(QmlGraphicsWebView); - if (d->pagewidth == pw) return; - d->pagewidth = pw; - expandToWebPage(); + if (d->preferredheight == ih) return; + d->preferredheight = ih; + emit preferredHeightChanged(); } /*! @@ -715,18 +696,38 @@ void QmlGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) delete me; } -void QmlGraphicsWebView::heuristicZoom(int clickX, int clickY) +/*! + \qmlmethod bool WebView::heuristicZoom(clickX,clickY,maxzoom) + + Finds a zoom that: + \list + \i shows a whole item + \i includes (\a clickX, \a clickY) + \i fits into the preferredWidth and preferredHeight + \i zooms by no more than \a maxzoom + \i is more than 20% above the current zoom + \endlist + + If such a zoom exists, emits zoomTo(zoom,centerX,centerY) and returns true; otherwise, + no signal is emitted and returns false. +*/ +bool QmlGraphicsWebView::heuristicZoom(int clickX, int clickY, qreal maxzoom) { Q_D(QmlGraphicsWebView); qreal ozf = zoomFactor(); - QRect showarea = elementAreaAt(clickX, clickY, 1, 1); - qreal z = qreal(preferredWidth())*ozf/showarea.width()*.95; - if ((z/ozf > 0.99 && z/ozf <1.01) || z < qreal(d->preferredwidth)/d->pagewidth) { - // zoom out - z = qreal(d->preferredwidth)/d->pagewidth; + if (ozf >= maxzoom) + return false; + QRect showarea = elementAreaAt(clickX, clickY, d->preferredwidth/maxzoom, d->preferredheight/maxzoom); + qreal z = qMin(qreal(d->preferredwidth)*ozf/showarea.width(),qreal(d->preferredheight)*ozf/showarea.height()); + if (z > maxzoom) + z = maxzoom; + if (z/ozf > 1.2) { + QRectF r(showarea.left()/ozf*z, showarea.top()/ozf*z, showarea.width()/ozf*z, showarea.height()/ozf*z); + emit zoomTo(z,r.x()+r.width()/2, r.y()+r.height()/2); + return true; + } else { + return false; } - QRectF r(showarea.left()/ozf*z, showarea.top()/ozf*z, showarea.width()/ozf*z, showarea.height()/ozf*z); - emit zooming(z,r.x()+r.width()/2, r.y()+r.height()/2); } void QmlGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent *event) @@ -911,7 +912,7 @@ void QmlGraphicsWebView::setZoomFactor(qreal factor) return; page()->mainFrame()->setZoomFactor(factor); - page()->setViewportSize(QSize(d->pagewidth*factor,-1)); + page()->setViewportSize(QSize(d->preferredwidth ? d->preferredwidth : -1,-1)); expandToWebPage(); emit zoomFactorChanged(); @@ -1239,15 +1240,15 @@ void QmlGraphicsWebView::setNewWindowParent(QmlGraphicsItem *parent) QRect QmlGraphicsWebView::elementAreaAt(int x, int y, int maxwidth, int maxheight) const { QWebHitTestResult hit = page()->mainFrame()->hitTestContent(QPoint(x,y)); + QRect rv = hit.boundingRect(); QWebElement element = hit.enclosingBlockElement(); - QWebElement parent = element.parent(); if (maxwidth<=0) maxwidth = INT_MAX; if (maxheight<=0) maxheight = INT_MAX; - while (!parent.isNull() && parent.geometry().width() <= maxwidth && parent.geometry().height() <= maxheight) { - element = parent; - parent = element.parent(); + while (!element.parent().isNull() && element.geometry().width() <= maxwidth && element.geometry().height() <= maxheight) { + rv = element.geometry(); + element = element.parent(); } - return element.geometry(); + return rv; } /*! diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p.h index 6373246..7c9faf4 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicswebview_p.h @@ -94,7 +94,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsWebView : public QmlGraphicsPaintedItem Q_PROPERTY(QString html READ html WRITE setHtml) Q_PROPERTY(int preferredWidth READ preferredWidth WRITE setPreferredWidth NOTIFY preferredWidthChanged) - Q_PROPERTY(int webPageWidth READ webPageWidth WRITE setWebPageWidth) + Q_PROPERTY(int preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged) Q_PROPERTY(int pixelCacheSize READ pixelCacheSize WRITE setPixelCacheSize) Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) @@ -127,11 +127,12 @@ public: qreal zoomFactor() const; void setZoomFactor(qreal); + Q_INVOKABLE bool heuristicZoom(int clickX, int clickY, qreal maxzoom); int preferredWidth() const; void setPreferredWidth(int); - int webPageWidth() const; - void setWebPageWidth(int); + int preferredHeight() const; + void setPreferredHeight(int); enum Status { Null, Ready, Loading, Error }; Status status() const; @@ -191,11 +192,10 @@ Q_SIGNALS: void doubleClick(int clickX, int clickY); - void zooming(qreal zoom, int centerX, int centerY); + void zoomTo(qreal zoom, int centerX, int centerY); public Q_SLOTS: QVariant evaluateJavaScript(const QString&); - void heuristicZoom(int clickX, int clickY); private Q_SLOTS: void expandToWebPage(); |