SVN_SILENT made messages (.desktop file)
[kdegames.git] / killbots / render.cpp
blob3fb7ef3550a54a41db1f538fc5cca3640bd9706d
1 /*
2 * Copyright 2007-2009 Parker Coates <parker.coates@gmail.com>
4 * This file is part of Killbots.
6 * Killbots is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * Killbots is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Killbots. If not, see <http://www.gnu.org/licenses/>.
20 #include "render.h"
22 #include <kgamesvgdocument.h>
23 #include <kgametheme.h>
25 #include <KDE/KDebug>
26 #include <KDE/KGlobal>
27 #include <KDE/KPixmapCache>
28 #include <KDE/KSvgRenderer>
30 #include <QtCore/QDateTime>
31 #include <QtCore/QFileInfo>
32 #include <QtCore/QHash>
33 #include <QtGui/QColor>
34 #include <QtGui/QCursor>
35 #include <QtGui/QPainter>
38 namespace Killbots
40 class RenderPrivate
42 public:
43 RenderPrivate()
44 : m_svgRenderer(),
45 m_pixmapCache("killbots-cache"),
46 m_cursors(),
47 m_hasBeenLoaded( false )
48 {};
50 KSvgRenderer m_svgRenderer;
51 KPixmapCache m_pixmapCache;
52 QHash<int,QCursor> m_cursors;
53 QColor m_textColor;
54 qreal m_aspectRatio;
55 bool m_hasBeenLoaded;
58 namespace Render
60 K_GLOBAL_STATIC( Killbots::RenderPrivate, rp )
65 bool Killbots::Render::loadTheme( const QString & fileName )
67 bool result = false;
69 KGameTheme newTheme;
70 if ( newTheme.load( fileName ) )
72 const QDateTime cacheTimeStamp = QDateTime::fromTime_t( rp->m_pixmapCache.timestamp() );
73 const QDateTime desktopFileTimeStamp = QFileInfo( newTheme.path() ).lastModified();
74 const QDateTime svgFileTimeStamp = QFileInfo( newTheme.graphics() ).lastModified();
76 // We check to see if the cache contains a key matching the path to the
77 // new theme file.
78 QPixmap nullPixmap;
79 const bool isNotInCache = !rp->m_pixmapCache.find( newTheme.path(), nullPixmap );
80 if ( isNotInCache )
81 kDebug() << "Theme is not already in cache.";
83 const bool desktopFileIsNewer = desktopFileTimeStamp > cacheTimeStamp;
84 if ( desktopFileIsNewer )
86 kDebug() << "Desktop file is newer than cache.";
87 kDebug() << "Cache timestamp is" << cacheTimeStamp.toString( Qt::ISODate );
88 kDebug() << "Desktop file timestamp is" << desktopFileTimeStamp.toString( Qt::ISODate );
91 const bool svgFileIsNewer = svgFileTimeStamp > cacheTimeStamp;
92 if ( svgFileIsNewer )
94 kDebug() << "SVG file is newer than cache.";
95 kDebug() << "Cache timestamp is" << cacheTimeStamp.toString( Qt::ISODate );
96 kDebug() << "SVG file timestamp is" << svgFileTimeStamp.toString( Qt::ISODate );
99 // Discard the cache if the loaded theme doesn't match the one already
100 // in the cache, or if either of the theme files have been updated
101 // since the cache was created.
102 const bool discardCache = isNotInCache || svgFileIsNewer || desktopFileIsNewer;
104 // Only bother actually loading the SVG if no SVG has been loaded
105 // yet or if the cache must be discarded.
106 if ( !rp->m_hasBeenLoaded || discardCache )
108 if ( discardCache )
110 kDebug() << "Discarding cache.";
111 rp->m_pixmapCache.discard();
112 rp->m_pixmapCache.setTimestamp( QDateTime::currentDateTime().toTime_t() );
114 // We store a null pixmap in the cache with the new theme's
115 // file path as the key. This allows us to keep track of the
116 // theme that is stored in the disk cache between runs.
117 rp->m_pixmapCache.insert( newTheme.path(), nullPixmap );
120 result = rp->m_hasBeenLoaded = rp->m_svgRenderer.load( newTheme.graphics() );
122 // Get the theme's aspect ratio from the .desktop file.
123 const QRectF tileRect = rp->m_svgRenderer.boundsOnElement("cell");
124 rp->m_aspectRatio = tileRect.width() / tileRect.height();
125 rp->m_aspectRatio = qBound( 0.3333, rp->m_aspectRatio, 3.0 );
127 // Get the theme's text color. Use the fill color of the "text" SVG element.
128 // If it exists doesn't exist or the fill isn't a valid color, default to black.
129 KGameSvgDocument svg;
130 svg.load( newTheme.graphics() );
131 if ( !svg.elementById("text").isNull() )
132 rp->m_textColor = QColor( svg.styleProperty("fill") );
133 if ( !rp->m_textColor.isValid() )
134 rp->m_textColor = Qt::black;
136 // Generate cursors.
137 for ( int i = 0; i <= 8; ++i )
139 const QPixmap pixmap = renderElement( QString("cursor%1").arg( i ), QSize( 42, 42 ) );
140 if ( !pixmap.isNull() )
141 rp->m_cursors.insert( i, QCursor( pixmap ) );
146 return result;
150 bool Killbots::Render::loadDefaultTheme()
152 return loadTheme("themes/default.desktop");
156 QPixmap Killbots::Render::renderElement( const QString & elementId, QSize size )
158 QPixmap result;
160 const QString key = elementId + QString::number( size.width() )
161 + 'x' + QString::number( size.height() );
163 if ( !rp->m_pixmapCache.find( key, result ) )
165 kDebug() << "Rendering \"" << elementId << "\" at " << size << " pixels.";
167 result = QPixmap( size );
168 result.fill( Qt::transparent );
170 QPainter p( &result );
171 rp->m_svgRenderer.render( &p, elementId );
172 p.end();
174 rp->m_pixmapCache.insert( key, result );
177 return result;
181 QCursor Killbots::Render::cursorFromAction( int direction )
183 return rp->m_cursors.value( direction, Qt::ArrowCursor );
187 QColor Killbots::Render::textColor()
189 return rp->m_textColor;
193 qreal Killbots::Render::aspectRatio()
195 return rp->m_aspectRatio;