1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2017 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the examples of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:BSD$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** BSD License Usage |
18 | ** Alternatively, you may use this file under the terms of the BSD license |
19 | ** as follows: |
20 | ** |
21 | ** "Redistribution and use in source and binary forms, with or without |
22 | ** modification, are permitted provided that the following conditions are |
23 | ** met: |
24 | ** * Redistributions of source code must retain the above copyright |
25 | ** notice, this list of conditions and the following disclaimer. |
26 | ** * Redistributions in binary form must reproduce the above copyright |
27 | ** notice, this list of conditions and the following disclaimer in |
28 | ** the documentation and/or other materials provided with the |
29 | ** distribution. |
30 | ** * Neither the name of The Qt Company Ltd nor the names of its |
31 | ** contributors may be used to endorse or promote products derived |
32 | ** from this software without specific prior written permission. |
33 | ** |
34 | ** |
35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
46 | ** |
47 | ** $QT_END_LICENSE$ |
48 | ** |
49 | ****************************************************************************/ |
50 | |
51 | #include <QGuiApplication> |
52 | #include <QQmlApplicationEngine> |
53 | #include <QQmlContext> |
54 | #include <QObject> |
55 | #include <QTime> |
56 | #include <QBasicTimer> |
57 | #include <QDebug> |
58 | #include <QEasingCurve> |
59 | #include <QGeoCoordinate> |
60 | #include <QtPositioning/private/qwebmercator_p.h> |
61 | |
62 | #define ANIMATION_DURATION 4000 |
63 | |
64 | //! [PlaneController1] |
65 | class PlaneController: public QObject |
66 | { |
67 | Q_OBJECT |
68 | Q_PROPERTY(QGeoCoordinate position READ position WRITE setPosition NOTIFY positionChanged) |
69 | //! [PlaneController1] |
70 | //! [C++Pilot1] |
71 | Q_PROPERTY(QGeoCoordinate from READ from WRITE setFrom NOTIFY fromChanged) |
72 | Q_PROPERTY(QGeoCoordinate to READ to WRITE setTo NOTIFY toChanged) |
73 | //! [C++Pilot1] |
74 | |
75 | public: |
76 | PlaneController() |
77 | { |
78 | easingCurve.setType(QEasingCurve::InOutQuad); |
79 | easingCurve.setPeriod(ANIMATION_DURATION); |
80 | } |
81 | |
82 | void setFrom(const QGeoCoordinate& from) |
83 | { |
84 | fromCoordinate = from; |
85 | } |
86 | |
87 | QGeoCoordinate from() const |
88 | { |
89 | return fromCoordinate; |
90 | } |
91 | |
92 | void setTo(const QGeoCoordinate& to) |
93 | { |
94 | toCoordinate = to; |
95 | } |
96 | |
97 | QGeoCoordinate to() const |
98 | { |
99 | return toCoordinate; |
100 | } |
101 | |
102 | void setPosition(const QGeoCoordinate &c) { |
103 | if (currentPosition == c) |
104 | return; |
105 | |
106 | currentPosition = c; |
107 | emit positionChanged(); |
108 | } |
109 | |
110 | QGeoCoordinate position() const |
111 | { |
112 | return currentPosition; |
113 | } |
114 | |
115 | Q_INVOKABLE bool isFlying() const { |
116 | return timer.isActive(); |
117 | } |
118 | |
119 | //! [C++Pilot2] |
120 | public slots: |
121 | void startFlight() |
122 | { |
123 | if (timer.isActive()) |
124 | return; |
125 | |
126 | startTime = QTime::currentTime(); |
127 | finishTime = startTime.addMSecs(ANIMATION_DURATION); |
128 | |
129 | timer.start(msec: 15, obj: this); |
130 | emit departed(); |
131 | } |
132 | //! [C++Pilot2] |
133 | |
134 | void swapDestinations() { |
135 | if (currentPosition == toCoordinate) { |
136 | // swap destinations |
137 | toCoordinate = fromCoordinate; |
138 | fromCoordinate = currentPosition; |
139 | } |
140 | } |
141 | |
142 | signals: |
143 | void positionChanged(); |
144 | void arrived(); |
145 | void departed(); |
146 | void toChanged(); |
147 | void fromChanged(); |
148 | |
149 | protected: |
150 | void timerEvent(QTimerEvent *event) override |
151 | { |
152 | if (!event) |
153 | return; |
154 | |
155 | if (event->timerId() == timer.timerId()) |
156 | updatePosition(); |
157 | else |
158 | QObject::timerEvent(event); |
159 | } |
160 | |
161 | private: |
162 | //! [C++Pilot3] |
163 | void updatePosition() |
164 | { |
165 | // simple progress animation |
166 | qreal progress; |
167 | QTime current = QTime::currentTime(); |
168 | if (current >= finishTime) { |
169 | progress = 1.0; |
170 | timer.stop(); |
171 | } else { |
172 | progress = ((qreal)startTime.msecsTo(current) / ANIMATION_DURATION); |
173 | } |
174 | |
175 | setPosition(QWebMercator::coordinateInterpolation( |
176 | from: fromCoordinate, to: toCoordinate, progress: easingCurve.valueForProgress(progress))); |
177 | |
178 | if (!timer.isActive()) |
179 | emit arrived(); |
180 | } |
181 | //! [C++Pilot3] |
182 | |
183 | private: |
184 | QGeoCoordinate currentPosition; |
185 | QGeoCoordinate fromCoordinate, toCoordinate; |
186 | QBasicTimer timer; |
187 | QTime startTime, finishTime; |
188 | QEasingCurve easingCurve; |
189 | //! [PlaneController2] |
190 | // ... |
191 | }; |
192 | //! [PlaneController2] |
193 | |
194 | //! [PlaneControllerMain] |
195 | int main(int argc, char *argv[]) |
196 | { |
197 | QGuiApplication app(argc, argv); |
198 | |
199 | PlaneController oslo2berlin; |
200 | PlaneController berlin2london; |
201 | |
202 | QQmlApplicationEngine engine; |
203 | engine.rootContext()->setContextProperty("oslo2Berlin" , &oslo2berlin); |
204 | engine.rootContext()->setContextProperty("berlin2London" , &berlin2london); |
205 | engine.load(url: QUrl(QStringLiteral("qrc:/planespotter.qml" ))); |
206 | |
207 | return app.exec(); |
208 | } |
209 | //! [PlaneControllerMain] |
210 | |
211 | #include "main.moc" |
212 | |