cache button icons in the handler. creation of 1000 decorations took 26s

before, now it's 10s... probably saves some memory, too.

svn path=/trunk/kdebase/kwin/; revision=397810
This commit is contained in:
Sandro Giessl 2005-03-15 14:07:37 +00:00
parent e7ad67c64b
commit 5cb8a385e9
5 changed files with 168 additions and 128 deletions

View file

@ -21,11 +21,27 @@
*/
#include <qpainter.h>
#include <qimage.h>
#include <kconfig.h>
#include <kpixmap.h>
#include <kpixmapeffect.h>
#include "xpm/close.xpm"
#include "xpm/minimize.xpm"
#include "xpm/maximize.xpm"
#include "xpm/restore.xpm"
#include "xpm/help.xpm"
#include "xpm/sticky.xpm"
#include "xpm/unsticky.xpm"
#include "xpm/shade.xpm"
#include "xpm/unshade.xpm"
#include "xpm/keepabove.xpm"
#include "xpm/notkeepabove.xpm"
#include "xpm/keepbelow.xpm"
#include "xpm/notkeepbelow.xpm"
#include "xpm/empty.xpm"
#include "misc.h"
#include "plastik.h"
#include "plastik.moc"
@ -36,16 +52,17 @@ namespace KWinPlastik
PlastikHandler::PlastikHandler()
{
memset(m_pixmaps, 0, sizeof(QPixmap *) * NumPixmaps); // set elements to 0
memset(m_pixmaps, 0, sizeof(QPixmap*)*(NumPixmaps+NumButtonPixmaps*2)*2*2); // set elements to 0
reset(0);
}
PlastikHandler::~PlastikHandler()
{
for (int n=0; n<NumPixmaps; n++) {
if (m_pixmaps[n]) delete m_pixmaps[n];
}
for (int t=0; t < 2; ++t)
for (int a=0; a < 2; ++a)
for (int i=0; i < NumPixmaps+NumButtonPixmaps*2; ++i)
delete m_pixmaps[t][a][i];
}
bool PlastikHandler::reset(unsigned long changed)
@ -86,10 +103,14 @@ bool PlastikHandler::reset(unsigned long changed)
readConfig();
// pixmaps probably need to be updated, so delete the cache.
for (int n=0; n<NumPixmaps; n++) {
if (m_pixmaps[n]) {
delete m_pixmaps[n];
m_pixmaps[n] = 0;
for (int t=0; t < 2; ++t) {
for (int a=0; a < 2; ++a) {
for (int i=0; i < NumPixmaps+NumButtonPixmaps*2; i++) {
if (m_pixmaps[t][a][i]) {
delete m_pixmaps[t][a][i];
m_pixmaps[t][a][i] = 0;
}
}
}
}
@ -199,24 +220,16 @@ QColor PlastikHandler::getColor(KWinPlastik::ColorType type, const bool active)
}
}
const QPixmap &PlastikHandler::pixmap(Pixmaps type) {
if (m_pixmaps[type])
return *m_pixmaps[type];
const QPixmap &PlastikHandler::pixmap(Pixmaps type, bool active, bool toolWindow)
{
if (m_pixmaps[toolWindow][active][type])
return *m_pixmaps[toolWindow][active][type];
switch (type) {
case aTitleBarTileTop:
case iTitleBarTileTop:
case atTitleBarTileTop:
case itTitleBarTileTop:
case TitleBarTileTop:
{
int h = 4-2; // TODO: don't hardcode the height...
bool active = false;
if (type == aTitleBarTileTop || type == atTitleBarTileTop) {
active = true;
}
KPixmap tempPixmap;
tempPixmap.resize(1, h);
KPixmapEffect::gradient(tempPixmap,
@ -228,26 +241,14 @@ const QPixmap &PlastikHandler::pixmap(Pixmaps type) {
painter.drawPixmap(0, 0, tempPixmap);
painter.end();
m_pixmaps[type] = pixmap;
m_pixmaps[toolWindow][active][type] = pixmap;
return *pixmap;
break;
}
case aTitleBarTile:
case iTitleBarTile:
case atTitleBarTile:
case itTitleBarTile:
case TitleBarTile:
{
bool active = false;
if (type == aTitleBarTile || type == atTitleBarTile) {
active = true;
}
bool toolWindow = false;
if (type == atTitleBarTile || type == itTitleBarTile) {
toolWindow = true;
}
int h = toolWindow ? m_titleHeightTool : m_titleHeight;
KPixmap tempPixmap;
@ -261,7 +262,7 @@ const QPixmap &PlastikHandler::pixmap(Pixmaps type) {
painter.drawPixmap(0, 0, tempPixmap);
painter.end();
m_pixmaps[type] = pixmap;
m_pixmaps[toolWindow][active][type] = pixmap;
return *pixmap;
break;
@ -270,6 +271,88 @@ const QPixmap &PlastikHandler::pixmap(Pixmaps type) {
}
}
const QPixmap &PlastikHandler::buttonPixmap(ButtonPixmaps type, const QSize &size, bool pressed, bool active, bool toolWindow)
{
int typeIndex = NumPixmaps+(pressed?type*2:type);
// btn icon size...
int reduceW = 0, reduceH = 0;
if(size.width()>12) {
reduceW = static_cast<int>(2*(size.width()/3.5) );
}
else
reduceW = 4;
if(size.height()>12)
reduceH = static_cast<int>(2*(size.height()/3.5) );
else
reduceH = 4;
int w = size.width() - reduceW;
int h = size.height() - reduceH;
if (m_pixmaps[toolWindow][active][typeIndex] && m_pixmaps[toolWindow][active][typeIndex]->size()==QSize(w,h) )
return *m_pixmaps[toolWindow][active][typeIndex];
// no matching pixmap found, create a new one...
delete m_pixmaps[toolWindow][active][typeIndex];
m_pixmaps[toolWindow][active][typeIndex] = 0;
QColor iconColor = alphaBlendColors(getColor(TitleGradientTo, active), pressed ? Qt::white : Qt::black, 50);
QImage img;
switch (type) {
case BtnHelp:
img = QImage(help_xpm);
break;
case BtnMax:
img = QImage(maximize_xpm);
break;
case BtnMaxRestore:
img = QImage(restore_xpm);
break;
case BtnMin:
img = QImage(minimize_xpm);
break;
case BtnClose:
img = QImage(close_xpm);
break;
case BtnOnAllDesktops:
img = QImage(sticky_xpm);
break;
case BtnNotOnAllDesktops:
img = QImage(unsticky_xpm);
break;
case BtnAbove:
img = QImage(keepabove_xpm);
break;
case BtnNotAbove:
img = QImage(notkeepabove_xpm);
break;
case BtnBelow:
img = QImage(keepbelow_xpm);
case BtnNotBelow:
img = QImage(notkeepbelow_xpm);
break;
case BtnShade:
img = QImage(shade_xpm);
break;
case BtnShadeRestore:
img = QImage(unshade_xpm);
break;
default:
img = QImage(empty_xpm);
break;
}
QPixmap *pixmap = new QPixmap(recolorImage(&img, iconColor).smoothScale(w,h) );
m_pixmaps[toolWindow][active][typeIndex] = pixmap;
return *pixmap;
}
QValueList< PlastikHandler::BorderSize >
PlastikHandler::borderSizes() const
{

View file

@ -23,7 +23,6 @@
#ifndef PLASTIK_H
#define PLASTIK_H
#include <qintcache.h>
#include <qfont.h>
#include <kdecoration.h>
@ -45,17 +44,28 @@ enum ColorType {
};
enum Pixmaps {
aTitleBarTileTop=0, // normal windows
iTitleBarTileTop,
aTitleBarTile,
iTitleBarTile,
atTitleBarTileTop, // tool windows
itTitleBarTileTop,
atTitleBarTile,
itTitleBarTile,
TitleBarTileTop=0,
TitleBarTile,
NumPixmaps
};
enum ButtonPixmaps {
BtnHelp = 0,
BtnMax,
BtnMaxRestore,
BtnMin,
BtnClose,
BtnOnAllDesktops,
BtnNotOnAllDesktops,
BtnAbove,
BtnNotAbove,
BtnBelow,
BtnNotBelow,
BtnShade,
BtnShadeRestore,
NumButtonPixmaps
};
class PlastikHandler: public QObject, public KDecorationFactory
{
Q_OBJECT
@ -67,7 +77,8 @@ public:
virtual KDecoration* createDecoration( KDecorationBridge* );
virtual bool supports( Ability ability );
const QPixmap &pixmap(Pixmaps pixmap);
const QPixmap &pixmap(Pixmaps type, bool active, bool toolWindow);
const QPixmap &buttonPixmap(ButtonPixmaps type, const QSize &size, bool pressed, bool active, bool toolWindow);
int titleHeight() { return m_titleHeight; }
int titleHeightTool() { return m_titleHeightTool; }
@ -98,7 +109,7 @@ private:
Qt::AlignmentFlags m_titleAlign;
// pixmap cache
QPixmap *m_pixmaps[NumPixmaps];
QPixmap *m_pixmaps[2][2][NumPixmaps+NumButtonPixmaps*2]; // button pixmaps have normal+pressed state...
};
PlastikHandler* Handler();

View file

@ -32,21 +32,6 @@
#include <qtooltip.h>
#include <qtimer.h>
#include "xpm/close.xpm"
#include "xpm/minimize.xpm"
#include "xpm/maximize.xpm"
#include "xpm/restore.xpm"
#include "xpm/help.xpm"
#include "xpm/sticky.xpm"
#include "xpm/unsticky.xpm"
#include "xpm/shade.xpm"
#include "xpm/unshade.xpm"
#include "xpm/keepabove.xpm"
#include "xpm/notkeepabove.xpm"
#include "xpm/keepbelow.xpm"
#include "xpm/notkeepbelow.xpm"
#include "xpm/empty.xpm"
#include "plastikbutton.h"
#include "plastikbutton.moc"
#include "plastikclient.h"
@ -62,8 +47,7 @@ static const uint ANIMATIONSTEPS = 4;
PlastikButton::PlastikButton(ButtonType type, PlastikClient *parent, const char *name)
: KCommonDecorationButton(type, parent, name),
m_client(parent),
m_aDecoLight(QImage() ), m_iDecoLight(QImage() ),
m_aDecoDark(QImage() ), m_iDecoDark(QImage() ),
m_pixmapType(BtnClose),
hover(false)
{
setBackgroundMode(NoBackground);
@ -82,82 +66,56 @@ PlastikButton::~PlastikButton()
void PlastikButton::reset(unsigned long changed)
{
if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) {
QColor aDecoFgDark = alphaBlendColors(Handler()->getColor(TitleGradientTo, true),
Qt::black, 50);
QColor aDecoFgLight = alphaBlendColors(Handler()->getColor(TitleGradientTo, true),
Qt::white, 50);
QColor iDecoFgDark = alphaBlendColors(Handler()->getColor(TitleGradientTo, false),
Qt::black, 50);
QColor iDecoFgLight = alphaBlendColors(Handler()->getColor(TitleGradientTo, false),
Qt::white, 50);
int reduceW = 0, reduceH = 0;
if(width()>12) {
reduceW = static_cast<int>(2*(width()/3.5) );
}
else
reduceW = 4;
if(height()>12)
reduceH = static_cast<int>(2*(height()/3.5) );
else
reduceH = 4;
QImage img;
switch (type() ) {
case CloseButton:
img = QImage(close_xpm);
m_pixmapType = BtnClose;
break;
case HelpButton:
img = QImage(help_xpm);
m_pixmapType = BtnHelp;
break;
case MinButton:
img = QImage(minimize_xpm);
m_pixmapType = BtnMin;
break;
case MaxButton:
if (isOn()) {
img = QImage(restore_xpm);
m_pixmapType = BtnMaxRestore;
} else {
img = QImage(maximize_xpm);
m_pixmapType = BtnMax;
}
break;
case OnAllDesktopsButton:
if (isOn()) {
img = QImage(unsticky_xpm);
m_pixmapType = BtnNotOnAllDesktops;
} else {
img = QImage(sticky_xpm);
m_pixmapType = BtnOnAllDesktops;
}
break;
case ShadeButton:
if (isOn()) {
img = QImage(unshade_xpm);
m_pixmapType = BtnShadeRestore;
} else {
img = QImage(shade_xpm);
m_pixmapType = BtnShade;
}
break;
case AboveButton:
if (isOn()) {
img = QImage(notkeepabove_xpm);
m_pixmapType = BtnNotAbove;
} else {
img = QImage(keepabove_xpm);
m_pixmapType = BtnAbove;
}
break;
case BelowButton:
if (isOn()) {
img = QImage(notkeepbelow_xpm);
m_pixmapType = BtnNotBelow;
} else {
img = QImage(keepbelow_xpm);
m_pixmapType = BtnBelow;
}
break;
default:
img = QImage(empty_xpm);
m_pixmapType = NumButtonPixmaps; // invalid...
break;
}
m_aDecoDark = recolorImage(&img, aDecoFgDark).smoothScale(width()-reduceW, height()-reduceH);
m_iDecoDark = recolorImage(&img, iDecoFgDark).smoothScale(width()-reduceW, height()-reduceH);
m_aDecoLight = recolorImage(&img, aDecoFgLight).smoothScale(width()-reduceW, height()-reduceH);
m_iDecoLight = recolorImage(&img, iDecoFgLight).smoothScale(width()-reduceW, height()-reduceH);
this->update();
}
}
@ -195,7 +153,6 @@ void PlastikButton::enterEvent(QEvent *e)
hover = true;
animate();
// repaint(false);
}
void PlastikButton::leaveEvent(QEvent *e)
@ -204,7 +161,6 @@ void PlastikButton::leaveEvent(QEvent *e)
hover = false;
animate();
// repaint(false);
}
void PlastikButton::drawButton(QPainter *painter)
@ -309,18 +265,13 @@ void PlastikButton::drawButton(QPainter *painter)
else
{
int dX,dY;
QImage *deco = 0;
if (isDown() ) {
deco = active?&m_aDecoLight:&m_iDecoLight;
} else {
deco = active?&m_aDecoDark:&m_iDecoDark;
}
dX = r.x()+(r.width()-deco->width())/2;
dY = r.y()+(r.height()-deco->height())/2;
const QPixmap &icon = Handler()->buttonPixmap(m_pixmapType, size(), isDown(), active, decoration()->isToolWindow() );
dX = r.x()+(r.width()-icon.width())/2;
dY = r.y()+(r.height()-icon.height())/2;
if (isDown() ) {
dY++;
}
bP.drawImage(dX, dY, *deco);
bP.drawPixmap(dX, dY, icon);
}
bP.end();

View file

@ -55,7 +55,7 @@ private:
private:
PlastikClient *m_client;
QImage m_aDecoLight,m_iDecoLight,m_aDecoDark,m_iDecoDark;
ButtonPixmaps m_pixmapType;
bool hover;
QTimer *animTmr;

View file

@ -43,11 +43,6 @@
namespace KWinPlastik
{
#define TITLEBARTILETOP (isToolWindow()? (isActive()?atTitleBarTileTop : itTitleBarTileTop) \
: (isActive()?aTitleBarTileTop : iTitleBarTileTop))
#define TITLEBARTILE (isToolWindow()? (isActive()?KWinPlastik::atTitleBarTile : KWinPlastik::itTitleBarTile) \
: (isActive()?KWinPlastik::aTitleBarTile : KWinPlastik::iTitleBarTile))
PlastikClient::PlastikClient(KDecorationBridge* bridge, KDecorationFactory* factory)
: KCommonDecoration (bridge, factory),
aCaptionBuffer(0), iCaptionBuffer(0),
@ -256,6 +251,7 @@ void PlastikClient::paintEvent(QPaintEvent *e)
update_captionBuffer();
bool active = isActive();
bool toolWindow = isToolWindow();
QPainter painter(widget() );
@ -356,7 +352,7 @@ void PlastikClient::paintEvent(QPaintEvent *e)
tempRect.setRect(r_x+2, r_y+2, r_w-2*2, titleEdgeTop-2 );
if (tempRect.isValid() && region.contains(tempRect) ) {
painter.drawTiledPixmap(tempRect, handler->pixmap(TITLEBARTILETOP) );
painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTileTop, active, toolWindow) );
}
// outside the region normally masked by doShape
@ -403,14 +399,14 @@ void PlastikClient::paintEvent(QPaintEvent *e)
tempRect.setRect(r_x+titleMarginLeft, m_captionRect.top(),
m_captionRect.left() - (r_x+titleMarginLeft), m_captionRect.height() );
if (tempRect.isValid() && region.contains(tempRect) ) {
painter.drawTiledPixmap(tempRect, handler->pixmap(TITLEBARTILE) );
painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) );
}
// right to the title
tempRect.setRect(m_captionRect.right()+1, m_captionRect.top(),
(r_x2-titleMarginRight) - m_captionRect.right(), m_captionRect.height() );
if (tempRect.isValid() && region.contains(tempRect) ) {
painter.drawTiledPixmap(tempRect, handler->pixmap(TITLEBARTILE) );
painter.drawTiledPixmap(tempRect, handler->pixmap(TitleBarTile, active, toolWindow) );
}
}
@ -599,8 +595,7 @@ void PlastikClient::reset( unsigned long changed )
const QPixmap &PlastikClient::getTitleBarTile(bool active) const
{
return Handler()->pixmap(isToolWindow() ?
(active? atTitleBarTile : itTitleBarTile) : (active? aTitleBarTile : iTitleBarTile) );
return Handler()->pixmap(TitleBarTile, active, isToolWindow() );
}
void PlastikClient::update_captionBuffer()
@ -641,7 +636,7 @@ void PlastikClient::update_captionBuffer()
aCaptionBuffer->resize(captionWidth+4, th ); // 4 px shadow
painter.begin(aCaptionBuffer);
painter.drawTiledPixmap(aCaptionBuffer->rect(),
Handler()->pixmap(isToolWindow()?KWinPlastik::atTitleBarTile:KWinPlastik::aTitleBarTile) );
Handler()->pixmap(TitleBarTile, true, isToolWindow()) );
if(Handler()->titleShadow())
{
QColor shadowColor;
@ -662,7 +657,7 @@ void PlastikClient::update_captionBuffer()
iCaptionBuffer->resize(captionWidth+4, th );
painter.begin(iCaptionBuffer);
painter.drawTiledPixmap(iCaptionBuffer->rect(),
Handler()->pixmap(isToolWindow()?KWinPlastik::itTitleBarTile:KWinPlastik::iTitleBarTile) );
Handler()->pixmap(TitleBarTile, false, isToolWindow()) );
if(Handler()->titleShadow())
{
painter.drawImage(1, 1, shadow);