summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/mediawidget.cpp1
-rw-r--r--noncore/multimedia/opieplayer2/skin.cpp6
-rw-r--r--noncore/multimedia/opieplayer2/skin.h4
3 files changed, 10 insertions, 1 deletions
diff --git a/noncore/multimedia/opieplayer2/mediawidget.cpp b/noncore/multimedia/opieplayer2/mediawidget.cpp
index edef2a7..46e7b6e 100644
--- a/noncore/multimedia/opieplayer2/mediawidget.cpp
+++ b/noncore/multimedia/opieplayer2/mediawidget.cpp
@@ -1,260 +1,261 @@
1/* 1/*
2 Copyright (C) 2002 Simon Hausmann <simon@lst.de> 2 Copyright (C) 2002 Simon Hausmann <simon@lst.de>
3 (C) 2002 Max Reiss <harlekin@handhelds.org> 3 (C) 2002 Max Reiss <harlekin@handhelds.org>
4 (C) 2002 L. Potter <ljp@llornkcor.com> 4 (C) 2002 L. Potter <ljp@llornkcor.com>
5 (C) 2002 Holger Freyther <zecke@handhelds.org> 5 (C) 2002 Holger Freyther <zecke@handhelds.org>
6 6
7 This program is free software; you can redistribute it and/or 7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public 8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details. 15 General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to 18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#include "mediawidget.h" 23#include "mediawidget.h"
24#include "playlistwidget.h" 24#include "playlistwidget.h"
25#include "skin.h" 25#include "skin.h"
26 26
27MediaWidget::MediaWidget( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QWidget *parent, const char *name ) 27MediaWidget::MediaWidget( PlayListWidget &_playList, MediaPlayerState &_mediaPlayerState, QWidget *parent, const char *name )
28 : QWidget( parent, name ), mediaPlayerState( _mediaPlayerState ), playList( _playList ) 28 : QWidget( parent, name ), mediaPlayerState( _mediaPlayerState ), playList( _playList )
29{ 29{
30 connect( &mediaPlayerState, SIGNAL( displayTypeChanged( MediaPlayerState::DisplayType ) ), 30 connect( &mediaPlayerState, SIGNAL( displayTypeChanged( MediaPlayerState::DisplayType ) ),
31 this, SLOT( setDisplayType( MediaPlayerState::DisplayType ) ) ); 31 this, SLOT( setDisplayType( MediaPlayerState::DisplayType ) ) );
32 connect( &mediaPlayerState, SIGNAL( lengthChanged( long ) ), 32 connect( &mediaPlayerState, SIGNAL( lengthChanged( long ) ),
33 this, SLOT( setLength( long ) ) ); 33 this, SLOT( setLength( long ) ) );
34 connect( &mediaPlayerState, SIGNAL( playingToggled( bool ) ), 34 connect( &mediaPlayerState, SIGNAL( playingToggled( bool ) ),
35 this, SLOT( setPlaying( bool ) ) ); 35 this, SLOT( setPlaying( bool ) ) );
36 36
37 setBackgroundMode( NoBackground ); 37 setBackgroundMode( NoBackground );
38} 38}
39 39
40MediaWidget::~MediaWidget() 40MediaWidget::~MediaWidget()
41{ 41{
42} 42}
43 43
44void MediaWidget::setupButtons( const SkinButtonInfo *skinInfo, uint buttonCount, 44void MediaWidget::setupButtons( const SkinButtonInfo *skinInfo, uint buttonCount,
45 const Skin &skin ) 45 const Skin &skin )
46{ 46{
47 buttonMask = skin.buttonMask( skinInfo, buttonCount ); 47 buttonMask = skin.buttonMask( skinInfo, buttonCount );
48 48
49 buttons.clear(); 49 buttons.clear();
50 buttons.reserve( buttonCount ); 50 buttons.reserve( buttonCount );
51 51
52 for ( uint i = 0; i < buttonCount; ++i ) { 52 for ( uint i = 0; i < buttonCount; ++i ) {
53 Button button = setupButton( skinInfo[ i ], skin ); 53 Button button = setupButton( skinInfo[ i ], skin );
54 buttons.push_back( button ); 54 buttons.push_back( button );
55 } 55 }
56} 56}
57 57
58MediaWidget::Button MediaWidget::setupButton( const SkinButtonInfo &buttonInfo, const Skin &skin ) 58MediaWidget::Button MediaWidget::setupButton( const SkinButtonInfo &buttonInfo, const Skin &skin )
59{ 59{
60 Button button; 60 Button button;
61 button.command = buttonInfo.command; 61 button.command = buttonInfo.command;
62 button.type = buttonInfo.type; 62 button.type = buttonInfo.type;
63 button.mask = skin.buttonMaskImage( buttonInfo.fileName ); 63 button.mask = skin.buttonMaskImage( buttonInfo.fileName );
64 64
65 return button; 65 return button;
66} 66}
67 67
68void MediaWidget::loadDefaultSkin( const GUIInfo &guiInfo ) 68void MediaWidget::loadDefaultSkin( const GUIInfo &guiInfo )
69{ 69{
70 Skin skin( guiInfo.fileNameInfix ); 70 Skin skin( guiInfo.fileNameInfix );
71 skin.setCachable( false );
71 loadSkin( guiInfo.buttonInfo, guiInfo.buttonCount, skin ); 72 loadSkin( guiInfo.buttonInfo, guiInfo.buttonCount, skin );
72} 73}
73 74
74void MediaWidget::loadSkin( const SkinButtonInfo *skinInfo, uint buttonCount, const Skin &skin ) 75void MediaWidget::loadSkin( const SkinButtonInfo *skinInfo, uint buttonCount, const Skin &skin )
75{ 76{
76 backgroundPixmap = skin.backgroundPixmap(); 77 backgroundPixmap = skin.backgroundPixmap();
77 buttonUpImage = skin.buttonUpImage(); 78 buttonUpImage = skin.buttonUpImage();
78 buttonDownImage = skin.buttonDownImage(); 79 buttonDownImage = skin.buttonDownImage();
79 80
80 setupButtons( skinInfo, buttonCount, skin ); 81 setupButtons( skinInfo, buttonCount, skin );
81} 82}
82 83
83void MediaWidget::closeEvent( QCloseEvent * ) 84void MediaWidget::closeEvent( QCloseEvent * )
84{ 85{
85 mediaPlayerState.setList(); 86 mediaPlayerState.setList();
86} 87}
87 88
88void MediaWidget::paintEvent( QPaintEvent *pe ) 89void MediaWidget::paintEvent( QPaintEvent *pe )
89{ 90{
90 QPainter p( this ); 91 QPainter p( this );
91 92
92 if ( mediaPlayerState.isFullscreen() ) { 93 if ( mediaPlayerState.isFullscreen() ) {
93 // Clear the background 94 // Clear the background
94 p.setBrush( QBrush( Qt::black ) ); 95 p.setBrush( QBrush( Qt::black ) );
95 return; 96 return;
96 } 97 }
97 98
98 QPixmap buffer( size() ); 99 QPixmap buffer( size() );
99 QPainter bufferedPainter( &buffer ); 100 QPainter bufferedPainter( &buffer );
100 bufferedPainter.drawTiledPixmap( rect(), backgroundPixmap, QPoint( 0, 0 ) ); 101 bufferedPainter.drawTiledPixmap( rect(), backgroundPixmap, QPoint( 0, 0 ) );
101 paintAllButtons( bufferedPainter ); 102 paintAllButtons( bufferedPainter );
102 p.drawPixmap( 0, 0, buffer ); 103 p.drawPixmap( 0, 0, buffer );
103} 104}
104 105
105void MediaWidget::resizeEvent( QResizeEvent *e ) 106void MediaWidget::resizeEvent( QResizeEvent *e )
106{ 107{
107 QPixmap pixUp = combineImageWithBackground( buttonUpImage, backgroundPixmap, upperLeftOfButtonMask ); 108 QPixmap pixUp = combineImageWithBackground( buttonUpImage, backgroundPixmap, upperLeftOfButtonMask );
108 QPixmap pixDn = combineImageWithBackground( buttonDownImage, backgroundPixmap, upperLeftOfButtonMask ); 109 QPixmap pixDn = combineImageWithBackground( buttonDownImage, backgroundPixmap, upperLeftOfButtonMask );
109 110
110 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it ) { 111 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it ) {
111 Button &button = *it; 112 Button &button = *it;
112 113
113 if ( button.mask.isNull() ) 114 if ( button.mask.isNull() )
114 continue; 115 continue;
115 button.pixUp = addMaskToPixmap( pixUp, button.mask ); 116 button.pixUp = addMaskToPixmap( pixUp, button.mask );
116 button.pixDown = addMaskToPixmap( pixDn, button.mask ); 117 button.pixDown = addMaskToPixmap( pixDn, button.mask );
117 } 118 }
118 119
119 QWidget::resizeEvent( e ); 120 QWidget::resizeEvent( e );
120} 121}
121 122
122MediaWidget::Button *MediaWidget::buttonAt( const QPoint &position ) 123MediaWidget::Button *MediaWidget::buttonAt( const QPoint &position )
123{ 124{
124 if ( position.x() <= 0 || position.y() <= 0 || 125 if ( position.x() <= 0 || position.y() <= 0 ||
125 position.x() >= buttonMask.width() || 126 position.x() >= buttonMask.width() ||
126 position.y() >= buttonMask.height() ) 127 position.y() >= buttonMask.height() )
127 return 0; 128 return 0;
128 129
129 int pixelIdx = buttonMask.pixelIndex( position.x(), position.y() ); 130 int pixelIdx = buttonMask.pixelIndex( position.x(), position.y() );
130 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it ) 131 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it )
131 if ( it->command + 1 == pixelIdx ) 132 if ( it->command + 1 == pixelIdx )
132 return &( *it ); 133 return &( *it );
133 134
134 return 0; 135 return 0;
135} 136}
136 137
137void MediaWidget::mousePressEvent( QMouseEvent *event ) 138void MediaWidget::mousePressEvent( QMouseEvent *event )
138{ 139{
139 Button *button = buttonAt( event->pos() - upperLeftOfButtonMask ); 140 Button *button = buttonAt( event->pos() - upperLeftOfButtonMask );
140 141
141 if ( !button ) { 142 if ( !button ) {
142 QWidget::mousePressEvent( event ); 143 QWidget::mousePressEvent( event );
143 return; 144 return;
144 } 145 }
145 146
146 switch ( button->command ) { 147 switch ( button->command ) {
147 case VolumeUp: emit moreClicked(); return; 148 case VolumeUp: emit moreClicked(); return;
148 case VolumeDown: emit lessClicked(); return; 149 case VolumeDown: emit lessClicked(); return;
149 case Back: emit backClicked(); return; 150 case Back: emit backClicked(); return;
150 case Forward: emit forwardClicked(); return; 151 case Forward: emit forwardClicked(); return;
151 default: break; 152 default: break;
152 } 153 }
153} 154}
154 155
155void MediaWidget::mouseReleaseEvent( QMouseEvent *event ) 156void MediaWidget::mouseReleaseEvent( QMouseEvent *event )
156{ 157{
157 Button *button = buttonAt( event->pos() - upperLeftOfButtonMask ); 158 Button *button = buttonAt( event->pos() - upperLeftOfButtonMask );
158 159
159 if ( !button ) { 160 if ( !button ) {
160 QWidget::mouseReleaseEvent( event ); 161 QWidget::mouseReleaseEvent( event );
161 return; 162 return;
162 } 163 }
163 164
164 if ( button->type == ToggleButton ) 165 if ( button->type == ToggleButton )
165 toggleButton( *button ); 166 toggleButton( *button );
166 167
167 handleCommand( button->command, button->isDown ); 168 handleCommand( button->command, button->isDown );
168} 169}
169 170
170void MediaWidget::makeVisible() 171void MediaWidget::makeVisible()
171{ 172{
172} 173}
173 174
174void MediaWidget::handleCommand( Command command, bool buttonDown ) 175void MediaWidget::handleCommand( Command command, bool buttonDown )
175{ 176{
176 switch ( command ) { 177 switch ( command ) {
177 case Play: mediaPlayerState.togglePaused(); return; 178 case Play: mediaPlayerState.togglePaused(); return;
178 case Stop: mediaPlayerState.setPlaying(FALSE); return; 179 case Stop: mediaPlayerState.setPlaying(FALSE); return;
179 case Next: if( playList.currentTab() == PlayListWidget::CurrentPlayList ) mediaPlayerState.setNext(); return; 180 case Next: if( playList.currentTab() == PlayListWidget::CurrentPlayList ) mediaPlayerState.setNext(); return;
180 case Previous: if( playList.currentTab() == PlayListWidget::CurrentPlayList ) mediaPlayerState.setPrev(); return; 181 case Previous: if( playList.currentTab() == PlayListWidget::CurrentPlayList ) mediaPlayerState.setPrev(); return;
181 case Loop: mediaPlayerState.setLooping( buttonDown ); return; 182 case Loop: mediaPlayerState.setLooping( buttonDown ); return;
182 case VolumeUp: emit moreReleased(); return; 183 case VolumeUp: emit moreReleased(); return;
183 case VolumeDown: emit lessReleased(); return; 184 case VolumeDown: emit lessReleased(); return;
184 case PlayList: mediaPlayerState.setList(); return; 185 case PlayList: mediaPlayerState.setList(); return;
185 case Forward: emit forwardReleased(); return; 186 case Forward: emit forwardReleased(); return;
186 case Back: emit backReleased(); return; 187 case Back: emit backReleased(); return;
187 case FullScreen: mediaPlayerState.setFullscreen( true ); makeVisible(); return; 188 case FullScreen: mediaPlayerState.setFullscreen( true ); makeVisible(); return;
188 default: assert( false ); 189 default: assert( false );
189 } 190 }
190} 191}
191 192
192bool MediaWidget::isOverButton( const QPoint &position, int buttonId ) const 193bool MediaWidget::isOverButton( const QPoint &position, int buttonId ) const
193{ 194{
194 return ( position.x() > 0 && position.y() > 0 && 195 return ( position.x() > 0 && position.y() > 0 &&
195 position.x() < buttonMask.width() && 196 position.x() < buttonMask.width() &&
196 position.y() < buttonMask.height() && 197 position.y() < buttonMask.height() &&
197 buttonMask.pixelIndex( position.x(), position.y() ) == buttonId + 1 ); 198 buttonMask.pixelIndex( position.x(), position.y() ) == buttonId + 1 );
198} 199}
199 200
200void MediaWidget::paintAllButtons( QPainter &p ) 201void MediaWidget::paintAllButtons( QPainter &p )
201{ 202{
202 for ( ButtonVector::const_iterator it = buttons.begin(); 203 for ( ButtonVector::const_iterator it = buttons.begin();
203 it != buttons.end(); ++it ) 204 it != buttons.end(); ++it )
204 paintButton( p, *it ); 205 paintButton( p, *it );
205} 206}
206 207
207void MediaWidget::paintButton( const Button &button ) 208void MediaWidget::paintButton( const Button &button )
208{ 209{
209 QPainter p( this ); 210 QPainter p( this );
210 paintButton( p, button ); 211 paintButton( p, button );
211} 212}
212 213
213void MediaWidget::paintButton( QPainter &p, const Button &button ) 214void MediaWidget::paintButton( QPainter &p, const Button &button )
214{ 215{
215 if ( button.isDown ) 216 if ( button.isDown )
216 p.drawPixmap( upperLeftOfButtonMask, button.pixDown ); 217 p.drawPixmap( upperLeftOfButtonMask, button.pixDown );
217 else 218 else
218 p.drawPixmap( upperLeftOfButtonMask, button.pixUp ); 219 p.drawPixmap( upperLeftOfButtonMask, button.pixUp );
219} 220}
220 221
221void MediaWidget::setToggleButton( Command command, bool down ) 222void MediaWidget::setToggleButton( Command command, bool down )
222{ 223{
223 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it ) 224 for ( ButtonVector::iterator it = buttons.begin(); it != buttons.end(); ++it )
224 if ( it->command == command ) { 225 if ( it->command == command ) {
225 setToggleButton( *it, down ); 226 setToggleButton( *it, down );
226 return; 227 return;
227 } 228 }
228} 229}
229 230
230void MediaWidget::setToggleButton( Button &button, bool down ) 231void MediaWidget::setToggleButton( Button &button, bool down )
231{ 232{
232 if ( down != button.isDown ) 233 if ( down != button.isDown )
233 toggleButton( button ); 234 toggleButton( button );
234} 235}
235 236
236void MediaWidget::toggleButton( Button &button ) 237void MediaWidget::toggleButton( Button &button )
237{ 238{
238 button.isDown = !button.isDown; 239 button.isDown = !button.isDown;
239 240
240 paintButton( button ); 241 paintButton( button );
241} 242}
242 243
243QPixmap MediaWidget::combineImageWithBackground( const QImage &image, const QPixmap &background, const QPoint &offset ) 244QPixmap MediaWidget::combineImageWithBackground( const QImage &image, const QPixmap &background, const QPoint &offset )
244{ 245{
245 QPixmap pix( image.size() ); 246 QPixmap pix( image.size() );
246 QPainter p( &pix ); 247 QPainter p( &pix );
247 p.drawTiledPixmap( pix.rect(), background, offset ); 248 p.drawTiledPixmap( pix.rect(), background, offset );
248 p.drawImage( 0, 0, image ); 249 p.drawImage( 0, 0, image );
249 return pix; 250 return pix;
250} 251}
251 252
252QPixmap MediaWidget::addMaskToPixmap( const QPixmap &pix, const QBitmap &mask ) 253QPixmap MediaWidget::addMaskToPixmap( const QPixmap &pix, const QBitmap &mask )
253{ 254{
254 QPixmap result( pix ); 255 QPixmap result( pix );
255 result.setMask( mask ); 256 result.setMask( mask );
256 return result; 257 return result;
257} 258}
258 259
259/* vim: et sw=4 ts=4 260/* vim: et sw=4 ts=4
260 */ 261 */
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp
index a8f4ae9..44f5ca2 100644
--- a/noncore/multimedia/opieplayer2/skin.cpp
+++ b/noncore/multimedia/opieplayer2/skin.cpp
@@ -1,320 +1,324 @@
1/* 1/*
2 Copyright (C) 2002 Simon Hausmann <simon@lst.de> 2 Copyright (C) 2002 Simon Hausmann <simon@lst.de>
3 (C) 2002 Max Reiss <harlekin@handhelds.org> 3 (C) 2002 Max Reiss <harlekin@handhelds.org>
4 (C) 2002 L. Potter <ljp@llornkcor.com> 4 (C) 2002 L. Potter <ljp@llornkcor.com>
5 (C) 2002 Holger Freyther <zecke@handhelds.org> 5 (C) 2002 Holger Freyther <zecke@handhelds.org>
6 6
7 This program is free software; you can redistribute it and/or 7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public 8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details. 15 General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to 18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#include "skin.h" 23#include "skin.h"
24#include "singleton.h" 24#include "singleton.h"
25 25
26#include <qcache.h> 26#include <qcache.h>
27#include <qmap.h> 27#include <qmap.h>
28#include <qtimer.h> 28#include <qtimer.h>
29 29
30#include <qpe/resource.h> 30#include <qpe/resource.h>
31#include <qpe/config.h> 31#include <qpe/config.h>
32 32
33#include <assert.h> 33#include <assert.h>
34 34
35struct SkinData 35struct SkinData
36{ 36{
37 typedef QMap<QString, QImage> ButtonMaskImageMap; 37 typedef QMap<QString, QImage> ButtonMaskImageMap;
38 38
39 QPixmap backgroundPixmap; 39 QPixmap backgroundPixmap;
40 QImage buttonUpImage; 40 QImage buttonUpImage;
41 QImage buttonDownImage; 41 QImage buttonDownImage;
42 QImage buttonMask; 42 QImage buttonMask;
43 ButtonMaskImageMap buttonMasks; 43 ButtonMaskImageMap buttonMasks;
44}; 44};
45 45
46class SkinCache : public Singleton<SkinCache> 46class SkinCache : public Singleton<SkinCache>
47{ 47{
48public: 48public:
49 SkinCache(); 49 SkinCache();
50 50
51 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix ); 51 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix );
52 52
53 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ); 53 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data );
54 54
55private: 55private:
56 typedef QCache<SkinData> DataCache; 56 typedef QCache<SkinData> DataCache;
57 typedef QCache<QPixmap> BackgroundPixmapCache; 57 typedef QCache<QPixmap> BackgroundPixmapCache;
58 58
59 template <class CacheType> 59 template <class CacheType>
60 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data ); 60 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data );
61 61
62 DataCache m_cache; 62 DataCache m_cache;
63 BackgroundPixmapCache m_backgroundPixmapCache; 63 BackgroundPixmapCache m_backgroundPixmapCache;
64}; 64};
65 65
66Skin::Skin( const QString &name, const QString &fileNameInfix ) 66Skin::Skin( const QString &name, const QString &fileNameInfix )
67 : m_fileNameInfix( fileNameInfix ) 67 : m_fileNameInfix( fileNameInfix )
68{ 68{
69 init( name ); 69 init( name );
70} 70}
71 71
72Skin::Skin( const QString &fileNameInfix ) 72Skin::Skin( const QString &fileNameInfix )
73 : m_fileNameInfix( fileNameInfix ) 73 : m_fileNameInfix( fileNameInfix )
74{ 74{
75 init( defaultSkinName() ); 75 init( defaultSkinName() );
76} 76}
77 77
78Skin::~Skin() 78Skin::~Skin()
79{ 79{
80 SkinCache::self().store( m_skinPath, m_fileNameInfix, d ); 80 if ( m_isCachable )
81 SkinCache::self().store( m_skinPath, m_fileNameInfix, d );
82 else
83 delete d;
81} 84}
82 85
83void Skin::init( const QString &name ) 86void Skin::init( const QString &name )
84{ 87{
88 m_isCachable = true;
85 m_skinPath = "opieplayer2/skins/" + name; 89 m_skinPath = "opieplayer2/skins/" + name;
86 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix ); 90 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix );
87} 91}
88 92
89QPixmap Skin::backgroundPixmap() const 93QPixmap Skin::backgroundPixmap() const
90{ 94{
91 if ( d->backgroundPixmap.isNull() ) 95 if ( d->backgroundPixmap.isNull() )
92 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); 96 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) );
93 return d->backgroundPixmap; 97 return d->backgroundPixmap;
94} 98}
95 99
96QImage Skin::buttonUpImage() const 100QImage Skin::buttonUpImage() const
97{ 101{
98 if ( d->buttonUpImage.isNull() ) 102 if ( d->buttonUpImage.isNull() )
99 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 103 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
100 return d->buttonUpImage; 104 return d->buttonUpImage;
101} 105}
102 106
103QImage Skin::buttonDownImage() const 107QImage Skin::buttonDownImage() const
104{ 108{
105 if ( d->buttonDownImage.isNull() ) 109 if ( d->buttonDownImage.isNull() )
106 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 110 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
107 return d->buttonDownImage; 111 return d->buttonDownImage;
108} 112}
109 113
110QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const 114QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const
111{ 115{
112 if ( !d->buttonMask.isNull() ) 116 if ( !d->buttonMask.isNull() )
113 return d->buttonMask; 117 return d->buttonMask;
114 118
115 QSize buttonAreaSize = buttonUpImage().size(); 119 QSize buttonAreaSize = buttonUpImage().size();
116 120
117 d->buttonMask = QImage( buttonAreaSize, 8, 255 ); 121 d->buttonMask = QImage( buttonAreaSize, 8, 255 );
118 d->buttonMask.fill( 0 ); 122 d->buttonMask.fill( 0 );
119 123
120 for ( uint i = 0; i < buttonCount; ++i ) 124 for ( uint i = 0; i < buttonCount; ++i )
121 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) ); 125 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) );
122 126
123 return d->buttonMask; 127 return d->buttonMask;
124} 128}
125 129
126void Skin::addButtonToMask( int tag, const QImage &maskImage ) const 130void Skin::addButtonToMask( int tag, const QImage &maskImage ) const
127{ 131{
128 if ( maskImage.isNull() ) 132 if ( maskImage.isNull() )
129 return; 133 return;
130 134
131 uchar **dest = d->buttonMask.jumpTable(); 135 uchar **dest = d->buttonMask.jumpTable();
132 for ( int y = 0; y < d->buttonMask.height(); y++ ) { 136 for ( int y = 0; y < d->buttonMask.height(); y++ ) {
133 uchar *line = dest[y]; 137 uchar *line = dest[y];
134 for ( int x = 0; x < d->buttonMask.width(); x++ ) 138 for ( int x = 0; x < d->buttonMask.width(); x++ )
135 if ( !qRed( maskImage.pixel( x, y ) ) ) 139 if ( !qRed( maskImage.pixel( x, y ) ) )
136 line[x] = tag; 140 line[x] = tag;
137 } 141 }
138} 142}
139 143
140QImage Skin::buttonMaskImage( const QString &fileName ) const 144QImage Skin::buttonMaskImage( const QString &fileName ) const
141{ 145{
142 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); 146 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName );
143 if ( it == d->buttonMasks.end() ) { 147 if ( it == d->buttonMasks.end() ) {
144 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); 148 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix );
145 QString path = prefix + fileName + ".png"; 149 QString path = prefix + fileName + ".png";
146 it = d->buttonMasks.insert( fileName, loadImage( path ) ); 150 it = d->buttonMasks.insert( fileName, loadImage( path ) );
147 } 151 }
148 return *it; 152 return *it;
149} 153}
150 154
151QString Skin::defaultSkinName() 155QString Skin::defaultSkinName()
152{ 156{
153 Config cfg( "OpiePlayer" ); 157 Config cfg( "OpiePlayer" );
154 cfg.setGroup( "Options" ); 158 cfg.setGroup( "Options" );
155 return cfg.readEntry( "Skin", "default" ); 159 return cfg.readEntry( "Skin", "default" );
156} 160}
157 161
158QImage Skin::loadImage( const QString &fileName ) 162QImage Skin::loadImage( const QString &fileName )
159{ 163{
160 return QImage( Resource::findPixmap( fileName ) ); 164 return QImage( Resource::findPixmap( fileName ) );
161} 165}
162 166
163SkinCache::SkinCache() 167SkinCache::SkinCache()
164{ 168{
165 // let's say we cache two skins (audio+video) at maximum 169 // let's say we cache two skins (audio+video) at maximum
166 m_cache.setMaxCost( 2 ); 170 m_cache.setMaxCost( 2 );
167 // ... and one background pixmap 171 // ... and one background pixmap
168 m_backgroundPixmapCache.setMaxCost( 1 ); 172 m_backgroundPixmapCache.setMaxCost( 1 );
169} 173}
170 174
171SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix ) 175SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix )
172{ 176{
173 QString key = skinPath + fileNameInfix; 177 QString key = skinPath + fileNameInfix;
174 178
175 SkinData *data = m_cache.take( key ); 179 SkinData *data = m_cache.take( key );
176 if ( !data ) 180 if ( !data )
177 data = new SkinData; 181 data = new SkinData;
178 else 182 else
179 qDebug( "SkinCache: hit" ); 183 qDebug( "SkinCache: hit" );
180 184
181 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath ); 185 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath );
182 if ( bgPixmap ) { 186 if ( bgPixmap ) {
183 qDebug( "SkinCache: hit on bgpixmap" ); 187 qDebug( "SkinCache: hit on bgpixmap" );
184 data->backgroundPixmap = *bgPixmap; 188 data->backgroundPixmap = *bgPixmap;
185 } 189 }
186 else 190 else
187 data->backgroundPixmap = QPixmap(); 191 data->backgroundPixmap = QPixmap();
188 192
189 return data; 193 return data;
190} 194}
191 195
192void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ) 196void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data )
193{ 197{
194 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap ); 198 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap );
195 199
196 data->backgroundPixmap = QPixmap(); 200 data->backgroundPixmap = QPixmap();
197 201
198 QString key = skinPath + fileNameInfix; 202 QString key = skinPath + fileNameInfix;
199 203
200 if ( m_cache.find( key, false /*ref*/ ) != 0 || 204 if ( m_cache.find( key, false /*ref*/ ) != 0 ||
201 !m_cache.insert( key, data ) ) 205 !m_cache.insert( key, data ) )
202 delete data; 206 delete data;
203 207
204 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 || 208 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 ||
205 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) ) 209 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) )
206 delete backgroundPixmap; 210 delete backgroundPixmap;
207} 211}
208 212
209SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info ) 213SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info )
210 : m_skin( info.skinName, info.fileNameInfix ), m_info( info ) 214 : m_skin( info.skinName, info.fileNameInfix ), m_info( info )
211{ 215{
212 m_currentState = LoadBackgroundPixmap; 216 m_currentState = LoadBackgroundPixmap;
213} 217}
214 218
215SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep() 219SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep()
216{ 220{
217 switch ( m_currentState ) { 221 switch ( m_currentState ) {
218 case LoadBackgroundPixmap: 222 case LoadBackgroundPixmap:
219 qDebug( "load bgpixmap" ); 223 qDebug( "load bgpixmap" );
220 m_skin.backgroundPixmap(); 224 m_skin.backgroundPixmap();
221 m_currentState = LoadButtonUpImage; 225 m_currentState = LoadButtonUpImage;
222 break; 226 break;
223 case LoadButtonUpImage: 227 case LoadButtonUpImage:
224 qDebug( "load upimage" ); 228 qDebug( "load upimage" );
225 m_skin.buttonUpImage(); 229 m_skin.buttonUpImage();
226 m_currentState = LoadButtonDownImage; 230 m_currentState = LoadButtonDownImage;
227 break; 231 break;
228 case LoadButtonDownImage: 232 case LoadButtonDownImage:
229 qDebug( "load downimage" ); 233 qDebug( "load downimage" );
230 m_skin.buttonDownImage(); 234 m_skin.buttonDownImage();
231 m_currentState = LoadButtonMasks; 235 m_currentState = LoadButtonMasks;
232 m_currentButton = 0; 236 m_currentButton = 0;
233 break; 237 break;
234 case LoadButtonMasks: 238 case LoadButtonMasks:
235 qDebug( "load button masks %i", m_currentButton ); 239 qDebug( "load button masks %i", m_currentButton );
236 m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName ); 240 m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName );
237 241
238 m_currentButton++; 242 m_currentButton++;
239 if ( m_currentButton >= m_info.buttonCount ) 243 if ( m_currentButton >= m_info.buttonCount )
240 m_currentState = LoadButtonMask; 244 m_currentState = LoadButtonMask;
241 245
242 break; 246 break;
243 case LoadButtonMask: 247 case LoadButtonMask:
244 qDebug( "load whole mask" ); 248 qDebug( "load whole mask" );
245 m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount ); 249 m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount );
246 return LoadingCompleted; 250 return LoadingCompleted;
247 } 251 }
248 252
249 return MoreToCome; 253 return MoreToCome;
250} 254}
251 255
252SkinLoader::SkinLoader() 256SkinLoader::SkinLoader()
253 : m_currentLoader( 0 ), m_timerId( -1 ) 257 : m_currentLoader( 0 ), m_timerId( -1 )
254{ 258{
255} 259}
256 260
257SkinLoader::~SkinLoader() 261SkinLoader::~SkinLoader()
258{ 262{
259 qDebug( "SkinLoader::~SkinLoader()" ); 263 qDebug( "SkinLoader::~SkinLoader()" );
260 killTimers(); 264 killTimers();
261 delete m_currentLoader; 265 delete m_currentLoader;
262} 266}
263 267
264void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo ) 268void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo )
265{ 269{
266 schedule( Skin::defaultSkinName(), guiInfo ); 270 schedule( Skin::defaultSkinName(), guiInfo );
267} 271}
268 272
269void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo ) 273void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo )
270{ 274{
271 pendingSkins << Info( skinName, guiInfo ); 275 pendingSkins << Info( skinName, guiInfo );
272} 276}
273 277
274void SkinLoader::start() 278void SkinLoader::start()
275{ 279{
276 assert( m_timerId == -1 ); 280 assert( m_timerId == -1 );
277 m_timerId = startTimer( 100 /* ms */ ); 281 m_timerId = startTimer( 100 /* ms */ );
278 qDebug( "SkinLoader::start() %d jobs", pendingSkins.count() ); 282 qDebug( "SkinLoader::start() %d jobs", pendingSkins.count() );
279} 283}
280 284
281void SkinLoader::timerEvent( QTimerEvent *ev ) 285void SkinLoader::timerEvent( QTimerEvent *ev )
282{ 286{
283 if ( ev->timerId() != m_timerId ) { 287 if ( ev->timerId() != m_timerId ) {
284 QObject::timerEvent( ev ); 288 QObject::timerEvent( ev );
285 return; 289 return;
286 } 290 }
287 291
288 if ( !m_currentLoader ) { 292 if ( !m_currentLoader ) {
289 293
290 if ( pendingSkins.isEmpty() ) { 294 if ( pendingSkins.isEmpty() ) {
291 qDebug( "all jobs done" ); 295 qDebug( "all jobs done" );
292 killTimer( m_timerId ); 296 killTimer( m_timerId );
293 m_timerId = -1; 297 m_timerId = -1;
294 // ### qt3: use deleteLater(); 298 // ### qt3: use deleteLater();
295 QTimer::singleShot( 0, this, SLOT( deleteMe() ) ); 299 QTimer::singleShot( 0, this, SLOT( deleteMe() ) );
296 return; 300 return;
297 } 301 }
298 302
299 Info nfo = *pendingSkins.begin(); 303 Info nfo = *pendingSkins.begin();
300 pendingSkins.remove( pendingSkins.begin() ); 304 pendingSkins.remove( pendingSkins.begin() );
301 305
302 m_currentLoader = new IncrementalLoader( nfo ); 306 m_currentLoader = new IncrementalLoader( nfo );
303 qDebug( "new loader %i jobs left", pendingSkins.count() ); 307 qDebug( "new loader %i jobs left", pendingSkins.count() );
304 } 308 }
305 309
306 if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) { 310 if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) {
307 delete m_currentLoader; 311 delete m_currentLoader;
308 m_currentLoader = 0; 312 m_currentLoader = 0;
309 } 313 }
310 314
311 qDebug( "finished step" ); 315 qDebug( "finished step" );
312} 316}
313 317
314void SkinLoader::deleteMe() 318void SkinLoader::deleteMe()
315{ 319{
316 delete this; 320 delete this;
317} 321}
318 322
319/* vim: et sw=4 ts=4 323/* vim: et sw=4 ts=4
320 */ 324 */
diff --git a/noncore/multimedia/opieplayer2/skin.h b/noncore/multimedia/opieplayer2/skin.h
index bafebd3..067b6c4 100644
--- a/noncore/multimedia/opieplayer2/skin.h
+++ b/noncore/multimedia/opieplayer2/skin.h
@@ -1,122 +1,126 @@
1/* 1/*
2 Copyright (C) 2002 Simon Hausmann <simon@lst.de> 2 Copyright (C) 2002 Simon Hausmann <simon@lst.de>
3 (C) 2002 Max Reiss <harlekin@handhelds.org> 3 (C) 2002 Max Reiss <harlekin@handhelds.org>
4 (C) 2002 L. Potter <ljp@llornkcor.com> 4 (C) 2002 L. Potter <ljp@llornkcor.com>
5 (C) 2002 Holger Freyther <zecke@handhelds.org> 5 (C) 2002 Holger Freyther <zecke@handhelds.org>
6 6
7 This program is free software; you can redistribute it and/or 7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public 8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either 9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version. 10 version 2 of the License, or (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details. 15 General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to 18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 20 Boston, MA 02111-1307, USA.
21*/ 21*/
22 22
23#ifndef SKIN_H 23#ifndef SKIN_H
24#define SKIN_H 24#define SKIN_H
25 25
26#include <qstring.h> 26#include <qstring.h>
27#include <qimage.h> 27#include <qimage.h>
28#include <qobject.h> 28#include <qobject.h>
29 29
30#include "mediawidget.h" 30#include "mediawidget.h"
31 31
32struct SkinData; 32struct SkinData;
33 33
34class Skin 34class Skin
35{ 35{
36public: 36public:
37 Skin( const QString &name, const QString &fileNameInfix ); 37 Skin( const QString &name, const QString &fileNameInfix );
38 Skin( const QString &fileNameInfix ); 38 Skin( const QString &fileNameInfix );
39 ~Skin(); 39 ~Skin();
40 40
41 bool isCachable() const { return m_isCachable; }
42 void setCachable( bool cachable ) { m_isCachable = cachable; }
43
41 QPixmap backgroundPixmap() const; 44 QPixmap backgroundPixmap() const;
42 QImage buttonUpImage() const; 45 QImage buttonUpImage() const;
43 QImage buttonDownImage() const; 46 QImage buttonDownImage() const;
44 47
45 QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const; 48 QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const;
46 49
47 QImage buttonMaskImage( const QString &fileName ) const; 50 QImage buttonMaskImage( const QString &fileName ) const;
48 51
49 static QString defaultSkinName(); 52 static QString defaultSkinName();
50 53
51private: 54private:
52 void init( const QString &name ); 55 void init( const QString &name );
53 56
54 void addButtonToMask( int tag, const QImage &maskImage ) const; 57 void addButtonToMask( int tag, const QImage &maskImage ) const;
55 58
56 static QImage loadImage( const QString &fileName ); 59 static QImage loadImage( const QString &fileName );
57 60
58 QString m_fileNameInfix; 61 QString m_fileNameInfix;
59 QString m_skinPath; 62 QString m_skinPath;
63 bool m_isCachable : 1;
60 64
61 SkinData *d; 65 SkinData *d;
62 66
63 Skin( const Skin & ); 67 Skin( const Skin & );
64 Skin &operator=( const Skin & ); 68 Skin &operator=( const Skin & );
65}; 69};
66 70
67class SkinLoader : public QObject 71class SkinLoader : public QObject
68{ 72{
69 Q_OBJECT 73 Q_OBJECT
70public: 74public:
71 SkinLoader(); 75 SkinLoader();
72 virtual ~SkinLoader(); 76 virtual ~SkinLoader();
73 77
74 void schedule( const MediaWidget::GUIInfo &guiInfo ); 78 void schedule( const MediaWidget::GUIInfo &guiInfo );
75 void schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo ); 79 void schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo );
76 80
77 void start(); 81 void start();
78 82
79protected: 83protected:
80 virtual void timerEvent( QTimerEvent *ev ); 84 virtual void timerEvent( QTimerEvent *ev );
81 85
82private slots: 86private slots:
83 void deleteMe(); 87 void deleteMe();
84 88
85private: 89private:
86 struct Info : public MediaWidget::GUIInfo 90 struct Info : public MediaWidget::GUIInfo
87 { 91 {
88 Info() {} 92 Info() {}
89 Info( const QString &_skinName, const MediaWidget::GUIInfo &guiInfo ) 93 Info( const QString &_skinName, const MediaWidget::GUIInfo &guiInfo )
90 : MediaWidget::GUIInfo( guiInfo ), skinName( _skinName ) 94 : MediaWidget::GUIInfo( guiInfo ), skinName( _skinName )
91 {} 95 {}
92 96
93 QString skinName; 97 QString skinName;
94 }; 98 };
95 typedef QValueList<Info> InfoList; 99 typedef QValueList<Info> InfoList;
96 100
97 class IncrementalLoader 101 class IncrementalLoader
98 { 102 {
99 public: 103 public:
100 enum LoaderResult { LoadingCompleted, MoreToCome }; 104 enum LoaderResult { LoadingCompleted, MoreToCome };
101 105
102 IncrementalLoader( const Info &info ); 106 IncrementalLoader( const Info &info );
103 107
104 LoaderResult loadStep(); 108 LoaderResult loadStep();
105 109
106 private: 110 private:
107 enum State { LoadBackgroundPixmap, LoadButtonUpImage, LoadButtonDownImage, LoadButtonMasks, LoadButtonMask }; 111 enum State { LoadBackgroundPixmap, LoadButtonUpImage, LoadButtonDownImage, LoadButtonMasks, LoadButtonMask };
108 112
109 Skin m_skin; 113 Skin m_skin;
110 Info m_info; 114 Info m_info;
111 State m_currentState; 115 State m_currentState;
112 uint m_currentButton; 116 uint m_currentButton;
113 }; 117 };
114 118
115 InfoList pendingSkins; 119 InfoList pendingSkins;
116 IncrementalLoader *m_currentLoader; 120 IncrementalLoader *m_currentLoader;
117 int m_timerId; 121 int m_timerId;
118}; 122};
119 123
120#endif // SKIN_H 124#endif // SKIN_H
121/* vim: et sw=4 ts=4 125/* vim: et sw=4 ts=4
122 */ 126 */