File indexing completed on 2024-04-21 07:36:28

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
0004 //
0005 
0006 #include "SerialTrack.h"
0007 #include "PlaybackFlyToItem.h"
0008 #include "PlaybackWaitItem.h"
0009 #include "PlaybackTourControlItem.h"
0010 #include "GeoDataCamera.h"
0011 #include "GeoDataLookAt.h"
0012 #include "TourPlayback.h"
0013 
0014 namespace Marble
0015 {
0016 
0017 SerialTrack::SerialTrack(): QObject()
0018 {
0019     m_currentIndex = 0;
0020     m_finishedPosition = 0;
0021     m_currentPosition = 0;
0022     m_paused = true;
0023 }
0024 
0025 SerialTrack::~SerialTrack()
0026 {
0027     clear();
0028 }
0029 
0030 void SerialTrack::append(PlaybackItem* item)
0031 {
0032     connect( item, SIGNAL(progressChanged(double)), this, SLOT(changeProgress(double)) );
0033     connect( item, SIGNAL(centerOn(GeoDataCoordinates)), this, SIGNAL(centerOn(GeoDataCoordinates)) );
0034     connect( item, SIGNAL(finished()), this, SLOT(handleFinishedItem()) ) ;
0035     connect( item, SIGNAL(paused()), this, SLOT(pause()) ) ;
0036     m_items.append( item );
0037     if( m_items.size() == 1 ) {
0038         PlaybackFlyToItem *flyTo = dynamic_cast<PlaybackFlyToItem*>( item );
0039         if( flyTo != nullptr ) {
0040             flyTo->setFirst( true )
0041 ;        }
0042     }
0043 }
0044 
0045 void SerialTrack::play()
0046 {
0047     m_paused = false;
0048     m_items[m_currentIndex]->play();
0049 }
0050 
0051 void SerialTrack::pause()
0052 {
0053     m_paused = true;
0054     m_items[m_currentIndex]->pause();
0055 }
0056 
0057 void SerialTrack::stop()
0058 {
0059     m_paused = true;
0060     if( m_items.size() != 0 && m_currentIndex >= 0 && m_currentIndex <= m_items.size() - 1 ){
0061         m_items[m_currentIndex]->stop();
0062     }
0063     m_finishedPosition = 0;
0064     emit progressChanged( m_finishedPosition );
0065     m_currentIndex = 0;
0066 }
0067 
0068 void SerialTrack::seek( double offset )
0069 {
0070     m_currentPosition = offset;
0071     int index = -1;
0072     for( int i = 0; i < m_items.size(); i++ ){
0073         if( offset < m_items[i]->duration() ){
0074             index = i;
0075             break;
0076         } else {
0077             m_items[i]->stop();
0078             offset -= m_items[i]->duration();
0079         }
0080     }
0081 
0082     if( index == -1 ){
0083         index = m_items.size() - 1;
0084     }
0085 
0086     if( index < m_items.size() - 1 ){
0087         for( int i = index + 1; i < m_items.size(); i++ ){
0088             m_items[ i ]->stop();
0089         }
0090     }
0091 
0092     if( index > m_currentIndex ){
0093         for( int i = m_currentIndex; i < index ; i++ ){
0094             m_finishedPosition += m_items[ i ]->duration();
0095         }
0096     }else{
0097         for( int i = m_currentIndex - 1; i >= index && i >= 0; i-- ){
0098             m_finishedPosition -= m_items[ i ]->duration();
0099         }
0100     }
0101 
0102     if (m_currentIndex != index && !m_paused) {
0103         m_items[ index ]->play();
0104     }
0105 
0106     m_currentIndex = index;
0107     if ( m_currentIndex != -1 ){
0108         double t = offset / m_items[ m_currentIndex ]->duration();
0109         Q_ASSERT( t >= 0 && t <= 1 );
0110         m_items[ m_currentIndex ]->seek( t );
0111     }
0112 }
0113 
0114 double SerialTrack::duration() const
0115 {
0116     double duration = 0.0;
0117     for (PlaybackItem* item: m_items) {
0118         duration += item->duration();
0119     }
0120     return duration;
0121 }
0122 
0123 void SerialTrack::clear()
0124 {
0125     qDeleteAll( m_items );
0126     m_items.clear();
0127     m_currentIndex = 0;
0128     m_finishedPosition = 0;
0129     m_currentPosition = 0;
0130     m_paused = true;
0131 }
0132 
0133 void SerialTrack::handleFinishedItem()
0134 {
0135     if( m_paused ){
0136         return;
0137     }
0138     if ( m_currentIndex + 1 < m_items.size() ) {
0139         m_finishedPosition += m_items[m_currentIndex]->duration();
0140         m_currentIndex++;
0141         m_items[m_currentIndex]->play();
0142         emit itemFinished( m_currentIndex + 1 );
0143 
0144     } else {
0145         emit finished();
0146     }
0147 }
0148 
0149 void SerialTrack::changeProgress( double progress )
0150 {
0151     m_currentPosition = m_finishedPosition + progress;
0152     emit progressChanged( m_currentPosition );
0153 }
0154 
0155 int SerialTrack::size() const
0156 {
0157     return m_items.size();
0158 }
0159 
0160 PlaybackItem* SerialTrack::at( int i )
0161 {
0162     return m_items.at( i );
0163 }
0164 
0165 double SerialTrack::currentPosition()
0166 {
0167     return m_currentPosition;
0168 }
0169 
0170 }
0171 
0172 #include "moc_SerialTrack.cpp"