fewer pixmaps. same great taste.

svn path=/trunk/KDE/kdelibs/; revision=1178341
This commit is contained in:
Aaron J. Seigo 2010-09-22 19:35:47 +00:00
parent 938880140b
commit 9983bc7dc8
3 changed files with 130 additions and 94 deletions

View File

@ -31,7 +31,9 @@ namespace Plasma
{
PixmapTransition::PixmapTransition(QObject *parent)
: EasingAnimation(parent)
: EasingAnimation(parent),
m_cache(false),
m_dirty(false)
{
}
@ -67,6 +69,16 @@ void PixmapTransition::setTargetPixmap(const QPixmap &pixmap)
updateEffectiveTime(0);
}
void PixmapTransition::setUsesCache(bool cache)
{
m_cache = cache;
}
bool PixmapTransition::usesCache() const
{
return m_cache;
}
QPixmap PixmapTransition::targetPixmap() const
{
return m_targetPixmap;
@ -74,92 +86,88 @@ QPixmap PixmapTransition::targetPixmap() const
QPixmap PixmapTransition::currentPixmap() const
{
return m_currentPixmap;
if (m_cache && !m_dirty) {
return m_currentPixmap;
}
QPixmap currentPixmap;
qreal delta = currentTime() / qreal(duration());
if (!m_startPixmap.isNull() && !m_targetPixmap.isNull()) {
//kDebug() << "transitioning";
currentPixmap = Plasma::PaintUtils::transition(m_startPixmap, m_targetPixmap, delta);
} else if (m_startPixmap.isNull()) {
if (qFuzzyCompare(delta, qreal(1.0))) {
currentPixmap = alignedTargetPixmap();
return currentPixmap;
}
if (currentPixmap.isNull()) {
currentPixmap = QPixmap(m_pixmapSize);
}
currentPixmap.fill(QColor(0, 0, 0, (int)(((qreal)255)*delta)));
QPainter p(&currentPixmap);
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
//kDebug() << "painting" << m_targetPixmap.rect() << "into" << m_targetRect << "in size" << currentPixmap.size();
p.drawPixmap(m_targetRect, m_targetPixmap);
p.end();
} else if (m_targetPixmap.isNull()) {
currentPixmap = alignedStartPixmap();
if (qFuzzyCompare(delta, qreal(1.0))) {
return currentPixmap;
}
//kDebug() << "painting" << m_startPixmap.rect() << "into" << m_targetRect << "in size" << currentPixmap.size();
QPainter p(&currentPixmap);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(m_currentPixmap.rect(), QColor(0, 0, 0, (int)(254 - ((qreal)254)*delta)));
p.end();
}
if (m_cache) {
const_cast<PixmapTransition *>(this)->m_currentPixmap = currentPixmap;
}
return currentPixmap;
}
QPixmap PixmapTransition::alignedTargetPixmap() const
{
QPixmap pm(m_pixmapSize);
pm.fill(Qt::transparent);
QPainter p(&pm);
p.drawPixmap(m_targetRect, m_targetPixmap);
return pm;
}
QPixmap PixmapTransition::alignedStartPixmap() const
{
QPixmap pm(m_pixmapSize);
pm.fill(Qt::transparent);
QPainter p(&pm);
p.drawPixmap(m_startRect, m_startPixmap);
return pm;
}
void PixmapTransition::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
{
QGraphicsWidget *w = targetWidget();
if (!w) {
return;
if (oldState == Stopped && newState == Running) {
m_targetRect = m_targetPixmap.rect();
m_startRect = m_startPixmap.rect();
m_pixmapSize = m_startRect.size().expandedTo(m_targetRect.size());
QRect actualRect = QRect(QPoint(0,0), m_pixmapSize);
m_targetRect.moveCenter(actualRect.center());
m_startRect.moveCenter(actualRect.center());
} else if (QGraphicsWidget *w = targetWidget()) {
w->update();
}
if (!m_startPixmap.isNull() && !m_targetPixmap.isNull()) {
if (oldState == Stopped && newState == Running) {
Plasma::PaintUtils::centerPixmaps(m_startPixmap, m_targetPixmap);
m_currentPixmap = (direction() == Forward ? m_startPixmap : m_targetPixmap);
} else if (newState == Stopped) {
m_currentPixmap = (direction() == Forward ? m_targetPixmap : m_startPixmap);
}
} else if (m_startPixmap.isNull()) {
if (oldState == Stopped && newState == Running) {
if (direction() == Forward) {
m_currentPixmap = QPixmap(m_targetPixmap.size());
m_currentPixmap.fill(Qt::transparent);
} else {
m_currentPixmap = m_targetPixmap;
}
} else if (newState == Stopped) {
if (direction() == Forward) {
m_currentPixmap = m_targetPixmap;
} else {
m_currentPixmap = QPixmap(m_targetPixmap.size());
m_currentPixmap.fill(Qt::transparent);
}
}
} else if (m_targetPixmap.isNull()) {
if (oldState == Stopped && newState == Running) {
if (direction() == Forward) {
m_currentPixmap = m_targetPixmap;
} else {
m_currentPixmap = QPixmap(m_targetPixmap.size());
m_currentPixmap.fill(Qt::transparent);
}
} else if (newState == Stopped) {
if (direction() == Forward) {
m_currentPixmap = QPixmap(m_targetPixmap.size());
m_currentPixmap.fill(Qt::transparent);
} else {
m_currentPixmap = m_targetPixmap;
}
}
}
w->update();
m_dirty = true;
}
void PixmapTransition::updateEffectiveTime(int currentTime)
{
m_dirty = true;
QGraphicsWidget *w = targetWidget();
if (w) {
qreal delta = currentTime / qreal(duration());
if (!m_startPixmap.isNull() && !m_targetPixmap.isNull()) {
m_currentPixmap = Plasma::PaintUtils::transition(m_startPixmap, m_targetPixmap, delta);
} else if (m_startPixmap.isNull()) {
if (qFuzzyCompare(delta, qreal(1.0))) {
m_currentPixmap = m_targetPixmap;
return;
}
if (m_currentPixmap.isNull()) {
m_currentPixmap = QPixmap(m_targetPixmap.size());
}
m_currentPixmap.fill(QColor(0, 0, 0, (int)(((qreal)255)*delta)));
QPainter p(&m_currentPixmap);
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
p.drawPixmap(m_currentPixmap.rect(), m_targetPixmap, m_targetPixmap.rect());
p.end();
} else if (m_targetPixmap.isNull()) {
m_currentPixmap = m_startPixmap;
if (qFuzzyCompare(delta, qreal(1.0))) {
return;
}
QPainter p(&m_currentPixmap);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(m_currentPixmap.rect(), QColor(0, 0, 0, (int)(254 - ((qreal)254)*delta)));
p.end();
}
}
if (w) {
w->update();
}

View File

@ -42,6 +42,7 @@ class PixmapTransition : public EasingAnimation
Q_OBJECT
Q_PROPERTY(QPixmap startPixmap READ startPixmap WRITE setStartPixmap)
Q_PROPERTY(QPixmap targetPixmap READ targetPixmap WRITE setTargetPixmap)
Q_PROPERTY(QPixmap usesCache READ usesCache WRITE setUsesCache)
Q_PROPERTY(QPixmap currentPixmap READ currentPixmap)
public:
@ -50,7 +51,7 @@ public:
virtual ~PixmapTransition();
/**
* The first pixmap of the animation
* @return The first pixmap of the animation
*/
QPixmap startPixmap() const;
@ -70,18 +71,39 @@ public:
void setTargetPixmap(const QPixmap &);
/**
* Returns the current pixmap
* @return the current pixmap
*/
QPixmap currentPixmap() const;
/**
* Enable caching of the resulting pixmap, otherwise it will be regenerated on
* each call to currentPixmap; for elements which already have their own caching
* this is not a problem.
*/
void setUsesCache(bool cache);
/**
* @return whether or not caching is on
*/
bool usesCache() const;
protected:
void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
void updateEffectiveTime(int currentTime);
private:
QPixmap alignedTargetPixmap() const;
QPixmap alignedStartPixmap() const;
private:
QPixmap m_startPixmap;
QPixmap m_targetPixmap;
QPixmap m_currentPixmap;
QRect m_startRect;
QRect m_targetRect;
QSize m_pixmapSize;
bool m_cache;
bool m_dirty;
};
}

View File

@ -82,8 +82,7 @@ QPixmap shadowText(QString text, const QFont &font, QColor textColor, QColor sha
p.end();
//Draw blurred shadow
QImage img(textRect.size() + QSize(radius * 2, radius * 2),
QImage::Format_ARGB32_Premultiplied);
QImage img(textRect.size() + QSize(radius * 2, radius * 2), QImage::Format_ARGB32_Premultiplied);
img.fill(0);
p.begin(&img);
p.drawImage(QPoint(radius, radius), textPixmap.toImage());
@ -147,6 +146,7 @@ void centerPixmaps(QPixmap &from, QPixmap &to)
if (from.size() == to.size() && from.hasAlphaChannel() && to.hasAlphaChannel()) {
return;
}
QRect fromRect(from.rect());
QRect toRect(to.rect());
@ -181,16 +181,16 @@ QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
return from;
}
QPixmap startPixmap(from);
QPixmap targetPixmap(to);
if (from.size() != to.size() || !from.hasAlphaChannel() || !to.hasAlphaChannel()) {
centerPixmaps(startPixmap, targetPixmap);
}
QRect startRect(from.rect());
QRect targetRect(to.rect());
QSize pixmapSize = startRect.size().expandedTo(targetRect.size());
QRect toRect = QRect(QPoint(0,0), pixmapSize);
targetRect.moveCenter(toRect.center());
startRect.moveCenter(toRect.center());
QPixmap startPixmap(pixmapSize);
QPixmap targetPixmap(pixmapSize);
//paint to in the center of from
QRect toRect = to.rect();
QColor color;
color.setAlphaF(amount);
@ -203,15 +203,17 @@ QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
QPainter p;
p.begin(&targetPixmap);
p.drawPixmap(targetRect, from);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(targetPixmap.rect(), color);
p.fillRect(targetRect, color);
p.end();
p.begin(&startPixmap);
p.drawPixmap(startRect, from);
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
p.fillRect(startPixmap.rect(), color);
p.fillRect(startRect, color);
p.setCompositionMode(QPainter::CompositionMode_Plus);
p.drawPixmap(toRect.topLeft(), targetPixmap);
p.drawPixmap(targetRect, to);
p.end();
return startPixmap;
@ -266,18 +268,22 @@ QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount)
#endif
else {
// Fall back to using QRasterPaintEngine to do the transition.
QImage under = startPixmap.toImage();
QImage over = targetPixmap.toImage();
QImage under(pixmapSize, QImage::Format_ARGB32_Premultiplied);// = startPixmap.toImage();
under.fill(Qt::transparent);
QImage over(pixmapSize, QImage::Format_ARGB32_Premultiplied);// = targetPixmap.toImage();
over.fill(Qt::transparent);
QPainter p;
p.begin(&over);
p.drawPixmap(targetRect, to);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(over.rect(), color);
p.end();
p.begin(&under);
p.drawPixmap(startRect, from);
p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
p.fillRect(under.rect(), color);
p.fillRect(startRect, color);
p.setCompositionMode(QPainter::CompositionMode_Plus);
p.drawImage(toRect.topLeft(), over);
p.end();