Пример #1
0
QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
                                                              QObject *,
                                                              QEvent *event)
{
    QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
    QSwipeGesturePrivate *d = q->d_func();

    const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);

    QGestureRecognizer::Result result;

    switch (event->type()) {
    case QEvent::TouchBegin: {
        d->velocityValue = 1;
        d->time.start();
        d->started = true;
        result = QGestureRecognizer::MayBeGesture;
        break;
    }
    case QEvent::TouchEnd: {
        if (q->state() != Qt::NoGesture) {
            result = QGestureRecognizer::FinishGesture;
        } else {
            result = QGestureRecognizer::CancelGesture;
        }
        break;
    }
    case QEvent::TouchUpdate: {
        if (!d->started)
            result = QGestureRecognizer::CancelGesture;
        else if (ev->touchPoints().size() == 3) {
            QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
            QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
            QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);

            if (d->lastPositions[0].isNull()) {
                d->lastPositions[0] = p1.startScreenPos().toPoint();
                d->lastPositions[1] = p2.startScreenPos().toPoint();
                d->lastPositions[2] = p3.startScreenPos().toPoint();
            }
            d->hotSpot = p1.screenPos();
            d->isHotSpotSet = true;

            int xDistance = (p1.screenPos().x() - d->lastPositions[0].x() +
                             p2.screenPos().x() - d->lastPositions[1].x() +
                             p3.screenPos().x() - d->lastPositions[2].x()) / 3;
            int yDistance = (p1.screenPos().y() - d->lastPositions[0].y() +
                             p2.screenPos().y() - d->lastPositions[1].y() +
                             p3.screenPos().y() - d->lastPositions[2].y()) / 3;

            const int distance = xDistance >= yDistance ? xDistance : yDistance;
            int elapsedTime = d->time.restart();
            if (!elapsedTime)
                elapsedTime = 1;
            d->velocityValue = 0.9 * d->velocityValue + distance / elapsedTime;
            d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();

            static const int MoveThreshold = 50;
            if (xDistance > MoveThreshold || yDistance > MoveThreshold) {
                // measure the distance to check if the direction changed
                d->lastPositions[0] = p1.screenPos().toPoint();
                d->lastPositions[1] = p2.screenPos().toPoint();
                d->lastPositions[2] = p3.screenPos().toPoint();
                QSwipeGesture::SwipeDirection horizontal =
                        xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left;
                QSwipeGesture::SwipeDirection vertical =
                        yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up;
                if (d->verticalDirection == QSwipeGesture::NoDirection)
                    d->verticalDirection = vertical;
                if (d->horizontalDirection == QSwipeGesture::NoDirection)
                    d->horizontalDirection = horizontal;
                if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) {
                    // the user has changed the direction!
                    result = QGestureRecognizer::CancelGesture;
                }
                result = QGestureRecognizer::TriggerGesture;
            } else {
                if (q->state() != Qt::NoGesture)
                    result = QGestureRecognizer::TriggerGesture;
                else
                    result = QGestureRecognizer::MayBeGesture;
            }
        } else if (ev->touchPoints().size() > 3) {
            result = QGestureRecognizer::CancelGesture;
        } else { // less than 3 touch points
            if (d->started && (ev->touchPointStates() & Qt::TouchPointPressed))
                result = QGestureRecognizer::CancelGesture;
            else if (d->started)
                result = QGestureRecognizer::Ignore;
            else
                result = QGestureRecognizer::MayBeGesture;
        }
        break;
    }
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        result = QGestureRecognizer::Ignore;
        break;
    default:
        result = QGestureRecognizer::Ignore;
        break;
    }
    return result;
}