コード例 #1
0
void QDeclarativePinchArea::updatePinch()
{
    Q_D(QDeclarativePinchArea);
    if (d->touchPoints.count() == 0) {
        if (d->inPinch) {
            d->stealMouse = false;
            setKeepMouseGrab(false);
            d->inPinch = false;
            QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
            QDeclarativePinchEvent 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);
        }
        return;
    }
    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
    if (d->touchPoints.count() == 2
        && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
        d->id1 = touchPoint1.id();
        d->sceneStartPoint1 = touchPoint1.scenePos();
        d->sceneStartPoint2 = touchPoint2.scenePos();
        d->inPinch = false;
        d->pinchRejected = false;
        d->pinchActivated = true;
    } else if (d->pinchActivated && !d->pinchRejected) {
        const int dragThreshold = QApplication::startDragDistance();
        QPointF p1 = touchPoint1.scenePos();
        QPointF p2 = touchPoint2.scenePos();
        qreal dx = p1.x() - p2.x();
        qreal dy = p1.y() - p2.y();
        qreal dist = sqrt(dx*dx + dy*dy);
        QPointF sceneCenter = (p1 + p2)/2;
        qreal angle = QLineF(p1, p2).angle();
        if (d->touchPoints.count() == 1) {
            // If we only have one point then just move the center
            if (d->id1 == touchPoint1.id())
                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
            else
                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
            angle = d->pinchLastAngle;
        }
        d->id1 = touchPoint1.id();
        if (angle > 180)
            angle -= 360;
        if (!d->inPinch) {
            if (d->touchPoints.count() >= 2
                    && (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)) {
                d->sceneStartCenter = sceneCenter;
                d->sceneLastCenter = sceneCenter;
                d->pinchStartCenter = mapFromScene(sceneCenter);
                d->pinchStartDist = dist;
                d->pinchStartAngle = angle;
                d->pinchLastScale = 1.0;
                d->pinchLastAngle = angle;
                d->pinchRotation = 0.0;
                d->lastPoint1 = p1;
                d->lastPoint2 = p2;
                QDeclarativePinchEvent 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()) {
                    d->inPinch = true;
                    d->stealMouse = true;
                    QGraphicsScene *s = scene();
                    if (s && s->mouseGrabberItem() != this)
                        grabMouse();
                    setKeepMouseGrab(true);
                    if (d->pinch && d->pinch->target()) {
                        d->pinchStartPos = pinch()->target()->pos();
                        d->pinchStartScale = d->pinch->target()->scale();
                        d->pinchStartRotation = d->pinch->target()->rotation();
                        d->pinch->setActive(true);
                    }
                } else {
                    d->pinchRejected = true;
                }
            }
        } else if (d->pinchStartDist > 0) {
            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
            qreal da = d->pinchLastAngle - angle;
            if (da > 180)
                da -= 360;
            else if (da < -180)
                da += 360;
            d->pinchRotation += da;
            QPointF pinchCenter = mapFromScene(sceneCenter);
            QDeclarativePinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(touchPoint1.pos());
            pe.setPoint2(touchPoint2.pos());
            pe.setPointCount(d->touchPoints.count());
            d->pinchLastScale = scale;
            d->sceneLastCenter = sceneCenter;
            d->pinchLastAngle = angle;
            d->lastPoint1 = touchPoint1.scenePos();
            d->lastPoint2 = touchPoint2.scenePos();
            emit pinchUpdated(&pe);
            if (d->pinch && d->pinch->target()) {
                qreal s = d->pinchStartScale * scale;
                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
                pinch()->target()->setScale(s);
                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
                if (pinch()->axis() & QDeclarativePinch::XAxis) {
                    qreal x = pos.x();
                    if (x < pinch()->xmin())
                        x = pinch()->xmin();
                    else if (x > pinch()->xmax())
                        x = pinch()->xmax();
                    pinch()->target()->setX(x);
                }
                if (pinch()->axis() & QDeclarativePinch::YAxis) {
                    qreal y = pos.y();
                    if (y < pinch()->ymin())
                        y = pinch()->ymin();
                    else if (y > pinch()->ymax())
                        y = pinch()->ymax();
                    pinch()->target()->setY(y);
                }
                if (d->pinchStartRotation >= pinch()->minimumRotation()
                        && d->pinchStartRotation <= pinch()->maximumRotation()) {
                    qreal r = d->pinchRotation + d->pinchStartRotation;
                    r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
                    pinch()->target()->setRotation(r);
                }
            }
        }
    }
}
コード例 #2
0
void QQuickPinchArea::updatePinch()
{
    Q_D(QQuickPinchArea);
    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;
        setKeepMouseGrab(false);
        return;
    }

    if (d->touchPoints.count() == 1) {
        setKeepMouseGrab(false);
    }

    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)
    // AND both points are inside the bounds.
    if (d->touchPoints.count() == 2
            && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed) &&
            bounds.contains(touchPoint1.pos()) && bounds.contains(touchPoint2.pos())) {
        d->id1 = touchPoint1.id();
        d->sceneStartPoint1 = touchPoint1.scenePos();
        d->sceneStartPoint2 = touchPoint2.scenePos();
        d->pinchActivated = true;
        d->initPinch = true;
    }
    if (d->pinchActivated && !d->pinchRejected) {
        const int dragThreshold = qApp->styleHints()->startDragDistance();
        QPointF p1 = touchPoint1.scenePos();
        QPointF p2 = touchPoint2.scenePos();
        qreal dx = p1.x() - p2.x();
        qreal dy = p1.y() - p2.y();
        qreal dist = sqrt(dx*dx + dy*dy);
        QPointF sceneCenter = (p1 + p2)/2;
        qreal angle = QLineF(p1, p2).angle();
        if (d->touchPoints.count() == 1) {
            // If we only have one point then just move the center
            if (d->id1 == touchPoint1.id())
                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
            else
                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
            angle = d->pinchLastAngle;
        }
        d->id1 = touchPoint1.id();
        if (angle > 180)
            angle -= 360;
        if (!d->inPinch || d->initPinch) {
            if (d->touchPoints.count() >= 2
                    && (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)) {
                d->initPinch = false;
                d->sceneStartCenter = sceneCenter;
                d->sceneLastCenter = sceneCenter;
                d->pinchStartCenter = mapFromScene(sceneCenter);
                d->pinchStartDist = dist;
                d->pinchStartAngle = angle;
                d->pinchLastScale = 1.0;
                d->pinchLastAngle = angle;
                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()) {
                    d->inPinch = true;
                    d->stealMouse = true;
                    QQuickWindow *c = window();
                    if (c && c->mouseGrabberItem() != this)
                        grabMouse();
                    setKeepMouseGrab(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 if (d->pinchStartDist > 0) {
            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
            qreal da = d->pinchLastAngle - angle;
            if (da > 180)
                da -= 360;
            else if (da < -180)
                da += 360;
            d->pinchRotation += da;
            QPointF pinchCenter = mapFromScene(sceneCenter);
            QQuickPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(touchPoint1.pos());
            pe.setPoint2(touchPoint2.pos());
            pe.setPointCount(d->touchPoints.count());
            d->pinchLastScale = scale;
            d->sceneLastCenter = sceneCenter;
            d->pinchLastAngle = angle;
            d->lastPoint1 = touchPoint1.scenePos();
            d->lastPoint2 = touchPoint2.scenePos();
            emit pinchUpdated(&pe);
            if (d->pinch && d->pinch->target()) {
                qreal s = d->pinchStartScale * scale;
                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
                pinch()->target()->setScale(s);
                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
                if (pinch()->axis() & QQuickPinch::XAxis) {
                    qreal x = pos.x();
                    if (x < pinch()->xmin())
                        x = pinch()->xmin();
                    else if (x > pinch()->xmax())
                        x = pinch()->xmax();
                    pinch()->target()->setX(x);
                }
                if (pinch()->axis() & QQuickPinch::YAxis) {
                    qreal y = pos.y();
                    if (y < pinch()->ymin())
                        y = pinch()->ymin();
                    else if (y > pinch()->ymax())
                        y = pinch()->ymax();
                    pinch()->target()->setY(y);
                }
                if (d->pinchStartRotation >= pinch()->minimumRotation()
                        && d->pinchStartRotation <= pinch()->maximumRotation()) {
                    qreal r = d->pinchRotation + d->pinchStartRotation;
                    r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
                    pinch()->target()->setRotation(r);
                }
            }
        }
    }
}
コード例 #3
0
/*!
    \internal
*/
void QDeclarativeGeoMapGestureArea::updatePinch()
{
    // Calculate the new zoom level if we have distance ( >= 2 touchpoints), otherwise stick with old.
    qreal newZoomLevel = pinch_.zoom.previous;
    if (distanceBetweenTouchPoints_) {
        newZoomLevel =
                // How much further/closer the current touchpoints are (in pixels) compared to pinch start
                ((distanceBetweenTouchPoints_ - pinch_.startDist)  *
                 //  How much one pixel corresponds in units of zoomlevel (and multiply by above delta)
                 (pinch_.zoom.maximumChange / ((declarativeMap_->width() + declarativeMap_->height()) / 2))) +
                // Add to starting zoom level. Sign of (dist-pinchstartdist) takes care of zoom in / out
                pinch_.zoom.start;
    }
    qreal da = pinch_.lastAngle - twoTouchAngle_;
    if (da > 180)
        da -= 360;
    else if (da < -180)
        da += 360;
    pinch_.rotation.angle -= da;
    pinch_.event.setCenter(declarativeMap_->mapFromScene(sceneCenter_));
    pinch_.event.setAngle(twoTouchAngle_);

    pinch_.lastPoint1 = touchPoints_.at(0).scenePos();
    pinch_.lastPoint2 = touchPoints_.at(1).scenePos();
    pinch_.event.setPoint1(pinch_.lastPoint1);
    pinch_.event.setPoint2(pinch_.lastPoint2);
    pinch_.event.setPointCount(touchPoints_.count());
    pinch_.event.setAccepted(true);

    pinch_.lastAngle = twoTouchAngle_;
    emit pinchUpdated(&pinch_.event);

    if (activeGestures_ & ZoomGesture) {
        // Take maximum and minimumzoomlevel into account
        qreal perPinchMinimumZoomLevel = qMax(pinch_.zoom.start - pinch_.zoom.maximumChange, pinch_.zoom.minimum);
        qreal perPinchMaximumZoomLevel = qMin(pinch_.zoom.start + pinch_.zoom.maximumChange, pinch_.zoom.maximum);
        newZoomLevel = qMin(qMax(perPinchMinimumZoomLevel, newZoomLevel), perPinchMaximumZoomLevel);
        declarativeMap_->setZoomLevel(newZoomLevel);
    }
    if (activeGestures_ & TiltGesture && pinch_.zoom.minimum >= 0 && pinch_.zoom.maximum >= 0) {
        // Note: tilt is not yet supported.
        qreal newTilt = pinch_.tilt.previous;
        if (distanceBetweenTouchPoints_) {
            newTilt =
                    // How much further/closer the current touchpoints are (in pixels) compared to pinch start
                    ((distanceBetweenTouchPoints_ - pinch_.startDist)  *
                     //  How much one pixel corresponds in units of tilt degrees (and multiply by above delta)
                     (pinch_.tilt.maximumChange / ((declarativeMap_->width() + declarativeMap_->height()) / 2))) +
                    // Add to starting tilt.
                    pinch_.tilt.start;
        }
        qreal perPinchMinimumTilt = qMax(pinch_.tilt.start - pinch_.tilt.maximumChange, pinch_.tilt.minimum);
        qreal perPinchMaximumTilt = qMin(pinch_.tilt.start + pinch_.tilt.maximumChange, pinch_.tilt.maximum);
        newTilt = qMin(qMax(perPinchMinimumTilt, newTilt), perPinchMaximumTilt);
        pinch_.tilt.previous = newTilt;
        declarativeMap_->setTilt(newTilt);
    }
    if (activeGestures_ & RotationGesture) {
        bool unlimitedRotation = (pinch_.rotation.minimum == 0.0 && pinch_.rotation.maximum == 0.0);
        if ((pinch_.rotation.start >= pinch_.rotation.minimum && pinch_.rotation.start <= pinch_.rotation.maximum) || unlimitedRotation)  {
            qreal r = pinch_.rotation.angle * pinch_.rotation.factor + pinch_.rotation.start;
            if (!unlimitedRotation)
                r = qMin(qMax(pinch_.rotation.minimum,r), pinch_.rotation.maximum);
            if (r > 360.0)
                r -= 360;
            if (r < -360.0)
                r += 360.0;
            declarativeMap_->setBearing(r);
        }
    }
}