From 14c8f32fb17a1361c068b92bef311259c57d382c Mon Sep 17 00:00:00 2001 From: shubinba Date: Mon, 3 Oct 2011 13:34:11 +1000 Subject: restructure of tests directory Change-Id: I9665c1a48976720597779be164d93da5087c3133 Reviewed-on: http://codereview.qt-project.org/5907 Reviewed-by: Qt Sanity Bot Reviewed-by: Natalia Shubina Reviewed-by: Juha Vuolle --- .../declarativetestplugin.pro | 36 ++ .../plugins/declarativetestplugin/locationtest.cpp | 72 ++++ .../qdeclarativelocationtestmodel.cpp | 255 ++++++++++++ .../qdeclarativelocationtestmodel_p.h | 137 ++++++ .../qdeclarativepinchgenerator.cpp | 459 +++++++++++++++++++++ .../qdeclarativepinchgenerator_p.h | 166 ++++++++ tests/plugins/declarativetestplugin/qmldir | 1 + 7 files changed, 1126 insertions(+) create mode 100644 tests/plugins/declarativetestplugin/declarativetestplugin.pro create mode 100644 tests/plugins/declarativetestplugin/locationtest.cpp create mode 100644 tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel.cpp create mode 100644 tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel_p.h create mode 100644 tests/plugins/declarativetestplugin/qdeclarativepinchgenerator.cpp create mode 100644 tests/plugins/declarativetestplugin/qdeclarativepinchgenerator_p.h create mode 100644 tests/plugins/declarativetestplugin/qmldir (limited to 'tests/plugins') diff --git a/tests/plugins/declarativetestplugin/declarativetestplugin.pro b/tests/plugins/declarativetestplugin/declarativetestplugin.pro new file mode 100644 index 00000000..8cf4902d --- /dev/null +++ b/tests/plugins/declarativetestplugin/declarativetestplugin.pro @@ -0,0 +1,36 @@ +TARGET = declarative_location_test +TARGETPATH = Qt/location/test + +include(../../../src/imports/location/qlocationimport.pri) + +QT += declarative location widgets + +DESTDIR = $$QT.location.imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INCLUDEPATH += ../../../src/imports/location +INCLUDEPATH += ../../../src/location + +# On some platforms, build both versions because debug and release +# versions are incompatible +#win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release + +HEADERS += qdeclarativepinchgenerator_p.h \ + qdeclarativelocationtestmodel_p.h \ + ../../../src/imports/location/qdeclarativecoordinate_p.h + + +SOURCES += locationtest.cpp \ + qdeclarativepinchgenerator.cpp \ + qdeclarativelocationtestmodel.cpp \ + ../../../src/imports/location/qdeclarativecoordinate.cpp + +# Tell qmake to create such makefile that qmldir and target (i.e. declarative_location) +# are both copied to qt/imports/QtMobility/location -directory, +# as the "/imports" is the default place where qmlviewer looks for plugins +# (otherwise qmlviewer -I -option is needed) + +qmldir.files += $$PWD/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir diff --git a/tests/plugins/declarativetestplugin/locationtest.cpp b/tests/plugins/declarativetestplugin/locationtest.cpp new file mode 100644 index 00000000..caa796b4 --- /dev/null +++ b/tests/plugins/declarativetestplugin/locationtest.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qdeclarativepinchgenerator_p.h" +#include "qdeclarativelocationtestmodel_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class QLocationDeclarativeTestModule: public QDeclarativeExtensionPlugin +{ + Q_OBJECT + +public: + virtual void registerTypes(const char* uri) { + qDebug() << "registerTypes in new test plugin: " << uri; + if (QLatin1String(uri) == QLatin1String("Qt.location.test")) { + // This version numbering is not correct. It is just something to get going + // until the proper versioning scheme of QML plugins in Qt5 is agreed upon. + qmlRegisterType(uri, 5, 0, "PinchGenerator"); + qmlRegisterType(uri, 5, 0, "TestModel"); + } else { + qDebug() << "Unsupported URI given to load location test QML plugin: " << QLatin1String(uri); + } + } +}; + +#include "locationtest.moc" + +QT_END_NAMESPACE + +Q_EXPORT_PLUGIN2(declarative_location_test, QT_PREPEND_NAMESPACE(QLocationDeclarativeTestModule)) diff --git a/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel.cpp b/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel.cpp new file mode 100644 index 00000000..12718054 --- /dev/null +++ b/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativelocationtestmodel_p.h" +#include +#include +#include +#include + +QDeclarativeLocationTestModel::QDeclarativeLocationTestModel(QObject *parent): + QAbstractListModel(parent), + delay_(0), + datacount_(0), + componentCompleted_(false), + crazyLevel_(0), + crazyMode_(false) +{ + // seed crazy random generator + qsrand(QTime(0,0,0).secsTo(QTime::currentTime()) + QCoreApplication::applicationPid()); + timer_.setSingleShot(true); + connect(&timer_, SIGNAL(timeout()), this, SLOT(timerFired())); + // Establish role names so that they can be queried from this model + QHash roleNames; + roleNames = QAbstractItemModel::roleNames(); + roleNames.insert(TestDataRole, "modeldata"); + setRoleNames(roleNames); +} + +QDeclarativeLocationTestModel::~QDeclarativeLocationTestModel() +{ + if (timer_.isActive()) + timer_.stop(); + if (!dataobjects_.isEmpty()) { + qDeleteAll(dataobjects_); + dataobjects_.clear(); + } +} + +void QDeclarativeLocationTestModel::timerFired() +{ + //qDebug() << "timer fired" ; + repopulate(); + if (crazyMode_) { + //qDebug() << "raw randomw value: " << qrand(); + int delay = (qAbs(qrand()) % crazyLevel_); // writing software is exact science + delay = qMax(1000, delay); // 3 ms at minimum + qDebug() << "starting timer with : " << delay; + timer_.start(delay); + } +} + +void QDeclarativeLocationTestModel::componentComplete() +{ + componentCompleted_ = true; + scheduleRepopulation(); +} + + +int QDeclarativeLocationTestModel::datacount() const +{ + return datacount_; +} + +void QDeclarativeLocationTestModel::setDatacount(int datacount) +{ + if (datacount_ == datacount) + return; + datacount_ = datacount; + emit datacountChanged(); + scheduleRepopulation(); +} + +int QDeclarativeLocationTestModel::delay() const +{ + return delay_; +} + +void QDeclarativeLocationTestModel::setDelay(int delay) +{ + if (delay_ == delay) + return; + delay_ = delay; + emit delayChanged(); +} + +QString QDeclarativeLocationTestModel::datatype() const +{ + return datatype_; +} + +void QDeclarativeLocationTestModel::setDatatype(QString datatype) +{ + if (datatype_ == datatype) + return; + datatype_ = datatype; + emit datatypeChanged(); + scheduleRepopulation(); +} + +int QDeclarativeLocationTestModel::crazyLevel() const +{ + return crazyLevel_; +} + +void QDeclarativeLocationTestModel::setCrazyLevel(int level) +{ + if (level == crazyLevel_) + return; + crazyLevel_ = level; + reset(); + scheduleRepopulation(); + emit crazyLevelChanged(); +} + +bool QDeclarativeLocationTestModel::crazyMode() const +{ + return crazyMode_; +} + +void QDeclarativeLocationTestModel::setCrazyMode(bool mode) +{ + if (mode == crazyMode_) + return; + crazyMode_ = mode; + //if (!crazyMode_) + //reset(); + //else + if (crazyMode_) + scheduleRepopulation(); + emit crazyModeChanged(); +} + +// only coordinate datatype for now to get started with, +// refactor if more usecases for the model emerge. +void QDeclarativeLocationTestModel::repopulate() +{ + double latitude = -30; + double longitude = 153; + beginResetModel(); + if (!dataobjects_.isEmpty()) { + qDeleteAll(dataobjects_); + dataobjects_.clear(); + } + int datacount = datacount_; + if (crazyMode_) + datacount = (qAbs(qrand()) % datacount_); + + qDebug() << "generating random content: " << datacount; + + for (int i = 0; i < datacount; ++i) { + DataObject* dataobject = new DataObject; + QDeclarativeCoordinate* coordinate = new QDeclarativeCoordinate(QGeoCoordinate(latitude,longitude)); + dataobject->coordinate_ = coordinate; + dataobjects_.append(dataobject); + longitude -= 0.2; + latitude += 0.2; + } + endResetModel(); +} + +void QDeclarativeLocationTestModel::reset() +{ + if (timer_.isActive()) + timer_.stop(); + beginResetModel(); + if (!dataobjects_.isEmpty()) { + qDeleteAll(dataobjects_); + dataobjects_.clear(); + } + endResetModel(); +} + +void QDeclarativeLocationTestModel::scheduleRepopulation() +{ + if (!componentCompleted_) + return; + if (datacount_ <= 0) { + qDebug() << __FUNCTION__ << "won't schedule model, invalid datacount: " << datacount_; + return; + } + + if (timer_.isActive()) + timer_.stop(); + + if (crazyMode_) { + // start generating arbitrary amount of data at arbitrary intervals + int delay = (qAbs(qrand()) % crazyLevel_); // writing software is exact science + delay = qMax(3, delay); // 3 ms at minimum + qDebug() << "starting timer with : " << delay; + timer_.start(delay); + } else { + // just update + if (delay_ > 0) + timer_.start(delay_); + else + repopulate(); + } +} + +int QDeclarativeLocationTestModel::rowCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent); + return dataobjects_.count(); +} + +// Returns the stored under the given role for the item referred to by the index. +QVariant QDeclarativeLocationTestModel::data(const QModelIndex& index, int role) const +{ + switch (role) { + case TestDataRole: + if (dataobjects_.at(index.row())) { + return QVariant::fromValue(qobject_cast(dataobjects_.at(index.row()))); + } + break; + } + return QVariant(); +} diff --git a/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel_p.h b/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel_p.h new file mode 100644 index 00000000..9e3061f0 --- /dev/null +++ b/tests/plugins/declarativetestplugin/qdeclarativelocationtestmodel_p.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVELOCATIONTESTMODEL_H +#define QDECLARATIVELOCATIONTESTMODEL_H + +#include +#include +#include +#include +#include +#include + +class DataObject: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeCoordinate* coordinate READ coordinate CONSTANT) + +public: + DataObject() : coordinate_(0) {} + ~DataObject() {delete coordinate_;} + + QDeclarativeCoordinate* coordinate_; + QDeclarativeCoordinate* coordinate() const {return coordinate_;} +}; + +class QDeclarativeLocationTestModel : public QAbstractListModel, public QDeclarativeParserStatus +{ + Q_OBJECT + Q_PROPERTY(int datacount READ datacount WRITE setDatacount NOTIFY datacountChanged) + Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY delayChanged) + Q_PROPERTY(bool crazyMode READ crazyMode WRITE setCrazyMode NOTIFY crazyModeChanged) + Q_PROPERTY(int crazyLevel READ crazyLevel WRITE setCrazyLevel NOTIFY crazyLevelChanged) + Q_PROPERTY(QString datatype READ datatype WRITE setDatatype NOTIFY datatypeChanged) + Q_INTERFACES(QDeclarativeParserStatus) + +public: + QDeclarativeLocationTestModel(QObject* parent = 0); + ~QDeclarativeLocationTestModel(); + + enum Roles { + TestDataRole = Qt::UserRole + 500 + }; + + // from QDeclarativeParserStatus + virtual void componentComplete(); + virtual void classBegin() {} + + // From QAbstractListModel + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + + int datacount() const; + void setDatacount(int datacount); + + int delay() const; + void setDelay(int delay); + + int crazyLevel() const; + void setCrazyLevel(int level); + + bool crazyMode() const; + void setCrazyMode(bool mode); + + QString datatype() const; + void setDatatype(QString datatype); + + //Q_INVOKABLE void clear(); + Q_INVOKABLE void reset(); + //Q_INVOKABLE void reset(); + +signals: + void countChanged(); + void datacountChanged(); + void datatypeChanged(); + void delayChanged(); + void modelChanged(); + void crazyLevelChanged(); + void crazyModeChanged(); + +private slots: + void repopulate(); + void timerFired(); + +private: + void scheduleRepopulation(); + +private: + int delay_; + int datacount_; + bool componentCompleted_; + QString datatype_; + QTimer timer_; + QList dataobjects_; + int crazyLevel_; + bool crazyMode_; +}; + +#endif diff --git a/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator.cpp b/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator.cpp new file mode 100644 index 00000000..c32c77ef --- /dev/null +++ b/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator.cpp @@ -0,0 +1,459 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativepinchgenerator_p.h" +#include +#include + + +QDeclarativePinchGenerator::QDeclarativePinchGenerator(): + target_(0), + state_(Invalid), + canvas_(0), + activeSwipe_(0), + replayTimer_(-1), + replayBookmark_(-1), + masterSwipe_(-1), + touchPointId_(0), + replaySpeedFactor_(1.0), + enabled_(true) +{ + setAcceptedMouseButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton); + swipeTimer_.invalidate(); +} + +QDeclarativePinchGenerator::~QDeclarativePinchGenerator() +{ + if (!swipeList1_.isEmpty()) { + qDeleteAll(swipeList1_); + swipeList1_.clear(); + } + if (!swipeList2_.isEmpty()) { + qDeleteAll(swipeList2_); + swipeList2_.clear(); + } +} + +void QDeclarativePinchGenerator::componentComplete() +{ + QSGItem::componentComplete(); +} + +void QDeclarativePinchGenerator::mousePressEvent(QMouseEvent *event) +{ + if (state_ != Idle || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(!activeSwipe_); + Q_ASSERT(!swipeTimer_.isValid()); + // Start recording a pinch gesture. + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointPressed) { + activeSwipe_ = new Swipe; + //touchPointId_ = 0; + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration = 0; + activeSwipe_->touchPointDurations.append(0); + swipeTimer_.start(); + setState(Recording); + } else { + Q_ASSERT(false); // no! + } +} + +bool QDeclarativePinchGenerator::enabled() const +{ + return enabled_; +} + + +void QDeclarativePinchGenerator::setEnabled(bool enabled) +{ + if (enabled == enabled_) + return; + enabled_ = enabled; + if (!enabled_) { + stop(); + clear(); + } + emit enabledChanged(); +} + +QTouchEvent::TouchPoint QDeclarativePinchGenerator::mouseEventToTouchPoint(QMouseEvent *event) +{ + QTouchEvent::TouchPoint touchPoint; + switch (event->type()) { + //case QEvent::GraphicsSceneMousePress: + case QEvent::MouseButtonPress: + touchPoint.setState(Qt::TouchPointPressed); + break; + //case QEvent::GraphicsSceneMouseMove: + case QEvent::MouseMove: + touchPoint.setState(Qt::TouchPointMoved); + break; + //case QEvent::GraphicsSceneMouseRelease: + case QEvent::MouseButtonRelease: + touchPoint.setState(Qt::TouchPointReleased); + break; + default: + break; + } + //touchPoint.setId(touchPointId_++); // running number + touchPoint.setId(0); + touchPoint.setPressure(0.75); + touchPoint.setPos(event->pos()); + touchPoint.setLastPos(event->pos()); + touchPoint.setScenePos(target_->mapToScene(event->pos())); + touchPoint.setLastScenePos(target_->mapToScene(event->pos())); + return touchPoint; +} + +// fixme this is excessive +QTouchEvent::TouchPoint QDeclarativePinchGenerator::convertToPrimary(QTouchEvent::TouchPoint original) +{ + QTouchEvent::TouchPoint touchPoint; + touchPoint.setState(original.state() | Qt::TouchPointPrimary); + touchPoint.setId(original.id() + 1); + touchPoint.setPressure(original.pressure()); + touchPoint.setPos(original.pos()); + touchPoint.setLastPos(original.lastPos()); + touchPoint.setScenePos(original.scenePos()); + touchPoint.setLastScenePos(original.lastScenePos()); + return touchPoint; + +} + +void QDeclarativePinchGenerator::mouseMoveEvent(QMouseEvent *event) +{ + if (state_ != Recording || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(activeSwipe_); + Q_ASSERT(swipeTimer_.isValid()); + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointMoved) { + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration += swipeTimer_.elapsed(); + activeSwipe_->touchPointDurations.append(swipeTimer_.elapsed()); + swipeTimer_.restart(); + } else { + Q_ASSERT(false); // no! + } +} + +void QDeclarativePinchGenerator::mouseReleaseEvent(QMouseEvent *event) +{ + if (state_ != Recording || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(activeSwipe_); + Q_ASSERT(swipeTimer_.isValid()); + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointReleased) { + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration += swipeTimer_.elapsed(); + activeSwipe_->touchPointDurations.append(swipeTimer_.elapsed()); + } else { + Q_ASSERT(false); // no! + } + if (swipes_.count() == SWIPES_REQUIRED) + delete swipes_.takeFirst(); + swipes_.append(activeSwipe_); + activeSwipe_ = 0; + swipeTimer_.invalidate(); + if (canvas_ && target_) setState(Idle); else setState(Invalid); + emit swipesChanged(); +} + +QList QDeclarativePinchGenerator::swipe1() +{ + if (swipes_.count() < 1) + return QList(); + if (!swipeList1_.isEmpty()) { + qDeleteAll(swipeList1_); + swipeList1_.clear(); + } + for (int i = 0; i < swipes_.at(0)->touchPoints.count(); ++i) { + TouchPoint* touchPoint = new TouchPoint( + swipes_.at(0)->touchPoints.at(i).scenePos().x(), + swipes_.at(0)->touchPoints.at(i).scenePos().y(), + static_cast(swipes_.at(0)->touchPoints.at(i).state())); + swipeList1_.append(touchPoint); + } + return swipeList1_; +} + +QList QDeclarativePinchGenerator::swipe2() +{ + if (swipes_.count() < 2) + return QList(); + if (!swipeList2_.isEmpty()) { + qDeleteAll(swipeList2_); + swipeList2_.clear(); + } + for (int i = 0; i < swipes_.at(1)->touchPoints.count(); ++i) { + TouchPoint* touchPoint = new TouchPoint( + static_cast(swipes_.at(1)->touchPoints.at(i).scenePos().x()), + static_cast(swipes_.at(1)->touchPoints.at(i).scenePos().y()), + static_cast(swipes_.at(1)->touchPoints.at(i).state())); + swipeList2_.append(touchPoint); + } + return swipeList2_; +} + +qreal QDeclarativePinchGenerator::replaySpeedFactor() const +{ + return replaySpeedFactor_; +} + +void QDeclarativePinchGenerator::setReplaySpeedFactor(qreal factor) +{ + if (factor == replaySpeedFactor_ || factor < 0.001) + return; + replaySpeedFactor_ = factor; + emit replaySpeedFactorChanged(); +} + +void QDeclarativePinchGenerator::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + if (!enabled_) { + event->ignore(); + return; + } + stop(); + clear(); + if (canvas_ && target_) setState(Idle); else setState(Invalid); +} + +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"; +} + +int QDeclarativePinchGenerator::count() const +{ + return swipes_.count(); +} + +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); + } else if (e->key() == Qt::Key_Minus) { + setReplaySpeedFactor(replaySpeedFactor() - 0.1); + } else { + qDebug() << metaObject()->className() << "Unsupported key event."; + } +} +void QDeclarativePinchGenerator::setState(GeneratorState state) +{ + if (state == state_) + return; + state_ = state; + emit stateChanged(); +} + +void QDeclarativePinchGenerator::itemChange(ItemChange change, const ItemChangeData & data) +{ + if (change == ItemSceneChange) { + canvas_ = data.canvas; + if (target_) + setState(Idle); + } +} + +void QDeclarativePinchGenerator::timerEvent(QTimerEvent *event) +{ + Q_ASSERT(replayTimer_ == event->timerId()); + Q_ASSERT(state_ == Replaying); + + // Create touchevent. May have one or two touchpoints. + QTouchEvent* touchEvent; + switch (swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_).state()) { + case (Qt::TouchPointPressed): + touchEvent = new QTouchEvent(QEvent::TouchBegin,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + case (Qt::TouchPointMoved): + touchEvent = new QTouchEvent(QEvent::TouchUpdate,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + case (Qt::TouchPointReleased): + touchEvent = new QTouchEvent(QEvent::TouchEnd,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + default: + Q_ASSERT(false); + break; + } + // Set touch points. Master swipe has touchpoints as it was chosen to have more touchpoints. + // For the other swipe we need to check. + QList touchPoints; + // The primary touch point generates also mouse events. Does not work at the moment because + // we dispatch the touch event via canvas rather than the qApp. However qApp dispatching + // seems to miss some events arbitrarily. + touchPoints.append(convertToPrimary(swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))); + //touchPoints.append(swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)); + + int slaveSwipe(1); + if (masterSwipe_ == 1) + slaveSwipe = 0; + if (replayBookmark_ < swipes_.at(slaveSwipe)->touchPoints.count()) + touchPoints.append(swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); + touchEvent->setTouchPoints(touchPoints); + canvas_->sendEvent(target_, touchEvent); + delete touchEvent; + + replayBookmark_++; + if (replayBookmark_ >= swipes_.at(masterSwipe_)->touchPoints.count()) { + qDebug() << "Pinch replay finished!"; + stop(); + } else { + killTimer(replayTimer_); + replayTimer_ = startTimer((swipes_.at(masterSwipe_)->touchPointDurations.at(replayBookmark_) + 5) / replaySpeedFactor_ ); + } +} + +QSGItem* QDeclarativePinchGenerator::target() const +{ + return target_; +} + +void QDeclarativePinchGenerator::setTarget(QSGItem* target) +{ + if (target == target_) + return; + target_ = target; + stop(); + clear(); + if (canvas_) + setState(Idle); + else + setState(Invalid); + emit targetChanged(); +} + +Q_INVOKABLE 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; + } + if (swipes_.at(0)->touchPoints.back().state() != Qt::TouchPointReleased) { + qDebug() << "Swipe misses release event, won't replay."; + return; + } + if (swipes_.at(1)->touchPoints.back().state() != Qt::TouchPointReleased) { + qDebug() << "Swipe misses release event, won't replay."; + return; + } + + Q_ASSERT(swipes_.at(0)->touchPoints.count() == swipes_.at(0)->touchPointDurations.count()); + Q_ASSERT(swipes_.at(1)->touchPoints.count() == swipes_.at(1)->touchPointDurations.count()); + + // 'nuff checkin' already, start replay. let the one with more swipes dictate + if (swipes_.at(0)->touchPoints.count() >= swipes_.at(1)->touchPoints.count()) + masterSwipe_ = 0; + else + masterSwipe_ = 1; + + replayTimer_ = startTimer(swipes_.at(masterSwipe_)->touchPointDurations.at(0) / replaySpeedFactor_); + replayBookmark_ = 0; + setState(Replaying); +} + +Q_INVOKABLE void QDeclarativePinchGenerator::clear() +{ + stop(); + delete activeSwipe_; + activeSwipe_ = 0; + if (!swipes_.isEmpty()) { + qDeleteAll(swipes_); + swipes_.clear(); + emit countChanged(); + emit swipesChanged(); + } +} + +Q_INVOKABLE void QDeclarativePinchGenerator::stop() +{ + if (state_ != Replaying) + return; + // stop replay + Q_ASSERT(replayTimer_ != -1); + killTimer(replayTimer_); + replayTimer_ = -1; + setState(Idle); +} diff --git a/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator_p.h b/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator_p.h new file mode 100644 index 00000000..536d09f9 --- /dev/null +++ b/tests/plugins/declarativetestplugin/qdeclarativepinchgenerator_p.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEPINCHGENERATOR_H +#define QDECLARATIVEPINCHGENERATOR_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// how many concurrent "swipes" should we have +// bit overkill here first I thought support random about of swipes (1..x) +// but thats for later +#define SWIPES_REQUIRED 2 + +typedef struct { + int totalDuration; // not sure if needed + QList touchPoints; + QList touchPointDurations; +} Swipe; + +// total overkill fixme +class TouchPoint: public QObject +{ + Q_OBJECT + Q_PROPERTY(double targetX READ targetX CONSTANT) + Q_PROPERTY(double targetY READ targetY CONSTANT) + Q_PROPERTY(int touchState READ touchState CONSTANT) +public: + TouchPoint(double x, double y, int state): targetX_(x), targetY_(y),touchState_(state) {} + double targetX() {return targetX_;} + double targetY() {return targetY_;} + double touchState() {return touchState_;} + double targetX_; + double targetY_; + int touchState_; +}; + +class QDeclarativePinchGenerator : public QSGItem +{ + Q_OBJECT + + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(QString state READ state NOTIFY stateChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(qreal replaySpeedFactor READ replaySpeedFactor WRITE setReplaySpeedFactor NOTIFY replaySpeedFactorChanged) + Q_PROPERTY(QSGItem* target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QList swipe1 READ swipe1 NOTIFY swipesChanged) + Q_PROPERTY(QList swipe2 READ swipe2 NOTIFY swipesChanged) + Q_INTERFACES(QDeclarativeParserStatus) + +public: + QDeclarativePinchGenerator(); + ~QDeclarativePinchGenerator(); + + QString state() const; + int count() const; + QSGItem* target() const; + void setTarget(QSGItem* target); + qreal replaySpeedFactor() const; + void setReplaySpeedFactor(qreal factor); + bool enabled() const; + void setEnabled(bool enabled); + + QList swipe1(); + QList swipe2(); + + Q_INVOKABLE void replay(); + Q_INVOKABLE void clear(); + Q_INVOKABLE void stop(); + +signals: + void stateChanged(); + void countChanged(); + void targetChanged(); + void swipesChanged(); + void replaySpeedFactorChanged(); + void enabledChanged(); + +public: + enum GeneratorState { + Invalid = 0, + Idle = 1, + Recording = 2, + Replaying = 3 + }; + + // from QDeclarativeParserStatus + virtual void componentComplete(); + // from QSGItem + void itemChange(ItemChange change, const ItemChangeData & data); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void timerEvent(QTimerEvent *event); + +private: + void setState(GeneratorState state); + QTouchEvent::TouchPoint mouseEventToTouchPoint(QMouseEvent* event); + QTouchEvent::TouchPoint convertToPrimary(QTouchEvent::TouchPoint original); + +private: + QSGItem* target_; + GeneratorState state_; + QSGCanvas* canvas_; + QList swipes_; + Swipe* activeSwipe_; + QElapsedTimer swipeTimer_; + int replayTimer_; + int replayBookmark_; + int masterSwipe_; + int touchPointId_; + qreal replaySpeedFactor_; + QList swipeList1_; + QList swipeList2_; + bool enabled_; +}; + +#endif diff --git a/tests/plugins/declarativetestplugin/qmldir b/tests/plugins/declarativetestplugin/qmldir new file mode 100644 index 00000000..f35dd9c1 --- /dev/null +++ b/tests/plugins/declarativetestplugin/qmldir @@ -0,0 +1 @@ +plugin declarative_location_test -- cgit v1.2.1