{
Q_D(QQuickPinchArea);
+ QQuickWindow *win = window();
++
+ if (d->touchPoints.count() < 2) {
+ setKeepMouseGrab(false);
+ QQuickWindow *c = window();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ }
+
+ if (d->touchPoints.count() == 0) {
+ if (d->inPinch) {
+ d->inPinch = false;
+ QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+ QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setPreviousCenter(pinchCenter);
+ pe.setPreviousAngle(d->pinchLastAngle);
+ pe.setPreviousScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(mapFromScene(d->lastPoint1));
+ pe.setPoint2(mapFromScene(d->lastPoint2));
+ emit pinchFinished(&pe);
+ d->pinchStartDist = 0;
+ d->pinchActivated = false;
+ if (d->pinch && d->pinch->target())
+ d->pinch->setActive(false);
+ }
+ d->initPinch = false;
+ d->pinchRejected = false;
+ d->stealMouse = false;
+ return;
+ }
+
QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
+
QRectF bounds = clipRect();
// Pinch is not started unless there are exactly two touch points
// AND one or more of the points has just now been pressed (wasn't pressed already)
d->pinchRotation = 0.0;
d->lastPoint1 = p1;
d->lastPoint2 = p2;
- QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
- pe.setStartCenter(d->pinchStartCenter);
- pe.setPreviousCenter(d->pinchStartCenter);
- pe.setPreviousAngle(d->pinchLastAngle);
- pe.setPreviousScale(d->pinchLastScale);
- pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
- pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
- pe.setPoint1(mapFromScene(d->lastPoint1));
- pe.setPoint2(mapFromScene(d->lastPoint2));
- pe.setPointCount(d->touchPoints.count());
- emit pinchStarted(&pe);
- if (pe.accepted()) {
- if (win && win->mouseGrabberItem() != this)
- grabMouse();
- setKeepMouseGrab(true);
- grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
- d->inPinch = true;
- d->stealMouse = true;
- if (d->pinch && d->pinch->target()) {
- d->pinchStartPos = pinch()->target()->position();
- d->pinchStartScale = d->pinch->target()->scale();
- d->pinchStartRotation = d->pinch->target()->rotation();
- d->pinch->setActive(true);
+ if (qAbs(dist - d->pinchStartDist) >= dragThreshold ||
+ (pinch()->axis() != QQuickPinch::NoDrag &&
+ (qAbs(p1.x()-d->sceneStartPoint1.x()) >= dragThreshold
+ || qAbs(p1.y()-d->sceneStartPoint1.y()) >= dragThreshold
+ || qAbs(p2.x()-d->sceneStartPoint2.x()) >= dragThreshold
+ || qAbs(p2.y()-d->sceneStartPoint2.y()) >= dragThreshold))) {
+ QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+ d->pinchStartDist = dist;
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setPreviousCenter(d->pinchStartCenter);
+ pe.setPreviousAngle(d->pinchLastAngle);
+ pe.setPreviousScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(mapFromScene(d->lastPoint1));
+ pe.setPoint2(mapFromScene(d->lastPoint2));
+ pe.setPointCount(d->touchPoints.count());
+ emit pinchStarted(&pe);
+ if (pe.accepted()) {
+ d->inPinch = true;
+ d->stealMouse = true;
- QQuickWindow *c = window();
- if (c && c->mouseGrabberItem() != this)
++ if (win && win->mouseGrabberItem() != this)
+ grabMouse();
+ setKeepMouseGrab(true);
++ grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
++ d->inPinch = true;
++ d->stealMouse = true;
+ if (d->pinch && d->pinch->target()) {
+ d->pinchStartPos = pinch()->target()->position();
+ d->pinchStartScale = d->pinch->target()->scale();
+ d->pinchStartRotation = d->pinch->target()->rotation();
+ d->pinch->setActive(true);
+ }
+ } else {
+ d->pinchRejected = true;
}
- } else {
- d->pinchRejected = true;
}
}
} else if (d->pinchStartDist > 0) {
}
}
-
-
/*
- Adds this window to the list of tracked windows in this window
- manager. show() does not trigger rendering to start, that happens
- in expose.
- */
-
-void QSGThreadedRenderLoop::show(QQuickWindow *window)
-{
- QSG_GUI_DEBUG(window, "show()");
-
- if (Window *w = windowFor(m_windows, window)) {
- /* Safeguard ourselves against misbehaving platform plugins.
- *
- * When being shown, the window should not be exposed as the
- * platform plugin is only told to show after we send the show
- * event. If we are already shown at this time and we don't have
- * an active rendering thread we don't trust the plugin to send
- * us another expose event, so make this explicit call to
- * handleExposure.
- *
- * REF: QTCREATORBUG-10699
- */
- if (window->isExposed() && (!w->thread || !w->thread->window))
- handleExposure(w);
- return;
- }
-
- QSG_GUI_DEBUG(window, " - now tracking new window");
-
- Window win;
- win.window = window;
- win.actualWindowFormat = window->format();
- win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context);
- win.timerId = 0;
- win.updateDuringSync = false;
- m_windows << win;
-}
-
-
-
-/*
Removes this window from the list of tracked windowes in this
window manager. hide() will trigger obscure, which in turn will
stop rendering.
Will post an event to the render thread that this window should
start to render.
*/
-void QSGThreadedRenderLoop::handleExposure(Window *w)
+void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
{
- QSG_GUI_DEBUG(w->window, "handleExposure");
+ QSG_GUI_DEBUG(window, "handleExposure");
+
+ Window *w = windowFor(m_windows, window);
+ if (!w) {
+ QSG_GUI_DEBUG(window, " - adding window to list");
+ Window win;
+ win.window = window;
++ win.actualWindowFormat = window->format();
+ win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context);
+ win.timerId = 0;
+ win.updateDuringSync = false;
+ m_windows << win;
+ w = &m_windows.last();
+ }
if (w->window->width() <= 0 || w->window->height() <= 0
|| !w->window->geometry().intersects(w->window->screen()->availableGeometry())) {
// create it here and pass it on to QSGRenderThread::invalidateGL()
QOffscreenSurface *fallback = 0;
if (!window->handle()) {
- QSG_GUI_DEBUG(w->window, " - using fallback surface");
+ QSG_GUI_DEBUG(window, " - using fallback surface");
fallback = new QOffscreenSurface();
- fallback->setFormat(window->requestedFormat());
+ fallback->setFormat(w->actualWindowFormat);
fallback->create();
}
delete obj;
}
- TestHTTPServer server(14449);
- QVERIFY(server.isValid());
+ void tst_qquickimage::highdpi()
+ {
++ TestHTTPServer server;
++ QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+ server.serveDirectory(dataDirectory());
+
+ QString componentStr = "import QtQuick 2.0\nImage { source: srcImage ; }";
+ QQmlComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQmlContext *ctxt = engine.rootContext();
+
+ // Testing "@2x" high-dpi image loading:
+ // The basic case is as follows. Suppose you have foo.png,
+ // which is a 64x64 png that fits in a QML layout. Now,
+ // on a high-dpi system that pixmap would not provide
+ // enough pixels. To fix this the app developer provides
+ // a 128x128 foo@2x.png, which Qt automatically loads.
+ // The image continues to be referred to as "foo.png" in
+ // the QML sources, and reports a size of 64x64.
+ //
+
+ // Load "heart-highdpi@2x.png", which is a 300x300 png. As a 2x scale image it
+ // should render and report a geometry of 150x150.
+ ctxt->setContextProperty("srcImage", testFileUrl("heart-highdpi@2x.png"));
+
+ QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+ QVERIFY(obj != 0);
+
+ QCOMPARE(obj->width(), 150.0);
+ QCOMPARE(obj->height(), 150.0);
+ QCOMPARE(obj->paintedWidth(), 150.0);
+ QCOMPARE(obj->paintedHeight(), 150.0);
+
+ // Load a normal 1x image.
+ ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+ QCOMPARE(obj->width(), 300.0);
+ QCOMPARE(obj->height(), 300.0);
+ QCOMPARE(obj->paintedWidth(), 300.0);
+ QCOMPARE(obj->paintedHeight(), 300.0);
+
+ delete obj;
+ }
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"