summaryrefslogtreecommitdiff
authorsimon <simon>2002-12-11 19:34:20 (UTC)
committer simon <simon>2002-12-11 19:34:20 (UTC)
commitb3373b77e12e4b138848110884aedc37b56384e1 (patch) (unidiff)
tree7432537024816d316d05fdc364d26db73fae190b
parente59fabf981834292c2ed9b7192dd4f789cc4b7cb (diff)
downloadopie-b3373b77e12e4b138848110884aedc37b56384e1.zip
opie-b3373b77e12e4b138848110884aedc37b56384e1.tar.gz
opie-b3373b77e12e4b138848110884aedc37b56384e1.tar.bz2
- SkinCache now operates on SkinData instead of single images
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/skin.cpp37
-rw-r--r--noncore/multimedia/opieplayer2/skin.h2
2 files changed, 18 insertions, 21 deletions
diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp
index d2e3b00..5013bb4 100644
--- a/noncore/multimedia/opieplayer2/skin.cpp
+++ b/noncore/multimedia/opieplayer2/skin.cpp
@@ -1,211 +1,210 @@
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>
27#include <qmap.h>
28
26#include <qpe/resource.h> 29#include <qpe/resource.h>
27#include <qpe/config.h> 30#include <qpe/config.h>
28 31
29#include <assert.h> 32#include <assert.h>
30 33
31struct SkinData 34struct SkinData
32{ 35{
33 typedef QMap<QString, QImage> ButtonMaskImageMap; 36 typedef QMap<QString, QImage> ButtonMaskImageMap;
34 37
35 QImage backgroundImage; 38 QImage backgroundImage;
36 QImage buttonUpImage; 39 QImage buttonUpImage;
37 QImage buttonDownImage; 40 QImage buttonDownImage;
38 QImage buttonMask; 41 QImage buttonMask;
39 ButtonMaskImageMap buttonMasks; 42 ButtonMaskImageMap buttonMasks;
40}; 43};
41 44
42class SkinCache : public Singleton<SkinCache> 45class SkinCache : public Singleton<SkinCache>
43{ 46{
44public: 47public:
45 SkinCache(); 48 SkinCache();
46 49
47 QImage loadImage( const QString &name ); 50 SkinData *lookupAndTake( const QString &skinPath, const QString &fileNameInfix );
48 51
49private: 52 void store( const QString &skinPath, const QString &fileNameInfix, SkinData *data );
50 typedef QDict<QImage> ImageCache;
51 53
52 ImageCache m_cache; 54private:
55 typedef QCache<SkinData> DataCache;
56 typedef QCache<QPixmap> BackgroundPixmapCache;
53 57
54 ThreadUtil::Mutex m_cacheGuard; 58 DataCache m_cache;
59 BackgroundPixmapCache m_backgroundPixmapCache;
55}; 60};
56 61
57Skin::Skin( const QString &name, const QString &fileNameInfix ) 62Skin::Skin( const QString &name, const QString &fileNameInfix )
58 : m_fileNameInfix( fileNameInfix ) 63 : m_fileNameInfix( fileNameInfix )
59{ 64{
60 init( name ); 65 init( name );
61} 66}
62 67
63Skin::Skin( const QString &fileNameInfix ) 68Skin::Skin( const QString &fileNameInfix )
64 : m_fileNameInfix( fileNameInfix ) 69 : m_fileNameInfix( fileNameInfix )
65{ 70{
66 init( defaultSkinName() ); 71 init( defaultSkinName() );
67} 72}
68 73
69Skin::~Skin() 74Skin::~Skin()
70{ 75{
71 delete d; 76 SkinCache::self().store( m_skinPath, m_fileNameInfix, d );
72} 77}
73 78
74void Skin::init( const QString &name ) 79void Skin::init( const QString &name )
75{ 80{
76 m_skinPath = "opieplayer2/skins/" + name; 81 m_skinPath = "opieplayer2/skins/" + name;
77 d = new SkinData; 82 d = SkinCache::self().lookupAndTake( m_skinPath, m_fileNameInfix );
78} 83}
79 84
80void Skin::preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) 85void Skin::preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount )
81{ 86{
82 backgroundImage(); 87 backgroundImage();
83 buttonUpImage(); 88 buttonUpImage();
84 buttonDownImage(); 89 buttonDownImage();
85 ( void )buttonMask( skinButtonInfo, buttonCount ); 90 ( void )buttonMask( skinButtonInfo, buttonCount );
86} 91}
87 92
88QImage Skin::backgroundImage() const 93QImage Skin::backgroundImage() const
89{ 94{
90 if ( d->backgroundImage.isNull() ) 95 if ( d->backgroundImage.isNull() )
91 d->backgroundImage = loadImage( QString( "%1/background" ).arg( m_skinPath ) ); 96 d->backgroundImage = loadImage( QString( "%1/background" ).arg( m_skinPath ) );
92 return d->backgroundImage; 97 return d->backgroundImage;
93} 98}
94 99
95QImage Skin::buttonUpImage() const 100QImage Skin::buttonUpImage() const
96{ 101{
97 if ( d->buttonUpImage.isNull() ) 102 if ( d->buttonUpImage.isNull() )
98 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 ) );
99 return d->buttonUpImage; 104 return d->buttonUpImage;
100} 105}
101 106
102QImage Skin::buttonDownImage() const 107QImage Skin::buttonDownImage() const
103{ 108{
104 if ( d->buttonDownImage.isNull() ) 109 if ( d->buttonDownImage.isNull() )
105 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 ) );
106 return d->buttonDownImage; 111 return d->buttonDownImage;
107} 112}
108 113
109QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const 114QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const
110{ 115{
111 if ( !d->buttonMask.isNull() ) 116 if ( !d->buttonMask.isNull() )
112 return d->buttonMask; 117 return d->buttonMask;
113 118
114 QSize buttonAreaSize = buttonUpImage().size(); 119 QSize buttonAreaSize = buttonUpImage().size();
115 120
116 d->buttonMask = QImage( buttonAreaSize, 8, 255 ); 121 d->buttonMask = QImage( buttonAreaSize, 8, 255 );
117 d->buttonMask.fill( 0 ); 122 d->buttonMask.fill( 0 );
118 123
119 for ( uint i = 0; i < buttonCount; ++i ) 124 for ( uint i = 0; i < buttonCount; ++i )
120 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) ); 125 addButtonToMask( skinButtonInfo[ i ].command + 1, buttonMaskImage( skinButtonInfo[ i ].fileName ) );
121 126
122 return d->buttonMask; 127 return d->buttonMask;
123} 128}
124 129
125void Skin::addButtonToMask( int tag, const QImage &maskImage ) const 130void Skin::addButtonToMask( int tag, const QImage &maskImage ) const
126{ 131{
127 if ( maskImage.isNull() ) 132 if ( maskImage.isNull() )
128 return; 133 return;
129 134
130 uchar **dest = d->buttonMask.jumpTable(); 135 uchar **dest = d->buttonMask.jumpTable();
131 for ( int y = 0; y < d->buttonMask.height(); y++ ) { 136 for ( int y = 0; y < d->buttonMask.height(); y++ ) {
132 uchar *line = dest[y]; 137 uchar *line = dest[y];
133 for ( int x = 0; x < d->buttonMask.width(); x++ ) 138 for ( int x = 0; x < d->buttonMask.width(); x++ )
134 if ( !qRed( maskImage.pixel( x, y ) ) ) 139 if ( !qRed( maskImage.pixel( x, y ) ) )
135 line[x] = tag; 140 line[x] = tag;
136 } 141 }
137} 142}
138 143
139QImage Skin::buttonMaskImage( const QString &fileName ) const 144QImage Skin::buttonMaskImage( const QString &fileName ) const
140{ 145{
141 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName ); 146 SkinData::ButtonMaskImageMap::Iterator it = d->buttonMasks.find( fileName );
142 if ( it == d->buttonMasks.end() ) { 147 if ( it == d->buttonMasks.end() ) {
143 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 );
144 QString path = prefix + fileName + ".png"; 149 QString path = prefix + fileName + ".png";
145 it = d->buttonMasks.insert( fileName, loadImage( path ) ); 150 it = d->buttonMasks.insert( fileName, loadImage( path ) );
146 } 151 }
147 return *it; 152 return *it;
148} 153}
149 154
150QString Skin::defaultSkinName() 155QString Skin::defaultSkinName()
151{ 156{
152 Config cfg( "OpiePlayer" ); 157 Config cfg( "OpiePlayer" );
153 cfg.setGroup( "Options" ); 158 cfg.setGroup( "Options" );
154 return cfg.readEntry( "Skin", "default" ); 159 return cfg.readEntry( "Skin", "default" );
155} 160}
156 161
157QImage Skin::loadImage( const QString &fileName ) 162QImage Skin::loadImage( const QString &fileName )
158{ 163{
159 return QImage( Resource::findPixmap( fileName ) ); 164 return QImage( Resource::findPixmap( fileName ) );
160} 165}
161 166
162SkinCache::SkinCache() 167SkinCache::SkinCache()
163{ 168{
164 m_cache.setAutoDelete( true );
165} 169}
166 170
167QImage SkinCache::loadImage( const QString &name ) 171SkinData *SkinCache::lookupAndTake( const QString &skinPath, const QString &fileNameInfix )
168{ 172{
169 ThreadUtil::AutoLock lock( m_cacheGuard ); 173 return new SkinData;
170 174}
171 QImage *image = m_cache.find( name );
172 if ( image ) {
173 qDebug( "cache hit for %s", name.ascii() );
174 return *image;
175 }
176 175
177 image = new QImage( Resource::findPixmap( name ) ); 176void SkinCache::store( const QString &skinPath, const QString &fileNameInfix, SkinData *data )
178 m_cache.insert( name, image ); 177{
179 return *image; 178 delete data;
180} 179}
181 180
182SkinLoader::SkinLoader() 181SkinLoader::SkinLoader()
183{ 182{
184} 183}
185 184
186void SkinLoader::schedule( const QString &skinName, const QString &fileNameInfix, 185void SkinLoader::schedule( const QString &skinName, const QString &fileNameInfix,
187 const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount ) 186 const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount )
188{ 187{
189 assert( isRunning() == false ); 188 assert( isRunning() == false );
190 189
191 pendingSkins << Info( skinName, fileNameInfix, skinButtonInfo, buttonCount ); 190 pendingSkins << Info( skinName, fileNameInfix, skinButtonInfo, buttonCount );
192} 191}
193 192
194void SkinLoader::run() 193void SkinLoader::run()
195{ 194{
196 qDebug( "SkinLoader::run()" ); 195 qDebug( "SkinLoader::run()" );
197 for ( InfoList::ConstIterator it = pendingSkins.begin(); it != pendingSkins.end(); ++it ) 196 for ( InfoList::ConstIterator it = pendingSkins.begin(); it != pendingSkins.end(); ++it )
198 load( *it ); 197 load( *it );
199 qDebug( "SkinLoader is done." ); 198 qDebug( "SkinLoader is done." );
200} 199}
201 200
202void SkinLoader::load( const Info &nfo ) 201void SkinLoader::load( const Info &nfo )
203{ 202{
204 qDebug( "preloading %s with infix %s", nfo.skinName.ascii(), nfo.fileNameInfix.ascii() ); 203 qDebug( "preloading %s with infix %s", nfo.skinName.ascii(), nfo.fileNameInfix.ascii() );
205 204
206 Skin skin( nfo.skinName, nfo.fileNameInfix ); 205 Skin skin( nfo.skinName, nfo.fileNameInfix );
207 skin.preload( nfo.skinButtonInfo, nfo.buttonCount ); 206 skin.preload( nfo.skinButtonInfo, nfo.buttonCount );
208} 207}
209 208
210/* vim: et sw=4 ts=4 209/* vim: et sw=4 ts=4
211 */ 210 */
diff --git a/noncore/multimedia/opieplayer2/skin.h b/noncore/multimedia/opieplayer2/skin.h
index e55832c..9180067 100644
--- a/noncore/multimedia/opieplayer2/skin.h
+++ b/noncore/multimedia/opieplayer2/skin.h
@@ -1,107 +1,105 @@
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 <qmap.h>
29#include <qdict.h>
30 28
31#include "mediawidget.h" 29#include "mediawidget.h"
32#include "threadutil.h" 30#include "threadutil.h"
33 31
34struct SkinData; 32struct SkinData;
35 33
36class Skin 34class Skin
37{ 35{
38public: 36public:
39 Skin( const QString &name, const QString &fileNameInfix ); 37 Skin( const QString &name, const QString &fileNameInfix );
40 Skin( const QString &fileNameInfix ); 38 Skin( const QString &fileNameInfix );
41 ~Skin(); 39 ~Skin();
42 40
43 void preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ); 41 void preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount );
44 42
45 QImage backgroundImage() const; 43 QImage backgroundImage() const;
46 QImage buttonUpImage() const; 44 QImage buttonUpImage() const;
47 QImage buttonDownImage() const; 45 QImage buttonDownImage() const;
48 46
49 QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const; 47 QImage buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const;
50 48
51 QImage buttonMaskImage( const QString &fileName ) const; 49 QImage buttonMaskImage( const QString &fileName ) const;
52 50
53 static QString defaultSkinName(); 51 static QString defaultSkinName();
54 52
55private: 53private:
56 void init( const QString &name ); 54 void init( const QString &name );
57 55
58 void addButtonToMask( int tag, const QImage &maskImage ) const; 56 void addButtonToMask( int tag, const QImage &maskImage ) const;
59 57
60 static QImage loadImage( const QString &fileName ); 58 static QImage loadImage( const QString &fileName );
61 59
62 QString m_fileNameInfix; 60 QString m_fileNameInfix;
63 QString m_skinPath; 61 QString m_skinPath;
64 62
65 SkinData *d; 63 SkinData *d;
66 64
67 Skin( const Skin & ); 65 Skin( const Skin & );
68 Skin &operator=( const Skin & ); 66 Skin &operator=( const Skin & );
69}; 67};
70 68
71class SkinLoader : public ThreadUtil::Thread 69class SkinLoader : public ThreadUtil::Thread
72{ 70{
73public: 71public:
74 SkinLoader(); 72 SkinLoader();
75 73
76 void schedule( const QString &skinName, const QString &fileNameInfix, 74 void schedule( const QString &skinName, const QString &fileNameInfix,
77 const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount ); 75 const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount );
78 76
79protected: 77protected:
80 virtual void run(); 78 virtual void run();
81 79
82private: 80private:
83 struct Info 81 struct Info
84 { 82 {
85 Info() : skinButtonInfo( 0 ), buttonCount( 0 ) {} 83 Info() : skinButtonInfo( 0 ), buttonCount( 0 ) {}
86 Info( const QString &_skinName, const QString &_fileNameInfix, 84 Info( const QString &_skinName, const QString &_fileNameInfix,
87 const MediaWidget::SkinButtonInfo *_skinButtonInfo, const uint _buttonCount ) 85 const MediaWidget::SkinButtonInfo *_skinButtonInfo, const uint _buttonCount )
88 : skinName( _skinName ), fileNameInfix( _fileNameInfix ), 86 : skinName( _skinName ), fileNameInfix( _fileNameInfix ),
89 skinButtonInfo( _skinButtonInfo ), buttonCount( _buttonCount ) 87 skinButtonInfo( _skinButtonInfo ), buttonCount( _buttonCount )
90 {} 88 {}
91 89
92 const QString skinName; 90 const QString skinName;
93 const QString fileNameInfix; 91 const QString fileNameInfix;
94 const MediaWidget::SkinButtonInfo *skinButtonInfo; 92 const MediaWidget::SkinButtonInfo *skinButtonInfo;
95 const uint buttonCount; 93 const uint buttonCount;
96 }; 94 };
97 typedef QValueList<Info> InfoList; 95 typedef QValueList<Info> InfoList;
98 96
99 void load( const Info &nfo ); 97 void load( const Info &nfo );
100 98
101 InfoList pendingSkins; 99 InfoList pendingSkins;
102 ThreadUtil::Mutex guard; 100 ThreadUtil::Mutex guard;
103}; 101};
104 102
105#endif // SKIN_H 103#endif // SKIN_H
106/* vim: et sw=4 ts=4 104/* vim: et sw=4 ts=4
107 */ 105 */