Still have a couple of problems with hands other than second, and for the black thingy in the middle. Too tired right now, will check (and hopefully fix) them again tomorrow. Let's party though! The first (mostly) working plasmoid goes public! Yay! CCMAIL:panel-devel@kde.org svn path=/trunk/KDE/kdebase/workspace/plasma/lib/; revision=666767
198 lines
5.5 KiB
C++
198 lines
5.5 KiB
C++
/*
|
|
* Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 as
|
|
* published by the Free Software Foundation
|
|
*
|
|
* 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 Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <QMatrix>
|
|
#include <QPainter>
|
|
#include <QPixmapCache>
|
|
|
|
#include <KDebug>
|
|
#include <KSvgRenderer>
|
|
|
|
#include "svg.h"
|
|
#include "theme.h"
|
|
|
|
namespace Plasma
|
|
{
|
|
|
|
class Svg::Private
|
|
{
|
|
public:
|
|
Private( const QString& image )
|
|
: renderer( 0 ),
|
|
themePath( image )
|
|
{
|
|
}
|
|
|
|
~Private()
|
|
{
|
|
delete renderer;
|
|
}
|
|
|
|
void removeFromCache()
|
|
{
|
|
if ( id.isEmpty() ) {
|
|
return;
|
|
}
|
|
|
|
QPixmapCache::remove( id );
|
|
id.clear();
|
|
}
|
|
|
|
void findInCache( QPainter* painter, QPixmap& p, const QString& elementId )
|
|
{
|
|
if ( path.isNull() ) {
|
|
path = Plasma::Theme::self()->image( themePath );
|
|
|
|
if ( path.isNull() ) {
|
|
// bad theme path
|
|
return;
|
|
}
|
|
}
|
|
|
|
QMatrix matrix = painter->worldMatrix();
|
|
|
|
//TODO: if the id changes, should we remove it or just let QPixmapCache do that for us?
|
|
id = QString::fromLatin1( "%7_%1_%2_%3_%4_%5_%6" )
|
|
.arg( size.width() )
|
|
.arg( size.height() )
|
|
.arg( matrix.m11() )
|
|
.arg( matrix.m12() )
|
|
.arg( matrix.m21() )
|
|
.arg( matrix.m22() )
|
|
.arg( themePath );
|
|
|
|
if (!elementId.isEmpty()) {
|
|
id.append(elementId);
|
|
}
|
|
|
|
if ( QPixmapCache::find( id, p ) ) {
|
|
//kDebug() << "found cached version of " << id << endl;
|
|
return;
|
|
}/* else {
|
|
kDebug() << "didn't find cached version of " << id << ", so re-rendering" << endl;
|
|
}*/
|
|
|
|
// we have to re-render this puppy
|
|
if ( ! renderer ) {
|
|
//TODO: connect the renderer's repaintNeeded to the Plasma::Svg signal
|
|
// take into consideration for cache, e.g. don't cache if svg is animated
|
|
renderer = new KSvgRenderer( path );
|
|
}
|
|
|
|
p = QPixmap( size.toSize() );
|
|
p.fill(Qt::transparent);
|
|
QPainter renderPainter( &p );
|
|
renderPainter.setWorldMatrix( matrix );
|
|
|
|
if ( elementId.isEmpty() ) {
|
|
renderer->render( &renderPainter, p.rect() );
|
|
} else {
|
|
renderer->render( &renderPainter, elementId, p.rect() );
|
|
}
|
|
renderPainter.end();
|
|
QPixmapCache::insert( id, p );
|
|
}
|
|
|
|
//TODO: share renderers between Svg objects with identical themePath
|
|
KSvgRenderer* renderer;
|
|
QString themePath;
|
|
QString path;
|
|
QString id;
|
|
QSizeF size;
|
|
};
|
|
|
|
Svg::Svg( const QString& imagePath, QObject* parent )
|
|
: QObject( parent ),
|
|
d( new Private( imagePath ) )
|
|
{
|
|
connect( Plasma::Theme::self(), SIGNAL(changed()), this, SLOT(themeChanged()) );
|
|
}
|
|
|
|
Svg::~Svg()
|
|
{
|
|
|
|
}
|
|
|
|
void Svg::paint( QPainter* painter, const QPointF& point, const QString& elementID )
|
|
{
|
|
QPixmap pix;
|
|
d->findInCache( painter, pix, elementID );
|
|
|
|
/* QMatrix matrix = painter->worldMatrix();
|
|
painter->setWorldMatrix( QMatrix() );*/
|
|
painter->drawPixmap( point.toPoint(), pix );
|
|
// painter->setWorldMatrix( matrix );
|
|
}
|
|
|
|
void Svg::paint( QPainter* painter, int x, int y, const QString& elementID )
|
|
{
|
|
paint( painter, QPointF( x, y ), elementID );
|
|
}
|
|
|
|
void Svg::paint( QPainter* painter, const QRectF& rect, const QString& elementID )
|
|
{
|
|
// QPixmap pix(rect.width(), rect.height());
|
|
QPixmap pix;
|
|
QPainter *pain = new QPainter();
|
|
d->findInCache( pain, pix, elementID );
|
|
|
|
/* QMatrix matrix = painter->worldMatrix();
|
|
painter->setWorldMatrix( QMatrix() );*/
|
|
painter->drawPixmap( rect, pix, rect );
|
|
// painter->setWorldMatrix( matrix );
|
|
}
|
|
|
|
void Svg::resize( int width, int height )
|
|
{
|
|
resize( QSize( width, height ) );
|
|
}
|
|
|
|
void Svg::resize( const QSizeF& size )
|
|
{
|
|
d->size = size;
|
|
}
|
|
|
|
QSize Svg::elementSize(const QString& elementId)
|
|
{
|
|
if (!d->renderer) {
|
|
return QSize();
|
|
}
|
|
|
|
QSizeF elementSize = d->renderer->boundsOnElement(elementId).size();
|
|
QSizeF naturalSize = d->renderer->defaultSize();
|
|
qreal dx = d->size.width() / naturalSize.width();
|
|
qreal dy = d->size.height() / naturalSize.height();
|
|
elementSize.scale( elementSize.width() * dx, elementSize.height() * dy, Qt::IgnoreAspectRatio );
|
|
|
|
return elementSize.toSize();;
|
|
}
|
|
|
|
void Svg::themeChanged()
|
|
{
|
|
d->removeFromCache();
|
|
d->path.clear();
|
|
delete d->renderer;
|
|
d->renderer = 0;
|
|
emit repaintNeeded();
|
|
}
|
|
|
|
} // Plasma namespace
|
|
|
|
#include "svg.moc"
|
|
|