Plasma::Svg debuts. it is an image centric wrapper around QSvgRenderer that takes care of things such as:
* caching rendered pixmaps * looking up the images from the Plasma::Theme * scheduling needed updates, e.g. when the plasma theme changes svn path=/trunk/KDE/kdebase/workspace/plasma/lib/; revision=640418
This commit is contained in:
parent
bfe37da902
commit
5cfabdc869
@ -7,6 +7,7 @@ set(plasma_LIB_SRCS
|
||||
applet.cpp
|
||||
interface.cpp
|
||||
runner.cpp
|
||||
svg.cpp
|
||||
theme.cpp
|
||||
dataengine.cpp
|
||||
datavisualization.cpp
|
||||
|
171
svg.cpp
Normal file
171
svg.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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 <QSvgRenderer>
|
||||
|
||||
#include <KDebug>
|
||||
|
||||
#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 )
|
||||
{
|
||||
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 ( 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 QSvgRenderer( path );
|
||||
}
|
||||
|
||||
p.resize( size );
|
||||
p.fill(Qt::transparent);
|
||||
QPainter renderPainter( &p );
|
||||
renderPainter.setWorldMatrix( matrix );
|
||||
renderer->render( &renderPainter, p.rect() );
|
||||
renderPainter.end();
|
||||
QPixmapCache::insert( id, p );
|
||||
}
|
||||
|
||||
//TODO: share renderers between Svg objects with identical themePath
|
||||
QSvgRenderer* renderer;
|
||||
QString themePath;
|
||||
QString path;
|
||||
QString id;
|
||||
QSize 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 QPoint& point )
|
||||
{
|
||||
QPixmap pix;
|
||||
d->findInCache( painter, pix );
|
||||
|
||||
QMatrix matrix = painter->worldMatrix();
|
||||
painter->setWorldMatrix( QMatrix() );
|
||||
painter->drawPixmap( point, pix );
|
||||
painter->setWorldMatrix( matrix );
|
||||
}
|
||||
|
||||
void Svg::paint( QPainter* painter, int x, int y )
|
||||
{
|
||||
paint( painter, QPoint( x, y ) );
|
||||
}
|
||||
|
||||
void Svg::paint( QPainter* painter, const QRect& rect )
|
||||
{
|
||||
QPixmap pix;
|
||||
d->findInCache( painter, pix );
|
||||
|
||||
QMatrix matrix = painter->worldMatrix();
|
||||
painter->setWorldMatrix( QMatrix() );
|
||||
painter->drawPixmap( rect, pix );
|
||||
painter->setWorldMatrix( matrix );
|
||||
}
|
||||
|
||||
void Svg::resize( int width, int height )
|
||||
{
|
||||
resize( QSize( width, height ) );
|
||||
}
|
||||
|
||||
void Svg::resize( const QSize& size )
|
||||
{
|
||||
d->size = size;
|
||||
}
|
||||
|
||||
void Svg::themeChanged()
|
||||
{
|
||||
d->removeFromCache();
|
||||
d->path.clear();
|
||||
delete d->renderer;
|
||||
d->renderer = 0;
|
||||
emit repaintNeeded();
|
||||
}
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#include "svg.moc"
|
||||
|
104
svg.h
Normal file
104
svg.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PLASMA_SVG_H
|
||||
#define PLASMA_SVG_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <kdemacros.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class KDE_EXPORT Svg : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs an SVG object that implicitly shares and caches rendering
|
||||
* As opposed to QSvgRenderer, which this class uses internally,
|
||||
* Plasma::Svg represents an image generated from an SVG. As such, it
|
||||
* has a related size and transform matrix (the latter being provided
|
||||
* by the painter used to paint the image).
|
||||
*
|
||||
* The size is initialized to be the SVG's native size.
|
||||
*
|
||||
* @arg imagePath the image to show, used to load the image from
|
||||
* Plasma::Theme
|
||||
* @arg parent options QObject to parent this to
|
||||
*/
|
||||
explicit Svg( const QString& imagePath, QObject* parent = 0 );
|
||||
~Svg();
|
||||
|
||||
/**
|
||||
* Paints the SVG represented by this object
|
||||
* @arg painter the QPainter to use
|
||||
* @arg point the position to start drawing; the entire svg will be
|
||||
* drawn starting at this point.
|
||||
*/
|
||||
void paint( QPainter* painter, const QPoint& point );
|
||||
|
||||
/**
|
||||
* Paints the SVG represented by this object
|
||||
* @arg painter the QPainter to use
|
||||
* @arg x the horizontal coordinate to start painting from
|
||||
* @arg y the vertical coordinate to start painting from
|
||||
*/
|
||||
void paint( QPainter* painter, int x, int y );
|
||||
|
||||
/**
|
||||
* Paints the SVG represented by this object
|
||||
* @arg painter the QPainter to use
|
||||
* @arg rect the rect to draw into; if small than the current size
|
||||
* of the
|
||||
* drawn starting at this point.
|
||||
*/
|
||||
void paint( QPainter* painter, const QRect& rect );
|
||||
|
||||
/**
|
||||
* Resizes the rendered image. Rendering will actually take place on
|
||||
* the next call to paint.
|
||||
* @arg width the new width
|
||||
* @arg height the new height
|
||||
**/
|
||||
void resize( int width, int height );
|
||||
|
||||
/**
|
||||
* Resizes the rendered image. Rendering will actually take place on
|
||||
* the next call to paint.
|
||||
* @arg size the new size of the image
|
||||
**/
|
||||
void resize( const QSize& size );
|
||||
|
||||
Q_SIGNALS:
|
||||
void repaintNeeded();
|
||||
|
||||
private Q_SLOTS:
|
||||
void themeChanged();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* d;
|
||||
};
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#endif // multiple inclusion guard
|
||||
|
28
theme.cpp
28
theme.cpp
@ -33,9 +33,22 @@ class Theme::Private
|
||||
{
|
||||
}
|
||||
|
||||
QString themeName;
|
||||
QString themeName;
|
||||
};
|
||||
|
||||
class ThemeSingleton
|
||||
{
|
||||
public:
|
||||
Theme self;
|
||||
};
|
||||
|
||||
K_GLOBAL_STATIC( ThemeSingleton, privateSelf )
|
||||
|
||||
Theme* Theme::self()
|
||||
{
|
||||
return &privateSelf->self;
|
||||
}
|
||||
|
||||
Theme::Theme(QObject* parent)
|
||||
: QObject(parent),
|
||||
d(new Private)
|
||||
@ -56,9 +69,16 @@ QString Theme::themeName() const
|
||||
|
||||
QString Theme::image( const QString& name ) const
|
||||
{
|
||||
return KStandardDirs::locate( "data", "desktoptheme/" +
|
||||
d->themeName +
|
||||
"/" + name + ".svg" );
|
||||
QString search = "desktoptheme/" + d->themeName + "/" + name + ".svg";
|
||||
QString path = KStandardDirs::locate( "data", search );
|
||||
|
||||
if ( path.isEmpty() ) {
|
||||
kDebug() << "Theme says: bad image path " << name
|
||||
<< "; looked in: " << search
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user