summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/skin.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp
index b2c1649..b95c544 100644
--- a/noncore/multimedia/opieplayer2/skin.cpp
+++ b/noncore/multimedia/opieplayer2/skin.cpp
@@ -1,324 +1,329 @@
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
26/* OPIE */
25#include <opie2/odebug.h> 27#include <opie2/odebug.h>
28#include <opie2/oresource.h>
29using namespace Opie::Core;
30#include <qpe/config.h>
31#include <qpe/global.h>
26 32
33/* QT */
27#include <qcache.h> 34#include <qcache.h>
28#include <qtimer.h> 35#include <qtimer.h>
29 36
30#include <qpe/config.h> 37/* STD */
31#include <qpe/global.h>
32
33#include <assert.h> 38#include <assert.h>
34 39
35struct SkinData 40struct SkinData
36{ 41{
37 typedef QMap<QString, QImage> ButtonMaskImageMap; 42 typedef QMap<QString, QImage> ButtonMaskImageMap;
38 43
39 QPixmap backgroundPixmap; 44 QPixmap backgroundPixmap;
40 QImage buttonUpImage; 45 QImage buttonUpImage;
41 QImage buttonDownImage; 46 QImage buttonDownImage;
42 QImage buttonMask; 47 QImage buttonMask;
43 ButtonMaskImageMap buttonMasks; 48 ButtonMaskImageMap buttonMasks;
44}; 49};
45 50
46class SkinCache : public Singleton<SkinCache> 51class SkinCache : public Singleton<SkinCache>
47{ 52{
48public: 53public:
49 SkinCache(); 54 SkinCache();
50 55
51 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix ); 56 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix );
52 57
53 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ); 58 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data );
54 59
55private: 60private:
56 typedef QCache<SkinData> DataCache; 61 typedef QCache<SkinData> DataCache;
57 typedef QCache<QPixmap> BackgroundPixmapCache; 62 typedef QCache<QPixmap> BackgroundPixmapCache;
58 63
59 template <class CacheType> 64 template <class CacheType>
60 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data ); 65 void store( const QCache<CacheType> &cache, const QString &key, CacheType *data );
61 66
62 DataCache m_cache; 67 DataCache m_cache;
63 BackgroundPixmapCache m_backgroundPixmapCache; 68 BackgroundPixmapCache m_backgroundPixmapCache;
64}; 69};
65 70
66Skin::Skin( const QString &name, const QString &fileNameInfix ) 71Skin::Skin( const QString &name, const QString &fileNameInfix )
67 : m_fileNameInfix( fileNameInfix ) 72 : m_fileNameInfix( fileNameInfix )
68{ 73{
69 init( name ); 74 init( name );
70} 75}
71 76
72Skin::Skin( const QString &fileNameInfix ) 77Skin::Skin( const QString &fileNameInfix )
73 : m_fileNameInfix( fileNameInfix ) 78 : m_fileNameInfix( fileNameInfix )
74{ 79{
75 init( defaultSkinName() ); 80 init( defaultSkinName() );
76} 81}
77 82
78Skin::~Skin() 83Skin::~Skin()
79{ 84{
80 if ( m_isCachable ) 85 if ( m_isCachable )
81 SkinCache::self().store( m_skinPath, m_fileNameInfix, d ); 86 SkinCache::self().store( m_skinPath, m_fileNameInfix, d );
82 else 87 else
83 delete d; 88 delete d;
84} 89}
85 90
86void Skin::init( const QString &name ) 91void Skin::init( const QString &name )
87{ 92{
88 m_isCachable = true; 93 m_isCachable = true;
89 m_skinPath = "opieplayer2/skins/" + name; 94 m_skinPath = "opieplayer2/skins/" + name;
90 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix ); 95 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix );
91} 96}
92 97
93QPixmap Skin::backgroundPixmap() const 98QPixmap Skin::backgroundPixmap() const
94{ 99{
95 if ( d->backgroundPixmap.isNull() ) 100 if ( d->backgroundPixmap.isNull() )
96 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); 101 d->backgroundPixmap = loadImage( QString( "%1/background" ).arg( m_skinPath ) );
97 return d->backgroundPixmap; 102 return d->backgroundPixmap;
98} 103}
99 104
100QImage Skin::buttonUpImage() const 105QImage Skin::buttonUpImage() const
101{ 106{
102 if ( d->buttonUpImage.isNull() ) 107 if ( d->buttonUpImage.isNull() )
103 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 108 d->buttonUpImage = loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
104 return d->buttonUpImage; 109 return d->buttonUpImage;
105} 110}
106 111
107QImage Skin::buttonDownImage() const 112QImage Skin::buttonDownImage() const
108{ 113{
109 if ( d->buttonDownImage.isNull() ) 114 if ( d->buttonDownImage.isNull() )
110 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); 115 d->buttonDownImage = loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) );
111 return d->buttonDownImage; 116 return d->buttonDownImage;
112} 117}
113 118
114QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const 119QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const
115{ 120{
116 if ( !d->buttonMask.isNull() ) 121 if ( !d->buttonMask.isNull() )
117 return d->buttonMask; 122 return d->buttonMask;
118 123
119 QSize buttonAreaSize = buttonUpImage().size(); 124 QSize buttonAreaSize = buttonUpImage().size();
120 125
121 d->buttonMask = QImage( buttonAreaSize, 8, 255 ); 126 d->buttonMask = QImage( buttonAreaSize, 8, 255 );
122 d->buttonMask.fill( 0 ); 127 d->buttonMask.fill( 0 );
123 128
124 for ( uint i = 0; i < buttonCount; ++i ) 129 for ( uint i = 0; i < buttonCount; ++i )
125 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) ); 130 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) );
126 131
127 return d->buttonMask; 132 return d->buttonMask;
128} 133}
129 134
130void Skin::addButtonToMask( int tag, const QImage &maskImage ) const 135void Skin::addButtonToMask( int tag, const QImage &maskImage ) const
131{ 136{
132 if ( maskImage.isNull() ) 137 if ( maskImage.isNull() )
133 return; 138 return;
134 139
135 uchar **dest = d->buttonMask.jumpTable(); 140 uchar **dest = d->buttonMask.jumpTable();
136 for ( int y = 0; y < d->buttonMask.height(); y++ ) { 141 for ( int y = 0; y < d->buttonMask.height(); y++ ) {
137 uchar *line = dest[y]; 142 uchar *line = dest[y];
138 for ( int x = 0; x < d->buttonMask.width(); x++ ) 143 for ( int x = 0; x < d->buttonMask.width(); x++ )
139 if ( !qRed( maskImage.pixel( x, y ) ) ) 144 if ( !qRed( maskImage.pixel( x, y ) ) )
140 line[x] = tag; 145 line[x] = tag;
141 } 146 }
142} 147}
143 148
144QImage Skin::buttonMaskImage( const QString &fileName ) const 149QImage Skin::buttonMaskImage( const QString &fileName ) const
145{ 150{
146 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); 151 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName );
147 if ( it == d->buttonMasks.end() ) { 152 if ( it == d->buttonMasks.end() ) {
148 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); 153 QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix );
149 QString path = prefix + fileName; 154 QString path = prefix + fileName;
150 it = d->buttonMasks.insert( fileName, loadImage( path ) ); 155 it = d->buttonMasks.insert( fileName, loadImage( path ) );
151 } 156 }
152 return *it; 157 return *it;
153} 158}
154 159
155QString Skin::defaultSkinName() 160QString Skin::defaultSkinName()
156{ 161{
157 Config cfg( "OpiePlayer" ); 162 Config cfg( "OpiePlayer" );
158 cfg.setGroup( "Options" ); 163 cfg.setGroup( "Options" );
159 return cfg.readEntry( "Skin", "default" ); 164 return cfg.readEntry( "Skin", "default" );
160} 165}
161 166
162QImage Skin::loadImage( const QString &fileName ) 167QImage Skin::loadImage( const QString &fileName )
163{ 168{
164 return QImage( Resource::findPixmap( fileName ) ); 169 return QImage( OResource::findPixmap( fileName ) );
165} 170}
166 171
167SkinCache::SkinCache() 172SkinCache::SkinCache()
168{ 173{
169 // let's say we cache two skins (audio+video) at maximum 174 // let's say we cache two skins (audio+video) at maximum
170 m_cache.setMaxCost( 2 ); 175 m_cache.setMaxCost( 2 );
171 // ... and one background pixmap 176 // ... and one background pixmap
172 m_backgroundPixmapCache.setMaxCost( 1 ); 177 m_backgroundPixmapCache.setMaxCost( 1 );
173} 178}
174 179
175SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix ) 180SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix )
176{ 181{
177 QString key = skinPath + fileNameInfix; 182 QString key = skinPath + fileNameInfix;
178 183
179 SkinData *data = m_cache.take( key ); 184 SkinData *data = m_cache.take( key );
180 if ( !data ) 185 if ( !data )
181 data = new SkinData; 186 data = new SkinData;
182 else 187 else
183 odebug << "SkinCache: hit" << oendl; 188 odebug << "SkinCache: hit" << oendl;
184 189
185 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath ); 190 QPixmap *bgPixmap = m_backgroundPixmapCache.find( skinPath );
186 if ( bgPixmap ) { 191 if ( bgPixmap ) {
187 odebug << "SkinCache: hit on bgpixmap" << oendl; 192 odebug << "SkinCache: hit on bgpixmap" << oendl;
188 data->backgroundPixmap = *bgPixmap; 193 data->backgroundPixmap = *bgPixmap;
189 } 194 }
190 else 195 else
191 data->backgroundPixmap = QPixmap(); 196 data->backgroundPixmap = QPixmap();
192 197
193 return data; 198 return data;
194} 199}
195 200
196void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data ) 201void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data )
197{ 202{
198 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap ); 203 QPixmap *backgroundPixmap = new QPixmap( data->backgroundPixmap );
199 204
200 data->backgroundPixmap = QPixmap(); 205 data->backgroundPixmap = QPixmap();
201 206
202 QString key = skinPath + fileNameInfix; 207 QString key = skinPath + fileNameInfix;
203 208
204 if ( m_cache.find( key, false /*ref*/ ) != 0 || 209 if ( m_cache.find( key, false /*ref*/ ) != 0 ||
205 !m_cache.insert( key, data ) ) 210 !m_cache.insert( key, data ) )
206 delete data; 211 delete data;
207 212
208 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 || 213 if ( m_backgroundPixmapCache.find( skinPath, false /*ref*/ ) != 0 ||
209 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) ) 214 !m_backgroundPixmapCache.insert( skinPath, backgroundPixmap ) )
210 delete backgroundPixmap; 215 delete backgroundPixmap;
211} 216}
212 217
213SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info ) 218SkinLoader::IncrementalLoader::IncrementalLoader( const Info &info )
214 : m_skin( info.skinName, info.fileNameInfix ), m_info( info ) 219 : m_skin( info.skinName, info.fileNameInfix ), m_info( info )
215{ 220{
216 m_currentState = LoadBackgroundPixmap; 221 m_currentState = LoadBackgroundPixmap;
217} 222}
218 223
219SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep() 224SkinLoader::IncrementalLoader::LoaderResult SkinLoader::IncrementalLoader::loadStep()
220{ 225{
221 switch ( m_currentState ) { 226 switch ( m_currentState ) {
222 case LoadBackgroundPixmap: 227 case LoadBackgroundPixmap:
223 odebug << "load bgpixmap" << oendl; 228 odebug << "load bgpixmap" << oendl;
224 m_skin.backgroundPixmap(); 229 m_skin.backgroundPixmap();
225 m_currentState = LoadButtonUpImage; 230 m_currentState = LoadButtonUpImage;
226 break; 231 break;
227 case LoadButtonUpImage: 232 case LoadButtonUpImage:
228 odebug << "load upimage" << oendl; 233 odebug << "load upimage" << oendl;
229 m_skin.buttonUpImage(); 234 m_skin.buttonUpImage();
230 m_currentState = LoadButtonDownImage; 235 m_currentState = LoadButtonDownImage;
231 break; 236 break;
232 case LoadButtonDownImage: 237 case LoadButtonDownImage:
233 odebug << "load downimage" << oendl; 238 odebug << "load downimage" << oendl;
234 m_skin.buttonDownImage(); 239 m_skin.buttonDownImage();
235 m_currentState = LoadButtonMasks; 240 m_currentState = LoadButtonMasks;
236 m_currentButton = 0; 241 m_currentButton = 0;
237 break; 242 break;
238 case LoadButtonMasks: 243 case LoadButtonMasks:
239 odebug << "load button masks " << m_currentButton << "" << oendl; 244 odebug << "load button masks " << m_currentButton << "" << oendl;
240 m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName ); 245 m_skin.buttonMaskImage( m_info.buttonInfo[ m_currentButton ].fileName );
241 246
242 m_currentButton++; 247 m_currentButton++;
243 if ( m_currentButton >= m_info.buttonCount ) 248 if ( m_currentButton >= m_info.buttonCount )
244 m_currentState = LoadButtonMask; 249 m_currentState = LoadButtonMask;
245 250
246 break; 251 break;
247 case LoadButtonMask: 252 case LoadButtonMask:
248 odebug << "load whole mask" << oendl; 253 odebug << "load whole mask" << oendl;
249 m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount ); 254 m_skin.buttonMask( m_info.buttonInfo, m_info.buttonCount );
250 return LoadingCompleted; 255 return LoadingCompleted;
251 } 256 }
252 257
253 return MoreToCome; 258 return MoreToCome;
254} 259}
255 260
256SkinLoader::SkinLoader() 261SkinLoader::SkinLoader()
257 : m_currentLoader( 0 ), m_timerId( -1 ) 262 : m_currentLoader( 0 ), m_timerId( -1 )
258{ 263{
259} 264}
260 265
261SkinLoader::~SkinLoader() 266SkinLoader::~SkinLoader()
262{ 267{
263 Global::statusMessage( tr( "Loading of Skin finished" ) ); 268 Global::statusMessage( tr( "Loading of Skin finished" ) );
264 killTimers(); 269 killTimers();
265 delete m_currentLoader; 270 delete m_currentLoader;
266} 271}
267 272
268void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo ) 273void SkinLoader::schedule( const MediaWidget::GUIInfo &guiInfo )
269{ 274{
270 schedule( Skin::defaultSkinName(), guiInfo ); 275 schedule( Skin::defaultSkinName(), guiInfo );
271} 276}
272 277
273void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo ) 278void SkinLoader::schedule( const QString &skinName, const MediaWidget::GUIInfo &guiInfo )
274{ 279{
275 pendingSkins << Info( skinName, guiInfo ); 280 pendingSkins << Info( skinName, guiInfo );
276} 281}
277 282
278void SkinLoader::start() 283void SkinLoader::start()
279{ 284{
280 assert( m_timerId == -1 ); 285 assert( m_timerId == -1 );
281 m_timerId = startTimer( 100 /* ms */ ); 286 m_timerId = startTimer( 100 /* ms */ );
282 odebug << "SkinLoader::start() " << pendingSkins.count() << " jobs" << oendl; 287 odebug << "SkinLoader::start() " << pendingSkins.count() << " jobs" << oendl;
283} 288}
284 289
285void SkinLoader::timerEvent( QTimerEvent *ev ) 290void SkinLoader::timerEvent( QTimerEvent *ev )
286{ 291{
287 if ( ev->timerId() != m_timerId ) { 292 if ( ev->timerId() != m_timerId ) {
288 QObject::timerEvent( ev ); 293 QObject::timerEvent( ev );
289 return; 294 return;
290 } 295 }
291 296
292 if ( !m_currentLoader ) { 297 if ( !m_currentLoader ) {
293 298
294 if ( pendingSkins.isEmpty() ) { 299 if ( pendingSkins.isEmpty() ) {
295 odebug << "all jobs done" << oendl; 300 odebug << "all jobs done" << oendl;
296 killTimer( m_timerId ); 301 killTimer( m_timerId );
297 m_timerId = -1; 302 m_timerId = -1;
298 // ### qt3: use deleteLater(); 303 // ### qt3: use deleteLater();
299 QTimer::singleShot( 0, this, SLOT( deleteMe() ) ); 304 QTimer::singleShot( 0, this, SLOT( deleteMe() ) );
300 return; 305 return;
301 } 306 }
302 307
303 Info nfo = *pendingSkins.begin(); 308 Info nfo = *pendingSkins.begin();
304 pendingSkins.remove( pendingSkins.begin() ); 309 pendingSkins.remove( pendingSkins.begin() );
305 310
306 m_currentLoader = new IncrementalLoader( nfo ); 311 m_currentLoader = new IncrementalLoader( nfo );
307 odebug << "new loader " << pendingSkins.count() << " jobs left" << oendl; 312 odebug << "new loader " << pendingSkins.count() << " jobs left" << oendl;
308 } 313 }
309 314
310 if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) { 315 if ( m_currentLoader->loadStep() == IncrementalLoader::LoadingCompleted ) {
311 delete m_currentLoader; 316 delete m_currentLoader;
312 m_currentLoader = 0; 317 m_currentLoader = 0;
313 } 318 }
314 319
315 odebug << "finished step" << oendl; 320 odebug << "finished step" << oendl;
316} 321}
317 322
318void SkinLoader::deleteMe() 323void SkinLoader::deleteMe()
319{ 324{
320 delete this; 325 delete this;
321} 326}
322 327
323/* vim: et sw=4 ts=4 328/* vim: et sw=4 ts=4
324 */ 329 */