From d4a0626f01fae21ed19d0eea88d8eca1935c6bc8 Mon Sep 17 00:00:00 2001
From: simon <simon>
Date: Wed, 11 Dec 2002 23:12:16 +0000
Subject: - skins are now pre-loaded in the background (step by step)

---
diff --git a/noncore/multimedia/opieplayer2/mediaplayer.cpp b/noncore/multimedia/opieplayer2/mediaplayer.cpp
index bbc60dd..963e783 100644
--- a/noncore/multimedia/opieplayer2/mediaplayer.cpp
+++ b/noncore/multimedia/opieplayer2/mediaplayer.cpp
@@ -56,6 +56,11 @@ MediaPlayer::MediaPlayer( PlayListWidget &_playList, MediaPlayerState &_mediaPla
     cfg.setGroup("PlayList");
     QString currentPlaylist = cfg.readEntry( "CurrentPlaylist", "default");
     playList.setCaption( tr( "OpiePlayer: " ) + QFileInfo(currentPlaylist).baseName() );
+
+    m_skinLoader = new SkinLoader;
+    m_skinLoader->schedule( AudioWidget::guiInfo() );
+    m_skinLoader->schedule( VideoWidget::guiInfo() );
+    m_skinLoader->start();
 }
 
 MediaPlayer::~MediaPlayer() {
@@ -347,6 +352,8 @@ void MediaPlayer::cleanUp() {// this happens on closing
 
 void MediaPlayer::recreateAudioAndVideoWidgets() const
 {
+    delete m_skinLoader;
+
     delete m_xineControl;
     delete m_audioUI;
     delete m_videoUI;
diff --git a/noncore/multimedia/opieplayer2/mediaplayer.h b/noncore/multimedia/opieplayer2/mediaplayer.h
index 5975731..351c884 100644
--- a/noncore/multimedia/opieplayer2/mediaplayer.h
+++ b/noncore/multimedia/opieplayer2/mediaplayer.h
@@ -40,6 +40,7 @@
 #include "xinecontrol.h"
 
 #include "playlistwidget.h"
+#include "skin.h"
 
 class DocLnk;
 class VolumeControl;
@@ -89,6 +90,8 @@ private:
     mutable XineControl *m_xineControl;
     mutable AudioWidget *m_audioUI;
     mutable VideoWidget *m_videoUI;
+
+    QGuardedPtr<SkinLoader> m_skinLoader;
 };
 
 
diff --git a/noncore/multimedia/opieplayer2/mediawidget.h b/noncore/multimedia/opieplayer2/mediawidget.h
index 40eb0af..45c46ea 100644
--- a/noncore/multimedia/opieplayer2/mediawidget.h
+++ b/noncore/multimedia/opieplayer2/mediawidget.h
@@ -91,6 +91,7 @@ public:
         const SkinButtonInfo *buttonInfo;
         const uint buttonCount;
     };
+    typedef QValueList<GUIInfo> GUIInfoList;
 
     MediaWidget( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QWidget *parent = 0, const char *name = 0 );
     virtual ~MediaWidget();
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp
index 0f49862..e9fb5a6 100644
--- a/noncore/multimedia/opieplayer2/skin.cpp
+++ b/noncore/multimedia/opieplayer2/skin.cpp
@@ -25,6 +25,7 @@
 
 #include <qcache.h>
 #include <qmap.h>
+#include <qtimer.h>
 
 #include <qpe/resource.h>
 #include <qpe/config.h>
@@ -182,10 +183,14 @@ SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &file
     SkinData *data = m_cache.take( key );
     if ( !data )
         data = new SkinData;
+    else
+        qDebug( "SkinCache: hit" );
 
     QImage *bgImage = m_backgroundImageCache.find( skinPath );
-    if ( bgImage )
+    if ( bgImage ) {
+        qDebug( "SkinCache: hit on bgimage" );
         data->backgroundImage = *bgImage;
+    }
     else
         data->backgroundImage = QImage();
 
@@ -209,32 +214,114 @@ void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, Sk
         delete backgroundImage;
 }
 
+SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info )
+    : m_skin( info.skinName, info.fileNameInfix ), m_info( info )
+{
+    m_currentState = LoadBackgroundImage;
+}
+
+SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep()
+{
+    switch ( m_currentState ) {
+        case LoadBackgroundImage:
+            qDebug( "load bgimage" );
+            m_skin.backgroundImage();
+            m_currentState = LoadButtonUpImage;
+            break;
+        case LoadButtonUpImage:
+            qDebug( "load upimage" );
+            m_skin.buttonUpImage();
+            m_currentState = LoadButtonDownImage;
+            break;
+        case LoadButtonDownImage:
+            qDebug( "load downimage" );
+            m_skin.buttonDownImage();
+            m_currentState = LoadButtonMasks;
+            m_currentButton = 0;
+            break;
+        case LoadButtonMasks:
+            qDebug( "load button masks %i", m_currentButton );
+            m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName );
+
+            m_currentButton++;
+            if ( m_currentButton >= m_info.buttonCount )
+                m_currentState = LoadButtonMask;
+
+            break;
+        case LoadButtonMask:
+            qDebug( "load whole mask" );
+            m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount );
+            return LoadingCompleted;
+    }
+
+    return MoreToCome;
+}
+
 SkinLoader::SkinLoader()
+    : m_currentLoader( 0 ), m_timerId( -1 )
 {
 }
 
