-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 @@ -35,48 +35,53 @@ MediaPlayer::MediaPlayer( PlayListWidget &_playList, MediaPlayerState &_mediaPla 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; } @@ -326,48 +331,50 @@ void MediaPlayer::keyReleaseEvent( QKeyEvent *e) { 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; 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 @@ -19,48 +19,49 @@ : .. .:, . . . 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(); @@ -68,29 +69,31 @@ private slots: 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 @@ -70,48 +70,49 @@ public: // 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 ); 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 @@ -4,48 +4,49 @@ (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 ); @@ -161,81 +162,167 @@ QString Skin::defaultSkinName() 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 @@ -4,102 +4,121 @@ (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 */ |