author | simon <simon> | 2002-12-11 23:12:16 (UTC) |
---|---|---|
committer | simon <simon> | 2002-12-11 23:12:16 (UTC) |
commit | d4a0626f01fae21ed19d0eea88d8eca1935c6bc8 (patch) (side-by-side diff) | |
tree | 9747bdd478c1bd93f46eaa49c95381404a6fd55b | |
parent | 8d5ae95e770bc387420fc094c54d8ac55e64e04b (diff) | |
download | opie-d4a0626f01fae21ed19d0eea88d8eca1935c6bc8.zip opie-d4a0626f01fae21ed19d0eea88d8eca1935c6bc8.tar.gz opie-d4a0626f01fae21ed19d0eea88d8eca1935c6bc8.tar.bz2 |
- skins are now pre-loaded in the background (step by step)
-rw-r--r-- | noncore/multimedia/opieplayer2/mediaplayer.cpp | 7 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/mediaplayer.h | 3 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/mediawidget.h | 1 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.cpp | 115 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.h | 53 |
5 files changed, 148 insertions, 31 deletions
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 @@ -11,96 +11,101 @@ #include <qfile.h> #include "mediaplayer.h" #include "playlistwidget.h" #include "audiowidget.h" #include "videowidget.h" #include "volumecontrol.h" #include "mediaplayerstate.h" // for setBacklight() #include <linux/fb.h> #include <sys/file.h> #include <sys/ioctl.h> #define FBIOBLANK 0x4611 MediaPlayer::MediaPlayer( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QObject *parent, const char *name ) : QObject( parent, name ), volumeDirection( 0 ), mediaPlayerState( _mediaPlayerState ), playList( _playList ) { m_audioUI = 0; m_videoUI = 0; m_xineControl = 0; fd=-1;fl=-1; playList.setCaption( tr( "OpiePlayer: Initializating" ) ); qApp->processEvents(); // QPEApplication::grabKeyboard(); // EVIL connect( qApp,SIGNAL( aboutToQuit()),SLOT( cleanUp()) ); connect( &mediaPlayerState, SIGNAL( playingToggled( bool ) ), this, SLOT( setPlaying( bool ) ) ); // What is pauseCheck good for? (Simon) // connect( &mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( pauseCheck( bool ) ) ); connect( &mediaPlayerState, SIGNAL( next() ), this, SLOT( next() ) ); connect( &mediaPlayerState, SIGNAL( prev() ), this, SLOT( prev() ) ); connect( &mediaPlayerState, SIGNAL( blankToggled( bool ) ), this, SLOT ( blank( bool ) ) ); volControl = new VolumeControl; Config cfg( "OpiePlayer" ); 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() { delete m_xineControl; delete m_audioUI; delete m_videoUI; delete volControl; } void MediaPlayer::pauseCheck( bool b ) { if ( b && !mediaPlayerState.isPlaying() ) { mediaPlayerState.setPaused( FALSE ); } } void MediaPlayer::play() { mediaPlayerState.setPlaying( FALSE ); mediaPlayerState.setPlaying( TRUE ); } void MediaPlayer::setPlaying( bool play ) { if ( !play ) { return; } if ( mediaPlayerState.isPaused() ) { mediaPlayerState.setPaused( FALSE ); return; } QString tickerText, time, fileName; if ( playList.currentTab() != PlayListWidget::CurrentPlayList ) { //if playing in file list.. play in a different way // random and looping settings enabled causes problems here, // since there is no selected file in the playlist, but a selected file in the file list, // so we remember and shutoff l = mediaPlayerState.isLooping(); if(l) { mediaPlayerState.setLooping( false ); } r = mediaPlayerState.isShuffled(); mediaPlayerState.setShuffled( false ); } PlayListWidget::Entry playListEntry = playList.currentEntry(); fileName = playListEntry.name; xineControl()->play( playListEntry.file ); @@ -302,94 +307,96 @@ void MediaPlayer::blank( bool b ) { ioctl( fd, FBIOBLANK, 0); #ifdef QT_QWS_EBX if(fl != -1) { ioctl( fl, 1); ::close(fl); } #endif isBlanked = FALSE; } close( fd ); } else { qDebug("<< /dev/fb0 could not be opened >>"); } } void MediaPlayer::keyReleaseEvent( QKeyEvent *e) { switch ( e->key() ) { ////////////////////////////// Zaurus keys case Key_Home: break; case Key_F9: //activity break; case Key_F10: //contacts break; case Key_F11: //menu break; case Key_F12: //home qDebug("Blank here"); // mediaPlayerState->toggleBlank(); break; case Key_F13: //mail qDebug("Blank here"); // mediaPlayerState->toggleBlank(); break; } } void MediaPlayer::cleanUp() {// this happens on closing Config cfg( "OpiePlayer" ); mediaPlayerState.writeConfig( cfg ); playList.writeDefaultPlaylist( ); // QPEApplication::grabKeyboard(); // QPEApplication::ungrabKeyboard(); } void MediaPlayer::recreateAudioAndVideoWidgets() const { + delete m_skinLoader; + delete m_xineControl; delete m_audioUI; delete m_videoUI; m_audioUI = new AudioWidget( playList, mediaPlayerState, 0, "audioUI" ); m_videoUI = new VideoWidget( playList, mediaPlayerState, 0, "videoUI" ); connect( m_audioUI, SIGNAL( moreClicked() ), this, SLOT( startIncreasingVolume() ) ); connect( m_audioUI, SIGNAL( lessClicked() ), this, SLOT( startDecreasingVolume() ) ); connect( m_audioUI, SIGNAL( moreReleased() ), this, SLOT( stopChangingVolume() ) ); connect( m_audioUI, SIGNAL( lessReleased() ), this, SLOT( stopChangingVolume() ) ); connect( m_videoUI, SIGNAL( moreClicked() ), this, SLOT( startIncreasingVolume() ) ); connect( m_videoUI, SIGNAL( lessClicked() ), this, SLOT( startDecreasingVolume() ) ); connect( m_videoUI, SIGNAL( moreReleased() ), this, SLOT( stopChangingVolume() ) ); connect( m_videoUI, SIGNAL( lessReleased() ), this, SLOT( stopChangingVolume() ) ); m_xineControl = new XineControl( m_videoUI->vidWidget(), mediaPlayerState ); } AudioWidget *MediaPlayer::audioUI() const { if ( !m_audioUI ) recreateAudioAndVideoWidgets(); return m_audioUI; } VideoWidget *MediaPlayer::videoUI() const { if ( !m_videoUI ) recreateAudioAndVideoWidgets(); return m_videoUI; } XineControl *MediaPlayer::xineControl() const { if ( !m_xineControl ) recreateAudioAndVideoWidgets(); return m_xineControl; } void MediaPlayer::reloadSkins() { audioUI()->loadSkin(); videoUI()->loadSkin(); } 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 @@ -1,96 +1,99 @@ /* This file is part of the Opie Project Copyright (c) 2002 Max Reiss <harlekin@handhelds.org> Copyright (c) 2002 LJP <> Copyright (c) 2002 Holger Freyther <zecke@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef MEDIA_PLAYER_H #define MEDIA_PLAYER_H #include <qmainwindow.h> #include <qframe.h> #include "xinecontrol.h" #include "playlistwidget.h" +#include "skin.h" class DocLnk; class VolumeControl; class MediaPlayerState; class AudioWidget; class VideoWidget; class MediaPlayer : public QObject { Q_OBJECT public: MediaPlayer( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QObject *parent, const char *name ); ~MediaPlayer(); public slots: void reloadSkins(); private slots: void setPlaying( bool ); void pauseCheck( bool ); void play(); void next(); void prev(); void startIncreasingVolume(); void startDecreasingVolume(); void stopChangingVolume(); void cleanUp(); void blank( bool ); protected: void timerEvent( QTimerEvent *e ); void keyReleaseEvent( QKeyEvent *e); private: AudioWidget *audioUI() const; VideoWidget *videoUI() const; XineControl *xineControl() const; bool isBlanked, l, r; int fd, fl; int volumeDirection; VolumeControl *volControl; MediaPlayerState &mediaPlayerState; PlayListWidget &playList; void recreateAudioAndVideoWidgets() const; mutable XineControl *m_xineControl; mutable AudioWidget *m_audioUI; mutable VideoWidget *m_videoUI; + + QGuardedPtr<SkinLoader> m_skinLoader; }; #endif // MEDIA_PLAYER_H 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 @@ -46,96 +46,97 @@ namespace class Skin; class MediaWidget : public QWidget { Q_OBJECT public: enum Command { Play = 0, Stop, Next, Previous, VolumeUp, VolumeDown, Loop, PlayList, Forward, Back, FullScreen, Undefined }; enum ButtonType { NormalButton, ToggleButton }; struct Button { Button() : command( Undefined ), type( NormalButton ), isDown( false ) {} Command command; ButtonType type; // this should be part of the bitfield but gcc2 is too buggy to support this :-( bool isDown : 1; QBitmap mask; QPixmap pixUp; QPixmap pixDown; }; #if defined( _CC_GNU_ ) // use that allocator to avoid the default allocator that on gcc2 requires libstdc++ because // in the BAD_ALLOC macro it uses std::cerr and friends :-( typedef std::vector<Button, std::__allocator<Button, simpleAndStupidAllocator> > ButtonVector; #else typedef std::vector<Button> ButtonVector; #endif struct SkinButtonInfo { Command command; const char *fileName; ButtonType type; }; struct GUIInfo { GUIInfo() : buttonInfo( 0 ), buttonCount( 0 ) {} GUIInfo( const QString &_fileNameInfix, const SkinButtonInfo *_buttonInfo, const uint _buttonCount ) : fileNameInfix( _fileNameInfix ), buttonInfo( _buttonInfo ), buttonCount( _buttonCount ) {} QString fileNameInfix; const SkinButtonInfo *buttonInfo; const uint buttonCount; }; + typedef QValueList<GUIInfo> GUIInfoList; MediaWidget( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QWidget *parent = 0, const char *name = 0 ); virtual ~MediaWidget(); public slots: virtual void setDisplayType( MediaPlayerState::DisplayType displayType ) = 0; virtual void setLength( long length ) = 0; virtual void setPlaying( bool playing ) = 0; virtual void loadSkin() = 0; signals: void moreReleased(); void lessReleased(); void forwardReleased(); void backReleased(); void forwardClicked(); void backClicked(); void moreClicked(); void lessClicked(); protected: void setupButtons( const SkinButtonInfo *skinInfo, uint buttonCount, const Skin &skin ); Button setupButton( const SkinButtonInfo &buttonInfo, const Skin &skin ); void loadDefaultSkin( const GUIInfo &guiInfo ); void loadSkin( const SkinButtonInfo *skinInfo, uint buttonCount, const Skin &skin ); virtual void closeEvent( QCloseEvent * ); virtual void paintEvent( QPaintEvent *pe ); virtual void resizeEvent( QResizeEvent *e ); Button *buttonAt( const QPoint &position ); virtual void mousePressEvent( QMouseEvent *event ); virtual void mouseReleaseEvent( QMouseEvent *event ); virtual void makeVisible(); void handleCommand( Command command, bool buttonDown ); bool isOverButton( const QPoint &position, int buttonId ) const; void paintAllButtons( QPainter &p ); void paintButton( const Button &button ); 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 @@ -1,75 +1,76 @@ /* Copyright (C) 2002 Simon Hausmann <simon@lst.de> (C) 2002 Max Reiss <harlekin@handhelds.org> (C) 2002 L. Potter <ljp@llornkcor.com> (C) 2002 Holger Freyther <zecke@handhelds.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "skin.h" #include "singleton.h" #include <qcache.h> #include <qmap.h> +#include <qtimer.h> #include <qpe/resource.h> #include <qpe/config.h> #include <assert.h> struct SkinData { typedef QMap<QString, QImage> ButtonMaskImageMap; QImage backgroundImage; QImage buttonUpImage; QImage buttonDownImage; QImage buttonMask; ButtonMaskImageMap buttonMasks; }; class SkinCache : public Singleton<SkinCache> { public: SkinCache(); SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix ); void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ); private: typedef QCache<SkinData> DataCache; typedef QCache<QImage> BackgroundImageCache; template <class CacheType> void store( const QCache<CacheType> &cache, const QString &key, CacheType *data ); DataCache m_cache; BackgroundImageCache m_backgroundImageCache; }; Skin::Skin( const QString &name, const QString &fileNameInfix ) : m_fileNameInfix( fileNameInfix ) { init( name ); } Skin::Skin( const QString &fileNameInfix ) : m_fileNameInfix( fileNameInfix ) { init( defaultSkinName() ); } @@ -137,105 +138,191 @@ void Skin::addButtonToMask( int tag, const QImage &maskImage ) const uchar **dest = d->buttonMask.jumpTable(); for ( int y = 0; y < d->buttonMask.height(); y++ ) { uchar *line = dest[y]; for ( int x = 0; x < d->buttonMask.width(); x++ ) if ( !qRed( maskImage.pixel( x, y ) ) ) line[x] = tag; } } QImage Skin::buttonMaskImage( const QString &fileName ) const { SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); if ( it == d->buttonMasks.end() ) { QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); QString path = prefix + fileName + ".png"; it = d->buttonMasks.insert( fileName, loadImage( path ) ); } return *it; } QString Skin::defaultSkinName() { Config cfg( "OpiePlayer" ); cfg.setGroup( "Options" ); return cfg.readEntry( "Skin", "default" ); } QImage Skin::loadImage( const QString &fileName ) { return QImage( Resource::findPixmap( fileName ) ); } SkinCache::SkinCache() { // let's say we cache two skins (audio+video) at maximum m_cache.setMaxCost( 2 ); // ... and one background pixmap m_backgroundImageCache.setMaxCost( 1 ); } SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix ) { QString key = skinPath + fileNameInfix; 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(); return data; } void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ) { QImage *backgroundImage = new QImage( data->backgroundImage ); data->backgroundImage = QImage(); QString key = skinPath + fileNameInfix; if ( m_cache.find( key, false /*ref*/ ) != 0 || !m_cache.insert( key, data ) ) delete data; if ( m_backgroundImageCache.find( skinPath, false /*ref*/ ) != 0 || !m_backgroundImageCache.insert( skinPath, backgroundImage ) ) 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 @@ -1,105 +1,124 @@ /* Copyright (C) 2002 Simon Hausmann <simon@lst.de> (C) 2002 Max Reiss <harlekin@handhelds.org> (C) 2002 L. Potter <ljp@llornkcor.com> (C) 2002 Holger Freyther <zecke@handhelds.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef SKIN_H #define SKIN_H #include <qstring.h> #include <qimage.h> +#include <qobject.h> #include "mediawidget.h" -#include "threadutil.h" struct SkinData; class Skin { public: Skin( const QString &name, const QString &fileNameInfix ); Skin( const QString &fileNameInfix ); ~Skin(); void preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ); QImage backgroundImage() const; QImage buttonUpImage() const; QImage buttonDownImage() const; QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const; QImage buttonMaskImage( const QString &fileName ) const; static QString defaultSkinName(); private: void init( const QString &name ); void addButtonToMask( int tag, const QImage &maskImage ) const; static QImage loadImage( const QString &fileName ); QString m_fileNameInfix; QString m_skinPath; SkinData *d; Skin( const Skin & ); 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 /* vim: et sw=4 ts=4 */ |