diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-04-15 14:07:24 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-05-07 14:17:46 +0000 |
commit | 4ee1b67b24773148b26e777bcfca2ff918974c82 (patch) | |
tree | 353e77b37cdbf29965e64070a9b0282acecbb6d6 /examples/location/planespotter | |
parent | 5a9b047c225ccd5a19bd863c807d2582517ba3e7 (diff) | |
download | qtlocation-4ee1b67b24773148b26e777bcfca2ff918974c82.tar.gz |
Provide new planespotter example
This diversifies the location examples as it adds a relatively small
example. Short of the places examples there is only one large
demo-like mapviewer example.
This new example demonstrates the following features:
- integration of C++ types into QML
- coordinate animations
- fitting viewport of maps
Change-Id: Id0b5b9669cfd1d98bb5dce7d7d42d220efd60142
Task-number: QTBUG-45415
Reviewed-by: Michal Klocek <michal.klocek@theqtcompany.com>
Reviewed-by: Alessandro Portale <alessandro.portale@theqtcompany.com>
Diffstat (limited to 'examples/location/planespotter')
-rw-r--r-- | examples/location/planespotter/Plane.qml | 115 | ||||
-rw-r--r-- | examples/location/planespotter/airplane.png | bin | 0 -> 831 bytes | |||
-rw-r--r-- | examples/location/planespotter/main.cpp | 201 | ||||
-rw-r--r-- | examples/location/planespotter/planespotter.pro | 10 | ||||
-rw-r--r-- | examples/location/planespotter/planespotter.qml | 226 | ||||
-rw-r--r-- | examples/location/planespotter/qml.qrc | 7 |
6 files changed, 559 insertions, 0 deletions
diff --git a/examples/location/planespotter/Plane.qml b/examples/location/planespotter/Plane.qml new file mode 100644 index 00000000..8037f153 --- /dev/null +++ b/examples/location/planespotter/Plane.qml @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtLocation 5.5 + +//! [PlaneMapQuick1] +// Plane.qml +MapQuickItem { + id: plane + property string pilotName; + property int bearing: 0; + + anchorPoint.x: image.width/2 + anchorPoint.y: image.height/2 + + sourceItem: Grid { + //... +//! [PlaneMapQuick1] + columns: 1 + Grid { + horizontalItemAlignment: Grid.AlignHCenter + Image { + id: image + rotation: bearing + source: "airplane.png" + } + Rectangle { + id: bubble + color: "lightblue" + border.width: 1 + width: text.width * 1.3 + height: text.height * 1.3 + radius: 5 + Text { + id: text + anchors.centerIn: parent + text: pilotName + } + } + } + + Rectangle { + id: message + color: "lightblue" + border.width: 1 + width: banner.width * 1.3 + height: banner.height * 1.3 + radius: 5 + opacity: 0 + Text { + id: banner + anchors.centerIn: parent + } + SequentialAnimation { + id: playMessage + running: false + NumberAnimation { target: message; + property: "opacity"; + to: 1.0; + duration: 200 + easing.type: Easing.InOutQuad + } + PauseAnimation { duration: 1000 } + NumberAnimation { target: message; + property: "opacity"; + to: 0.0; + duration: 200} + } + } + } + function showMessage(message) { + banner.text = message + playMessage.start() +//! [PlaneMapQuick2] + } +} +//! [PlaneMapQuick2] diff --git a/examples/location/planespotter/airplane.png b/examples/location/planespotter/airplane.png Binary files differnew file mode 100644 index 00000000..080460dd --- /dev/null +++ b/examples/location/planespotter/airplane.png diff --git a/examples/location/planespotter/main.cpp b/examples/location/planespotter/main.cpp new file mode 100644 index 00000000..c71a6999 --- /dev/null +++ b/examples/location/planespotter/main.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QObject> +#include <QTime> +#include <QBasicTimer> +#include <QDebug> +#include <QEasingCurve> +#include <QGeoCoordinate> +#include <QtPositioning/private/qgeoprojection_p.h> + +#define ANIMATION_DURATION 4000 + +//! [PlaneController1] +class PlaneController: public QObject +{ + Q_OBJECT + Q_PROPERTY(QGeoCoordinate position READ position WRITE setPosition NOTIFY positionChanged) +//! [PlaneController1] + //! [C++Pilot1] + Q_PROPERTY(QGeoCoordinate from READ from WRITE setFrom NOTIFY fromChanged) + Q_PROPERTY(QGeoCoordinate to READ to WRITE setTo NOTIFY toChanged) + //! [C++Pilot1] + +public: + PlaneController() + { + easingCurve.setType(QEasingCurve::InOutQuad); + easingCurve.setPeriod(ANIMATION_DURATION); + } + + void setFrom(const QGeoCoordinate& from) + { + fromCoordinate = from; + } + + QGeoCoordinate from() const + { + return fromCoordinate; + } + + void setTo(const QGeoCoordinate& to) + { + toCoordinate = to; + } + + QGeoCoordinate to() const + { + return toCoordinate; + } + + void setPosition(const QGeoCoordinate &c) { + if (currentPosition == c) + return; + + currentPosition = c; + emit positionChanged(); + } + + QGeoCoordinate position() const + { + return currentPosition; + } + + Q_INVOKABLE bool isFlying() const { + return timer.isActive(); + } + +//! [C++Pilot2] +public slots: + void startFlight() + { + if (timer.isActive()) + return; + + startTime = QTime::currentTime(); + finishTime = startTime.addMSecs(ANIMATION_DURATION); + + timer.start(15, this); + emit departed(); + } +//! [C++Pilot2] + + void swapDestinations() { + if (currentPosition == toCoordinate) { + // swap destinations + toCoordinate = fromCoordinate; + fromCoordinate = currentPosition; + } + } + +signals: + void positionChanged(); + void arrived(); + void departed(); + void toChanged(); + void fromChanged(); + +protected: + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE + { + if (!event) + return; + + if (event->timerId() == timer.timerId()) + updatePosition(); + else + QObject::timerEvent(event); + } + +private: + //! [C++Pilot3] + void updatePosition() + { + // simple progress animation + qreal progress; + QTime current = QTime::currentTime(); + if (current >= finishTime) { + progress = 1.0; + timer.stop(); + } else { + progress = ((qreal)startTime.msecsTo(current) / ANIMATION_DURATION); + } + + setPosition(QGeoProjection::coordinateInterpolation( + fromCoordinate, toCoordinate, easingCurve.valueForProgress(progress))); + + if (!timer.isActive()) + emit arrived(); + } + //! [C++Pilot3] + +private: + QGeoCoordinate currentPosition; + QGeoCoordinate fromCoordinate, toCoordinate; + QBasicTimer timer; + QTime startTime, finishTime; + QEasingCurve easingCurve; +//! [PlaneController2] + // ... +}; +//! [PlaneController2] + +//! [PlaneControllerMain] +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + PlaneController oslo2berlin; + PlaneController berlin2london; + + QQmlApplicationEngine engine; + engine.rootContext()->setContextProperty("oslo2Berlin", &oslo2berlin); + engine.rootContext()->setContextProperty("berlin2London", &berlin2london); + engine.load(QUrl(QStringLiteral("qrc:/planespotter.qml"))); + + return app.exec(); +} +//! [PlaneControllerMain] + +#include "main.moc" diff --git a/examples/location/planespotter/planespotter.pro b/examples/location/planespotter/planespotter.pro new file mode 100644 index 00000000..d3be902c --- /dev/null +++ b/examples/location/planespotter/planespotter.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = planespotter +QT += qml quick positioning positioning-private location + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/location/planespotter +INSTALLS += target diff --git a/examples/location/planespotter/planespotter.qml b/examples/location/planespotter/planespotter.qml new file mode 100644 index 00000000..59b8b00b --- /dev/null +++ b/examples/location/planespotter/planespotter.qml @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Window 2.2 +import QtPositioning 5.5 +import QtLocation 5.5 + +Window { + width: 700 + height: 500 + visible: true + + property variant topLeftEurope: QtPositioning.coordinate(60.5, 0.0) + property variant bottomRightEurope: QtPositioning.coordinate(51.0, 14.0) + property variant viewOfEurope: + QtPositioning.rectangle(topLeftEurope, bottomRightEurope) + + property variant berlin: QtPositioning.coordinate(52.5175, 13.384) + property variant oslo: QtPositioning.coordinate(59.9154, 10.7425) + property variant london: QtPositioning.coordinate(51.5, 0.1275) + + Map { + id: mapOfEurope + anchors.centerIn: parent; + anchors.fill: parent + plugin: Plugin { + name: "osm" + } + + Plane { + id: qmlPlane + pilotName: "QML" + coordinate: oslo2Berlin.position + + SequentialAnimation { + id: qmlPlaneAnimation + property real rotationDirection : 0; + NumberAnimation { + target: qmlPlane; property: "bearing"; duration: 1000 + easing.type: Easing.InOutQuad + to: qmlPlaneAnimation.rotationDirection + } + //! [QmlPlane1] + CoordinateAnimation { + id: coordinateAnimation; duration: 5000 + target: oslo2Berlin; property: "position" + easing.type: Easing.InOutQuad + } + //! [QmlPlane1] + + onStopped: { + if (coordinateAnimation.to === berlin) + qmlPlane.showMessage(qsTr("Hello Berlin!")) + else if (coordinateAnimation.to === oslo) + qmlPlane.showMessage(qsTr("Hello Oslo!")) + } + onStarted: { + if (coordinateAnimation.from === oslo) + qmlPlane.showMessage(qsTr("See you Oslo!")) + else if (coordinateAnimation.from === berlin) + qmlPlane.showMessage(qsTr("See you Berlin!")) + } + } + + //! [QmlPlane2] + MouseArea { + anchors.fill: parent + onClicked: { + if (qmlPlaneAnimation.running) { + console.log("Plane still in the air."); + return; + } + + if (oslo2Berlin.position === berlin) { + coordinateAnimation.from = berlin; + coordinateAnimation.to = oslo; + } else if (oslo2Berlin.position === oslo) { + coordinateAnimation.from = oslo; + coordinateAnimation.to = berlin; + } + + qmlPlaneAnimation.rotationDirection = oslo2Berlin.position.azimuthTo(coordinateAnimation.to) + qmlPlaneAnimation.start() + } + } + //! [QmlPlane2] + Component.onCompleted: { + oslo2Berlin.position = oslo; + } + } + + //! [CppPlane1] + Plane { + id: cppPlane + pilotName: "C++" + coordinate: berlin2London.position + + MouseArea { + anchors.fill: parent + onClicked: { + if (cppPlaneAnimation.running || berlin2London.isFlying()) { + console.log("Plane still in the air."); + return; + } + + berlin2London.swapDestinations(); + cppPlaneAnimation.rotationDirection = berlin2London.position.azimuthTo(berlin2London.to) + cppPlaneAnimation.start(); + cppPlane.departed(); + } + } + //! [CppPlane1] + //! [CppPlane3] + SequentialAnimation { + id: cppPlaneAnimation + property real rotationDirection : 0; + NumberAnimation { + target: cppPlane; property: "bearing"; duration: 1000 + easing.type: Easing.InOutQuad + to: cppPlaneAnimation.rotationDirection + } + ScriptAction { script: berlin2London.startFlight() } + } + //! [CppPlane3] + + Component.onCompleted: { + berlin2London.position = berlin; + berlin2London.to = london; + berlin2London.from = berlin; + berlin2London.arrived.connect(arrived) + } + + function arrived(){ + if (berlin2London.to === berlin) + cppPlane.showMessage(qsTr("Hello Berlin!")) + else if (berlin2London.to === london) + cppPlane.showMessage(qsTr("Hello London!")) + } + + function departed(){ + if (berlin2London.from === berlin) + cppPlane.showMessage(qsTr("See you Berlin!")) + else if (berlin2London.from === london) + cppPlane.showMessage(qsTr("See you London!")) + } + //! [CppPlane2] + } + //! [CppPlane2] + + onWidthChanged: { + if (width > 0) + mapOfEurope.fitViewportToGeoShape(viewOfEurope) + } + + onHeightChanged: { + if (height > 0) + mapOfEurope.fitViewportToGeoShape(viewOfEurope) + } + } + + Rectangle { + id: infoBox + anchors.centerIn: parent + color: "white" + border.width: 1 + width: text.width * 1.3 + height: text.height * 1.3 + radius: 5 + Text { + id: text + anchors.centerIn: parent + text: qsTr("Hit the plane to start the flight!") + } + + Timer { + interval: 5000; running: true; repeat: false; + onTriggered: fadeOut.start() + } + + NumberAnimation { + id: fadeOut; target: infoBox; + property: "opacity"; + to: 0.0; + duration: 200 + easing.type: Easing.InOutQuad + } + } +} diff --git a/examples/location/planespotter/qml.qrc b/examples/location/planespotter/qml.qrc new file mode 100644 index 00000000..6903ec0f --- /dev/null +++ b/examples/location/planespotter/qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>planespotter.qml</file> + <file>Plane.qml</file> + <file>airplane.png</file> + </qresource> +</RCC> |