summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-12-02 05:35:43 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-12-02 05:35:43 (GMT)
commit289645d2bf46c1d6eace7a0d60389a9c10dd0c34 (patch)
tree18f4566813e2e18adcdf5f0a605b95a2276bef04
parent1893849a7e90781b85f15ac32bef972b0087a720 (diff)
downloadQt-289645d2bf46c1d6eace7a0d60389a9c10dd0c34.zip
Qt-289645d2bf46c1d6eace7a0d60389a9c10dd0c34.tar.gz
Qt-289645d2bf46c1d6eace7a0d60389a9c10dd0c34.tar.bz2
Change from scaling/zooming by zoomFactor to instead use painter scaling.
Uses a fixed zoomFactor of 4 to allow sufficient sub-"pixel" precision.
-rw-r--r--demos/declarative/webbrowser/webbrowser.qml32
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspainteditem.cpp57
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspainteditem_p.h8
-rw-r--r--src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h3
-rw-r--r--src/declarative/graphicsitems/qmlgraphicswebview.cpp45
-rw-r--r--src/declarative/graphicsitems/qmlgraphicswebview_p.h4
6 files changed, 107 insertions, 42 deletions
diff --git a/demos/declarative/webbrowser/webbrowser.qml b/demos/declarative/webbrowser/webbrowser.qml
index 105bb07..11776aa 100644
--- a/demos/declarative/webbrowser/webbrowser.qml
+++ b/demos/declarative/webbrowser/webbrowser.qml
@@ -195,13 +195,14 @@ Item {
smoothCache: true // We do want smooth rendering
fillColor: "white"
focus: true
+ zoomFactor: 4
onAlert: console.log(message)
function doZoom(zoom,centerX,centerY)
{
if (centerX) {
- var sc = zoom/zoomFactor;
+ var sc = zoom/contentsScale;
scaleAnim.to = sc;
flickVX.from = flickable.viewportX
flickVX.to = Math.max(0,Math.min(centerX-flickable.width/2,webView.width*sc-flickable.width))
@@ -214,17 +215,28 @@ Item {
}
}
+ Keys.onLeftPressed: webView.contentsScale -= 0.1
+ Keys.onRightPressed: webView.contentsScale += 0.1
+
preferredWidth: flickable.width
preferredHeight: flickable.height
- zoomFactor: flickable.width > 980 ? 1 : flickable.width/980
-
- onUrlChanged: { if (url != null) { editUrl.text = url.toString(); } }
+ contentsScale: 1/zoomFactor
+ onContentsSizeChanged: {
+ // zoom out
+ contentsScale = flickable.width / contentsSize.width
+ }
+ onUrlChanged: {
+ // got to topleft
+ flickable.viewportX = 0
+ flickable.viewportY = 0
+ if (url != null) { editUrl.text = url.toString(); }
+ }
onDoubleClick: {
if (!heuristicZoom(clickX,clickY,2.5)) {
- var zf = flickable.width > 980 ? 1 : flickable.width/980;
- if (zf > zoomFactor)
- zf = 2.0 // zoom in (else zooming out)
- doZoom(zf,clickX/zoomFactor*zf,clickY/zoomFactor*zf)
+ var zf = flickable.width / contentsSize.width
+ if (zf >= contentsScale)
+ zf = 2.0/zoomFactor // zoom in (else zooming out)
+ doZoom(zf,clickX*zf,clickY*zf)
}
}
@@ -268,7 +280,7 @@ Item {
PropertyAction {
id: finalZoom
target: webView
- property: "zoomFactor"
+ property: "contentsScale"
}
PropertyAction {
target: webView
@@ -277,7 +289,7 @@ Item {
}
// Have to set the viewportXY, since the above 2
// size changes may have started a correction if
- // zoomFactor < 1.0.
+ // contentsScale < 1.0.
PropertyAction {
id: finalX
target: flickable
diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp
index 948f69a..b4bb361 100644
--- a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp
@@ -50,6 +50,7 @@
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPaintEngine>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -98,9 +99,13 @@ static int inpaint_clearcache=0;
void QmlGraphicsPaintedItem::dirtyCache(const QRect& rect)
{
Q_D(QmlGraphicsPaintedItem);
+ QRect srect(qCeil(rect.x()*d->contentsScale),
+ qCeil(rect.y()*d->contentsScale),
+ qCeil(rect.width()*d->contentsScale),
+ qCeil(rect.height()*d->contentsScale));
for (int i=0; i < d->imagecache.count(); ) {
QmlGraphicsPaintedItemPrivate::ImageCacheItem *c = d->imagecache[i];
- QRect isect = (c->area & rect) | c->dirty;
+ QRect isect = (c->area & srect) | c->dirty;
if (isect == c->area && !inpaint) {
delete d->imagecache.takeAt(i);
} else {
@@ -147,10 +152,32 @@ void QmlGraphicsPaintedItem::setContentsSize(const QSize &size)
Q_D(QmlGraphicsPaintedItem);
if (d->contentsSize == size) return;
d->contentsSize = size;
+ setImplicitWidth(size.width()*d->contentsScale);
+ setImplicitHeight(size.height()*d->contentsScale);
clearCache();
update();
+ emit contentsSizeChanged();
}
+qreal QmlGraphicsPaintedItem::contentsScale() const
+{
+ Q_D(const QmlGraphicsPaintedItem);
+ return d->contentsScale;
+}
+
+void QmlGraphicsPaintedItem::setContentsScale(qreal scale)
+{
+ Q_D(QmlGraphicsPaintedItem);
+ if (d->contentsScale == scale) return;
+ d->contentsScale = scale;
+ setImplicitWidth(d->contentsSize.width()*scale);
+ setImplicitHeight(d->contentsSize.height()*scale);
+ clearCache();
+ update();
+ emit contentsScaleChanged();
+}
+
+
/*!
Constructs a new QmlGraphicsPaintedItem with the given \a parent.
*/
@@ -204,7 +231,8 @@ void QmlGraphicsPaintedItem::setCacheFrozen(bool frozen)
void QmlGraphicsPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QmlGraphicsPaintedItem);
- const QRect content(QPoint(0,0),d->contentsSize);
+ const QRect content(0,0,qCeil(d->contentsSize.width()*d->contentsScale),
+ qCeil(d->contentsSize.height()*d->contentsScale));
if (content.width() <= 0 || content.height() <= 0)
return;
@@ -244,21 +272,27 @@ void QmlGraphicsPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *
if (!d->cachefrozen) {
if (!d->imagecache[i]->dirty.isNull() && topaint.contains(d->imagecache[i]->dirty)) {
QPainter qp(&d->imagecache[i]->image);
- qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache);
+ qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache);
qp.translate(-area.x(), -area.y());
+ qp.scale(d->contentsScale,d->contentsScale);
+ QRect clip = d->imagecache[i]->dirty;
+ QRect sclip(qFloor(clip.x()/d->contentsScale),
+ qFloor(clip.y()/d->contentsScale),
+ qCeil(clip.width()/d->contentsScale+clip.x()/d->contentsScale-qFloor(clip.x()/d->contentsScale)),
+ qCeil(clip.height()/d->contentsScale+clip.y()/d->contentsScale-qFloor(clip.y()/d->contentsScale)));
+ qp.setClipRect(sclip);
if (d->fillColor.isValid()){
if(d->fillColor.alpha() < 255){
// ### Might not work outside of raster paintengine
QPainter::CompositionMode prev = qp.compositionMode();
qp.setCompositionMode(QPainter::CompositionMode_Source);
- qp.fillRect(d->imagecache[i]->dirty,d->fillColor);
+ qp.fillRect(sclip,d->fillColor);
qp.setCompositionMode(prev);
}else{
- qp.fillRect(d->imagecache[i]->dirty,d->fillColor);
+ qp.fillRect(sclip,d->fillColor);
}
}
- qp.setClipRect(d->imagecache[i]->dirty);
- drawContents(&qp, d->imagecache[i]->dirty);
+ drawContents(&qp, sclip);
d->imagecache[i]->dirty = QRect();
}
}
@@ -300,10 +334,15 @@ void QmlGraphicsPaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *
img.fill(d->fillColor);
{
QPainter qp(&img);
- qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache);
+ qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache);
qp.translate(-r.x(),-r.y());
- drawContents(&qp, r);
+ qp.scale(d->contentsScale,d->contentsScale);
+ QRect sclip(qFloor(r.x()/d->contentsScale),
+ qFloor(r.y()/d->contentsScale),
+ 1+qCeil(r.width()/d->contentsScale+r.x()/d->contentsScale-qFloor(r.x()/d->contentsScale)),
+ 1+qCeil(r.height()/d->contentsScale+r.y()/d->contentsScale-qFloor(r.y()/d->contentsScale)));
+ drawContents(&qp, sclip);
}
QmlGraphicsPaintedItemPrivate::ImageCacheItem *newitem = new QmlGraphicsPaintedItemPrivate::ImageCacheItem;
newitem->area = r;
diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h b/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h
index f6bb078..d59f6d1 100644
--- a/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h
@@ -56,10 +56,11 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsPaintedItem : public QmlGraphicsItem
{
Q_OBJECT
- Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize)
+ Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize NOTIFY contentsSizeChanged)
Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
Q_PROPERTY(int pixelCacheSize READ pixelCacheSize WRITE setPixelCacheSize)
Q_PROPERTY(bool smoothCache READ smoothCache WRITE setSmoothCache)
+ Q_PROPERTY(qreal contentsScale READ contentsScale WRITE setContentsScale NOTIFY contentsScaleChanged)
public:
@@ -69,6 +70,9 @@ public:
QSize contentsSize() const;
void setContentsSize(const QSize &);
+ qreal contentsScale() const;
+ void setContentsScale(qreal);
+
int pixelCacheSize() const;
void setPixelCacheSize(int pixels);
@@ -89,6 +93,8 @@ protected:
Q_SIGNALS:
void fillColorChanged();
+ void contentsSizeChanged();
+ void contentsScaleChanged();
protected Q_SLOTS:
void dirtyCache(const QRect &);
diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h b/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h
index a49bbdf..6bcc51a 100644
--- a/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h
@@ -63,7 +63,7 @@ class QmlGraphicsPaintedItemPrivate : public QmlGraphicsItemPrivate
public:
QmlGraphicsPaintedItemPrivate()
- : max_imagecache_size(100000), fillColor(Qt::transparent), cachefrozen(false), smoothCache(true)
+ : max_imagecache_size(100000), contentsScale(1.0), fillColor(Qt::transparent), cachefrozen(false), smoothCache(true)
{
}
@@ -80,6 +80,7 @@ public:
int max_imagecache_size;
QSize contentsSize;
+ qreal contentsScale;
QColor fillColor;
bool cachefrozen;
bool smoothCache;
diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp
index 0a1587e..c9ba37b 100644
--- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp
@@ -349,7 +349,9 @@ void QmlGraphicsWebView::setPreferredWidth(int iw)
Q_D(QmlGraphicsWebView);
if (d->preferredwidth == iw) return;
d->preferredwidth = iw;
- expandToWebPage();
+ if (d->preferredwidth > 0 && d->preferredheight > 0)
+ page()->setPreferredContentsSize(QSize(d->preferredwidth,d->preferredheight));
+ //expandToWebPage();
emit preferredWidthChanged();
}
@@ -368,6 +370,8 @@ void QmlGraphicsWebView::setPreferredHeight(int ih)
Q_D(QmlGraphicsWebView);
if (d->preferredheight == ih) return;
d->preferredheight = ih;
+ if (d->preferredwidth > 0 && d->preferredheight > 0)
+ page()->setPreferredContentsSize(QSize(d->preferredwidth,d->preferredheight));
emit preferredHeightChanged();
}
@@ -397,7 +401,7 @@ void QmlGraphicsWebView::initialLayout()
// nothing useful to do at this point
}
-void QmlGraphicsWebView::contentsSizeChanged(const QSize&)
+void QmlGraphicsWebView::noteContentsSizeChanged(const QSize&)
{
expandToWebPage();
}
@@ -416,10 +420,9 @@ void QmlGraphicsWebView::expandToWebPage()
cs.setHeight(height());
if (cs != page()->viewportSize()) {
page()->setViewportSize(cs);
- clearCache();
- setImplicitWidth(cs.width());
- setImplicitHeight(cs.height());
}
+ if (cs != contentsSize())
+ setContentsSize(cs);
}
void QmlGraphicsWebView::geometryChanged(const QRectF &newGeometry,
@@ -432,9 +435,6 @@ void QmlGraphicsWebView::geometryChanged(const QRectF &newGeometry,
void QmlGraphicsWebView::paintPage(const QRect& r)
{
- Q_D(QmlGraphicsWebView);
- if (d->page->mainFrame()->contentsSize() != contentsSize())
- setContentsSize(d->page->mainFrame()->contentsSize());
dirtyCache(r);
update();
}
@@ -536,7 +536,7 @@ void QmlGraphicsWebView::drawContents(QPainter *p, const QRect &r)
page()->mainFrame()->render(p,r);
}
-static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e)
+QMouseEvent *QmlGraphicsWebView::sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e)
{
QEvent::Type t;
switch(e->type()) {
@@ -555,15 +555,15 @@ static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e)
break;
}
- QMouseEvent *me = new QMouseEvent(t, e->pos().toPoint(), e->button(), e->buttons(), 0);
+ QMouseEvent *me = new QMouseEvent(t, (e->pos()/contentsScale()).toPoint(), e->button(), e->buttons(), 0);
return me;
}
-static QMouseEvent *sceneHoverMoveEventToMouseEvent(QGraphicsSceneHoverEvent *e)
+QMouseEvent *QmlGraphicsWebView::sceneHoverMoveEventToMouseEvent(QGraphicsSceneHoverEvent *e)
{
QEvent::Type t = QEvent::MouseMove;
- QMouseEvent *me = new QMouseEvent(t, e->pos().toPoint(), Qt::NoButton, Qt::NoButton, 0);
+ QMouseEvent *me = new QMouseEvent(t, (e->pos()/contentsScale()).toPoint(), Qt::NoButton, Qt::NoButton, 0);
return me;
}
@@ -601,15 +601,15 @@ void QmlGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
bool QmlGraphicsWebView::heuristicZoom(int clickX, int clickY, qreal maxzoom)
{
Q_D(QmlGraphicsWebView);
- qreal ozf = zoomFactor();
- if (ozf >= maxzoom)
+ if (contentsScale() >= maxzoom/zoomFactor())
return false;
+ qreal ozf = contentsScale();
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.1) {
- QRectF r(showarea.left()/ozf*z, showarea.top()/ozf*z, showarea.width()/ozf*z, showarea.height()/ozf*z);
+ qreal z = qMin(qreal(d->preferredwidth)/showarea.width(),qreal(d->preferredheight)/showarea.height());
+ if (z > maxzoom/zoomFactor())
+ z = maxzoom/zoomFactor();
+ if (z/ozf > 1.2) {
+ QRectF r(showarea.left()*z, showarea.top()*z, showarea.width()*z, showarea.height()*z);
emit zoomTo(z,r.x()+r.width()/2, r.y()+r.height()/2);
return true;
} else {
@@ -963,7 +963,7 @@ void QmlGraphicsWebView::setPage(QWebPage *page)
connect(d->page->mainFrame(),SIGNAL(urlChanged(QUrl)),this,SLOT(pageUrlChanged()));
connect(d->page->mainFrame(), SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString)));
connect(d->page->mainFrame(), SIGNAL(iconChanged()), this, SIGNAL(iconChanged()));
- connect(d->page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), this, SLOT(contentsSizeChanged(QSize)));
+ connect(d->page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), this, SLOT(noteContentsSizeChanged(QSize)));
connect(d->page->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(initialLayout()));
connect(d->page,SIGNAL(loadStarted()),this,SLOT(doLoadStarted()));
@@ -1204,6 +1204,7 @@ QString QmlGraphicsWebPage::chooseFile(QWebFrame *originatingFrame, const QStrin
void QmlGraphicsWebPage::javaScriptAlert(QWebFrame *originatingFrame, const QString& msg)
{
+ Q_UNUSED(originatingFrame)
emit viewItem()->alert(msg);
}
@@ -1218,6 +1219,10 @@ bool QmlGraphicsWebPage::javaScriptConfirm(QWebFrame *originatingFrame, const QS
bool QmlGraphicsWebPage::javaScriptPrompt(QWebFrame *originatingFrame, const QString& msg, const QString& defaultValue, QString* result)
{
// Not supported (it's modal)
+ Q_UNUSED(originatingFrame)
+ Q_UNUSED(msg)
+ Q_UNUSED(defaultValue)
+ Q_UNUSED(result)
return false;
}
diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p.h
index 1e44263..2280697 100644
--- a/src/declarative/graphicsitems/qmlgraphicswebview_p.h
+++ b/src/declarative/graphicsitems/qmlgraphicswebview_p.h
@@ -210,7 +210,7 @@ private Q_SLOTS:
void setStatusText(const QString&);
void windowObjectCleared();
void pageUrlChanged();
- void contentsSizeChanged(const QSize&);
+ void noteContentsSizeChanged(const QSize&);
void initialLayout();
protected:
@@ -235,6 +235,8 @@ private:
virtual void componentComplete();
Q_DISABLE_COPY(QmlGraphicsWebView)
Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QmlGraphicsWebView)
+ QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *);
+ QMouseEvent *sceneHoverMoveEventToMouseEvent(QGraphicsSceneHoverEvent *);
friend class QmlGraphicsWebPage;
};