6#include "TourPlayback.h"
12#include "AnimatedUpdateTrack.h"
13#include "GeoDataAnimatedUpdate.h"
14#include "GeoDataFlyTo.h"
15#include "GeoDataLookAt.h"
16#include "GeoDataPlacemark.h"
17#include "GeoDataPlaylist.h"
18#include "GeoDataPoint.h"
19#include "GeoDataSoundCue.h"
20#include "GeoDataTour.h"
21#include "GeoDataTourControl.h"
22#include "GeoDataTreeModel.h"
23#include "GeoDataWait.h"
26#include "PlaybackAnimatedUpdateItem.h"
27#include "PlaybackFlyToItem.h"
28#include "PlaybackSoundCueItem.h"
29#include "PlaybackTourControlItem.h"
30#include "PlaybackWaitItem.h"
31#include "PopupLayer.h"
32#include "SerialTrack.h"
33#include "SoundTrack.h"
38class TourPlaybackPrivate
41 TourPlaybackPrivate();
42 ~TourPlaybackPrivate();
44 GeoDataTour *m_tour =
nullptr;
46 SerialTrack m_mainTrack;
49 GeoDataFlyTo m_mapCenter;
54TourPlaybackPrivate::TourPlaybackPrivate()
63TourPlaybackPrivate::~TourPlaybackPrivate()
65 qDeleteAll(m_soundTracks);
66 qDeleteAll(m_animatedUpdateTracks);
69TourPlayback::TourPlayback(
QObject *parent)
71 , d(new TourPlaybackPrivate())
73 connect(&d->m_mainTrack, &SerialTrack::centerOn,
this, &TourPlayback::centerOn);
74 connect(&d->m_mainTrack, &SerialTrack::progressChanged,
this, &TourPlayback::progressChanged);
75 connect(&d->m_mainTrack, &SerialTrack::finished,
this, &TourPlayback::stopTour);
76 connect(&d->m_mainTrack, &SerialTrack::itemFinished,
this, &TourPlayback::handleFinishedItem);
79TourPlayback::~TourPlayback()
85void TourPlayback::handleFinishedItem(
int index)
87 Q_EMIT itemFinished(index);
90void TourPlayback::stopTour()
92 for (SoundTrack *track : std::as_const(d->m_soundTracks)) {
94 track->setPaused(
false);
96 for (
int i = d->m_animatedUpdateTracks.size() - 1; i >= 0; i--) {
97 d->m_animatedUpdateTracks[i]->stop();
98 d->m_animatedUpdateTracks[i]->setPaused(
false);
103void TourPlayback::showBalloon(GeoDataPlacemark *placemark)
105 auto point =
static_cast<GeoDataPoint *
>(placemark->geometry());
107 d->m_widget->popupLayer()->setContent(placemark->description(), d->m_baseUrl);
108 d->m_widget->popupLayer()->setVisible(
true);
109 d->m_widget->popupLayer()->setSize(
QSizeF(500, 520));
112void TourPlayback::hideBalloon()
115 d->m_widget->popupLayer()->setVisible(
false);
119bool TourPlayback::isPlaying()
const
124void TourPlayback::setMarbleWidget(MarbleWidget *widget)
126 d->m_widget = widget;
128 connect(
this, &TourPlayback::added, d->m_widget->model()->treeModel(), &GeoDataTreeModel::addFeature);
129 connect(
this, SIGNAL(removed(GeoDataFeature *)), d->m_widget->model()->treeModel(), SLOT(removeFeature(GeoDataFeature *)));
130 connect(
this, &TourPlayback::updated, d->m_widget->model()->treeModel(), &GeoDataTreeModel::updateFeature);
133void TourPlayback::setBaseUrl(
const QUrl &baseUrl)
135 d->m_baseUrl = baseUrl;
138QUrl TourPlayback::baseUrl()
const
143void TourPlayback::centerOn(
const GeoDataCoordinates &coordinates)
146 GeoDataLookAt lookat;
147 lookat.setCoordinates(coordinates);
148 lookat.setRange(coordinates.altitude());
149 d->m_widget->flyTo(lookat, Instant);
153void TourPlayback::setTour(GeoDataTour *tour)
164void TourPlayback::play()
167 auto lookat =
new GeoDataLookAt(d->m_widget->lookAt());
168 lookat->setAltitude(lookat->range());
169 d->m_mapCenter.setView(lookat);
170 d->m_mainTrack.play();
171 for (SoundTrack *track : std::as_const(d->m_soundTracks)) {
174 for (AnimatedUpdateTrack *track : std::as_const(d->m_animatedUpdateTracks)) {
179void TourPlayback::pause()
182 d->m_mainTrack.pause();
183 for (SoundTrack *track : std::as_const(d->m_soundTracks)) {
186 for (AnimatedUpdateTrack *track : std::as_const(d->m_animatedUpdateTracks)) {
191void TourPlayback::stop()
194 d->m_mainTrack.stop();
195 for (SoundTrack *track : std::as_const(d->m_soundTracks)) {
198 for (
int i = d->m_animatedUpdateTracks.size() - 1; i >= 0; i--) {
199 d->m_animatedUpdateTracks[i]->stop();
204void TourPlayback::seek(
double value)
206 double const offset = qBound(0.0, value, d->m_mainTrack.duration());
207 d->m_mainTrack.seek(offset);
208 for (SoundTrack *track : std::as_const(d->m_soundTracks)) {
211 for (AnimatedUpdateTrack *track : std::as_const(d->m_animatedUpdateTracks)) {
216int TourPlayback::mainTrackSize()
218 return d->m_mainTrack.size();
221PlaybackItem *TourPlayback::mainTrackItemAt(
int i)
223 return d->m_mainTrack.at(i);
226void TourPlayback::updateTracks()
230 for (
int i = 0; i < d->m_tour->playlist()->size(); i++) {
231 GeoDataTourPrimitive *primitive = d->m_tour->playlist()->primitive(i);
232 if (
const auto flyTo = geodata_cast<GeoDataFlyTo>(primitive)) {
233 d->m_mainTrack.append(
new PlaybackFlyToItem(flyTo));
234 delay += flyTo->duration();
235 }
else if (
const auto wait = geodata_cast<GeoDataWait>(primitive)) {
236 d->m_mainTrack.append(
new PlaybackWaitItem(wait));
237 delay += wait->duration();
238 }
else if (
const auto tourControl = geodata_cast<GeoDataTourControl>(primitive)) {
239 d->m_mainTrack.append(
new PlaybackTourControlItem(tourControl));
240 }
else if (
const auto soundCue = geodata_cast<GeoDataSoundCue>(primitive)) {
241 auto item =
new PlaybackSoundCueItem(soundCue);
242 auto track =
new SoundTrack(item);
243 track->setDelayBeforeTrackStarts(delay);
244 d->m_soundTracks.append(track);
245 }
else if (
const auto animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
246 auto item =
new PlaybackAnimatedUpdateItem(animatedUpdate);
247 auto track =
new AnimatedUpdateTrack(item);
248 track->setDelayBeforeTrackStarts(delay + animatedUpdate->delayedStart());
249 d->m_animatedUpdateTracks.append(track);
250 connect(track, &AnimatedUpdateTrack::balloonHidden,
this, &TourPlayback::hideBalloon);
251 connect(track, &AnimatedUpdateTrack::balloonShown,
this, &TourPlayback::showBalloon);
252 connect(track, &AnimatedUpdateTrack::updated,
this, &TourPlayback::updated);
253 connect(track, &AnimatedUpdateTrack::added,
this, &TourPlayback::added);
254 connect(track, &AnimatedUpdateTrack::removed,
this, &TourPlayback::removed);
257 Q_ASSERT(d->m_widget);
258 auto lookat =
new GeoDataLookAt(d->m_widget->lookAt());
259 lookat->setAltitude(lookat->range());
260 d->m_mapCenter.setView(lookat);
261 auto mapCenterItem =
new PlaybackFlyToItem(&d->m_mapCenter);
262 PlaybackFlyToItem *before = mapCenterItem;
263 for (
int i = 0; i < d->m_mainTrack.size(); ++i) {
264 auto item = qobject_cast<PlaybackFlyToItem *>(d->m_mainTrack.at(i));
266 item->setBefore(before);
270 PlaybackFlyToItem *
next =
nullptr;
271 for (
int i = d->m_mainTrack.size() - 1; i >= 0; --i) {
272 auto item = qobject_cast<PlaybackFlyToItem *>(d->m_mainTrack.at(i));
280void TourPlayback::clearTracks()
282 d->m_mainTrack.clear();
283 qDeleteAll(d->m_soundTracks);
284 qDeleteAll(d->m_animatedUpdateTracks);
285 d->m_soundTracks.clear();
286 d->m_animatedUpdateTracks.clear();
289double TourPlayback::duration()
const
291 return d->m_mainTrack.duration();
296#include "moc_TourPlayback.cpp"
This file contains the headers for MarbleModel.
void stop(Ekos::AlignState mode)
QAction * next(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)