-void SkinLoader::schedule( const QString &skinName, const QString &fileNameInfix, 
-                           const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount )
+SkinLoader::~SkinLoader()
 {
-    assert( isRunning() == false );
+    qDebug( "SkinLoader::~SkinLoader()" );
+    killTimers();
+    delete m_currentLoader;
+}
 
-    pendingSkins << Info( skinName, fileNameInfix, skinButtonInfo, buttonCount );
+void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo )
+{
+    schedule( Skin::defaultSkinName(), guiInfo );
 }
 
-void SkinLoader::run()
+void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo )
 {
-    qDebug( "SkinLoader::run()" );
-    for ( InfoList::ConstIterator it = pendingSkins.begin(); it != pendingSkins.end(); ++it )
-        load( *it );
-    qDebug( "SkinLoader is done." );
+    pendingSkins << Info( skinName, guiInfo );
 }
 
-void SkinLoader::load( const Info &nfo )
+void SkinLoader::start()
 {
-    qDebug( "preloading %s with infix %s", nfo.skinName.ascii(), nfo.fileNameInfix.ascii() );
+    assert( m_timerId == -1 );
+    m_timerId = startTimer( 100 /* ms */ );
+    qDebug( "SkinLoader::start() %d jobs", pendingSkins.count() );
+}
 
-    Skin skin( nfo.skinName, nfo.fileNameInfix );
-    skin.preload( nfo.skinButtonInfo, nfo.buttonCount );
+void SkinLoader::timerEvent( QTimerEvent *ev )
+{
+    if ( ev->timerId() != m_timerId ) {
+        QObject::timerEvent( ev );
+        return;
+    }
+
+    if ( !m_currentLoader ) {
+
+        if ( pendingSkins.isEmpty() ) {
+            qDebug( "all jobs done" );
+            killTimer( m_timerId );
+            m_timerId = -1;
+            // ### qt3: use deleteLater();
+            QTimer::singleShot( 0, this, SLOT( deleteMe() ) );
+            return;
+        }
+
+        Info nfo = *pendingSkins.begin();
+        pendingSkins.remove( pendingSkins.begin() );
+
+        m_currentLoader = new IncrementalLoader( nfo );
+        qDebug( "new loader %i jobs left", pendingSkins.count() );
+    }
+
+    if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) {
+        delete m_currentLoader;
+        m_currentLoader = 0;
+    }
+
+    qDebug( "finished step" );
+}
+
+void SkinLoader::deleteMe()
+{
+    delete this;
 }
 
 /* vim: et sw=4 ts=4
diff --git a/noncore/multimedia/opieplayer2/skin.h b/noncore/multimedia/opieplayer2/skin.h
index 9180067..a43a1d0 100644
--- a/noncore/multimedia/opieplayer2/skin.h
+++ b/noncore/multimedia/opieplayer2/skin.h
@@ -25,9 +25,9 @@
 
 #include <qstring.h>
 #include <qimage.h>
+#include <qobject.h>
 
 #include "mediawidget.h"
-#include "threadutil.h"
 
 struct SkinData;
 
@@ -66,38 +66,57 @@ private:
     Skin &operator=( const Skin & );
 };
 
-class SkinLoader : public ThreadUtil::Thread
+class SkinLoader : public QObject
 {
+    Q_OBJECT
 public:
     SkinLoader();
+    virtual ~SkinLoader();
 
-    void schedule( const QString &skinName, const QString &fileNameInfix, 
-                   const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount );
+    void schedule( const MediaWidget::GUIInfo &guiInfo );
+    void schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo );
+
+    void start();
 
 protected:
-    virtual void run();
+    virtual void timerEvent( QTimerEvent *ev );
+
+private slots:
+    void deleteMe();
 
 private:
-    struct Info
+    struct Info : public MediaWidget::GUIInfo
     {
-        Info() : skinButtonInfo( 0 ), buttonCount( 0 ) {}
-        Info( const QString &_skinName, const QString &_fileNameInfix, 
-              const MediaWidget::SkinButtonInfo *_skinButtonInfo, const uint _buttonCount )
-            : skinName( _skinName ), fileNameInfix( _fileNameInfix ), 
-              skinButtonInfo( _skinButtonInfo ), buttonCount( _buttonCount )
+        Info() {}
+        Info( const QString &_skinName, const MediaWidget::GUIInfo &guiInfo )
+            : MediaWidget::GUIInfo( guiInfo ), skinName( _skinName )
         {}
 
-        const QString skinName;
-        const QString fileNameInfix;
-        const MediaWidget::SkinButtonInfo *skinButtonInfo;
-        const uint buttonCount;
+        QString skinName;
     };
     typedef QValueList<Info> InfoList;
 
-    void load( const Info &nfo );
+    class IncrementalLoader
+    {
+    public:
+        enum LoaderResult { LoadingCompleted, MoreToCome };
+
+        IncrementalLoader( const Info &info );
+
+        LoaderResult loadStep();
+
+    private:
+        enum State { LoadBackgroundImage, LoadButtonUpImage, LoadButtonDownImage, LoadButtonMasks, LoadButtonMask };
+
+        Skin m_skin;
+        Info m_info;
+        State m_currentState;
+        uint m_currentButton;
+    };
 
     InfoList pendingSkins;
-    ThreadUtil::Mutex guard;
+    IncrementalLoader *m_currentLoader;
+    int m_timerId;
 };
 
 #endif // SKIN_H
--
cgit v0.9.0.2