qdeclarativepinchgenerator.cpp 10.87 KiB
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
** $QT_END_LICENSE$
****************************************************************************/
#include "qdeclarativepinchgenerator_p.h"
#include <QtTest/QtTest>
#include <QtGui/QGuiApplication>
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtGui/QStyleHints>
QT_BEGIN_NAMESPACE
QDeclarativePinchGenerator::QDeclarativePinchGenerator():
    target_(0),
    state_(Invalid),
    window_(0),
    activeSwipe_(0),
    replayTimer_(-1),
    replayBookmark_(-1),
    masterSwipe_(-1),
    replaySpeedFactor_(1.0),
    enabled_(true)
    setAcceptedMouseButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton);
    swipeTimer_.invalidate();
    device_ = new QTouchDevice;
    device_->setType(QTouchDevice::TouchScreen);
    QWindowSystemInterface::registerTouchDevice(device_);
QDeclarativePinchGenerator::~QDeclarativePinchGenerator()
    clear();
void QDeclarativePinchGenerator::componentComplete()
    QQuickItem::componentComplete();
void QDeclarativePinchGenerator::mousePressEvent(QMouseEvent *event)
    if (state_ != Idle || !enabled_) {
        event->ignore();
        return;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
} Q_ASSERT(!activeSwipe_); Q_ASSERT(!swipeTimer_.isValid()); // Start recording a pinch gesture. activeSwipe_ = new Swipe; activeSwipe_->touchPoints << event->pos(); activeSwipe_->durations << 0; swipeTimer_.start(); setState(Recording); } void QDeclarativePinchGenerator::mouseMoveEvent(QMouseEvent *event) { if (state_ != Recording || !enabled_) { event->ignore(); return; } Q_ASSERT(activeSwipe_); Q_ASSERT(swipeTimer_.isValid()); activeSwipe_->touchPoints << event->pos(); activeSwipe_->durations << swipeTimer_.elapsed(); swipeTimer_.restart(); } void QDeclarativePinchGenerator::mouseReleaseEvent(QMouseEvent *event) { if (state_ != Recording || !enabled_) { event->ignore(); return; } Q_ASSERT(activeSwipe_); Q_ASSERT(swipeTimer_.isValid()); activeSwipe_->touchPoints << event->pos(); activeSwipe_->durations << swipeTimer_.elapsed(); if (swipes_.count() == SWIPES_REQUIRED) delete swipes_.takeFirst(); swipes_ << activeSwipe_; activeSwipe_ = 0; swipeTimer_.invalidate(); if (window_ && target_) setState(Idle); else setState(Invalid); } void QDeclarativePinchGenerator::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event); if (!enabled_) { event->ignore(); return; } stop(); clear(); if (window_ && target_) setState(Idle); else setState(Invalid); } void QDeclarativePinchGenerator::keyPressEvent(QKeyEvent *e) { if (!enabled_) { e->ignore(); } if (e->key() == Qt::Key_C) { clear(); } else if (e->key() == Qt::Key_R) { replay(); } else if (e->key() == Qt::Key_S) { stop(); } else if (e->key() == Qt::Key_Plus) { setReplaySpeedFactor(replaySpeedFactor() + 0.1);
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} else if (e->key() == Qt::Key_Minus) { setReplaySpeedFactor(replaySpeedFactor() - 0.1); } else { qDebug() << metaObject()->className() << "Unsupported key event."; } } bool QDeclarativePinchGenerator::enabled() const { return enabled_; } void QDeclarativePinchGenerator::setEnabled(bool enabled) { if (enabled == enabled_) return; enabled_ = enabled; if (!enabled_) { stop(); clear(); } emit enabledChanged(); } qreal QDeclarativePinchGenerator::replaySpeedFactor() const { return replaySpeedFactor_; } void QDeclarativePinchGenerator::setReplaySpeedFactor(qreal factor) { if (factor == replaySpeedFactor_ || factor < 0.001) return; replaySpeedFactor_ = factor; emit replaySpeedFactorChanged(); } QString QDeclarativePinchGenerator::state() const { switch (state_) { case Invalid: return "Invalid"; case Idle: return "Idle"; break; case Recording: return "Recording"; break; case Replaying: return "Replaying"; break; default: Q_ASSERT(false); } return "How emberassing"; } void QDeclarativePinchGenerator::setState(GeneratorState state) { if (state == state_) return; state_ = state; emit stateChanged(); } void QDeclarativePinchGenerator::itemChange(ItemChange change, const ItemChangeData & data) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
if (change == ItemSceneChange) { window_ = data.window; if (target_) setState(Idle); } } void QDeclarativePinchGenerator::timerEvent(QTimerEvent *event) { Q_ASSERT(replayTimer_ == event->timerId()); Q_UNUSED(event); Q_ASSERT(state_ == Replaying); int slaveSwipe = masterSwipe_ ^ 1; int masterCount = swipes_.at(masterSwipe_)->touchPoints.count(); int slaveCount = swipes_.at(slaveSwipe)->touchPoints.count(); if (replayBookmark_ == 0) { QTest::touchEvent(window_, device_) .press(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)) .press(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); } else if (replayBookmark_ == (slaveCount - 1)) { if (masterCount != slaveCount) { QTest::touchEvent(window_, device_) .move(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)) .release(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); } else { QTest::touchEvent(window_, device_) .release(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)) .release(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); } } else if (replayBookmark_ == (masterCount - 1)) { QTest::touchEvent(window_, device_) .release(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)); } else { QTest::touchEvent(window_, device_) .move(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)) .move(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); } replayBookmark_++; if (replayBookmark_ >= swipes_.at(masterSwipe_)->touchPoints.count()) stop(); else { killTimer(replayTimer_); replayTimer_ = startTimer((swipes_.at(masterSwipe_)->durations.at(replayBookmark_) + 5) / replaySpeedFactor_ ); } } QQuickItem* QDeclarativePinchGenerator::target() const { return target_; } void QDeclarativePinchGenerator::setTarget(QQuickItem* target) { if (target == target_) return; target_ = target; stop(); clear(); if (window_) setState(Idle); else setState(Invalid); emit targetChanged(); }
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
void QDeclarativePinchGenerator::pinch(QPoint point1From, QPoint point1To, QPoint point2From, QPoint point2To, int interval1, int interval2, int samples1, int samples2) { Q_ASSERT(interval1 > 10); Q_ASSERT(interval2 > 10); Q_ASSERT(samples1 >= 2); // we need press and release events at minimum Q_ASSERT(samples2 >= 2); clear(); Swipe* swipe1 = new Swipe; Swipe* swipe2 = new Swipe; for (int i = 0; i < samples1; ++i) { swipe1->touchPoints << point1From + (point1To - point1From) / samples1 * i; swipe1->durations << interval1; } for (int i = 0; i < samples2; ++i) { swipe2->touchPoints << point2From + (point2To - point2From) / samples2 * i; swipe2->durations << interval2; } swipes_ << swipe1 << swipe2; Q_ASSERT(swipes_.at(0)); Q_ASSERT(swipes_.at(1)); masterSwipe_ = (samples1 >= samples2) ? 0 : 1; replayTimer_ = startTimer(swipes_.at(masterSwipe_)->durations.at(0) / replaySpeedFactor_); replayBookmark_ = 0; setState(Replaying); } void QDeclarativePinchGenerator::pinchPress(QPoint point1From, QPoint point2From) { QTest::touchEvent(window_, device_).press(0, point1From).press(1, point2From); } void QDeclarativePinchGenerator::pinchMoveTo(QPoint point1To, QPoint point2To) { QTest::touchEvent(window_, device_).move(0, point1To).move(1, point2To); } void QDeclarativePinchGenerator::pinchRelease(QPoint point1To, QPoint point2To) { QTest::touchEvent(window_, device_).release(0, point1To).release(1, point2To); } void QDeclarativePinchGenerator::replay() { if (state_ != Idle) { qDebug() << "Wrong state, will not replay pinch, state: " << state_; return; } if (swipes_.count() < SWIPES_REQUIRED) { qDebug() << "Too few swipes, cannot replay, amount: " << swipes_.count(); return; } if ((swipes_.at(0)->touchPoints.count() < 2) || (swipes_.at(1)->touchPoints.count() < 2)) { qDebug() << "Too few touchpoints, won't replay, amount: " << swipes_.at(0)->touchPoints.count() << (swipes_.at(1)->touchPoints.count() < 2); return; } masterSwipe_ = (swipes_.at(0)->touchPoints.count() >= swipes_.at(1)->touchPoints.count()) ? 0 : 1;
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
replayTimer_ = startTimer(swipes_.at(masterSwipe_)->touchPoints.count() / replaySpeedFactor_); replayBookmark_ = 0; setState(Replaying); } void QDeclarativePinchGenerator::clear() { stop(); delete activeSwipe_; activeSwipe_ = 0; if (!swipes_.isEmpty()) { qDeleteAll(swipes_); swipes_.clear(); } } void QDeclarativePinchGenerator::stop() { if (state_ != Replaying) return; // stop replay Q_ASSERT(replayTimer_ != -1); killTimer(replayTimer_); replayTimer_ = -1; setState(Idle); } int QDeclarativePinchGenerator::startDragDistance() { return qApp->styleHints()->startDragDistance(); } QT_END_NAMESPACE