kwin/clients/kwmtheme/kwmthemeclient.cpp
Luboš Luňák fc23037d3a Add missing license headers. Some files mentioned only copyright
but not explicitly the license, there I assumed they're licensed
under the same license as the rest of KWin, which is GPLv2+ as of now.
CC-ing all people mentioned as copyright holders just in case
somebody wants some other license, e.g. the X11 license KWin used
to be licensed under until KDE3.2. Please check with other relevant
contributors and change accordingly in such case.
CCMAIL: Karol Szwed <gallium@kde.org>
CCMAIL: Luciano Montanaro <mikelima@cirulla.net>
CCMAIL: Sandro Giessl <sandro@giessl.com>
CCMAIL: Daniel M. Duley <mosfet@kde.org>
CCMAIL: Chris Lee <clee@kde.org>


svn path=/trunk/KDE/kdebase/workspace/; revision=742990
2007-11-29 15:32:50 +00:00

951 lines
27 KiB
C++

/********************************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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 General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "kwmthemeclient.h"
#include <kconfig.h>
#include <kglobal.h>
#include <QLayout>
#include <qdrawutil.h>
#include <QPainter>
#include <kpixmapeffect.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include <klocale.h>
#include <QBitmap>
#include <QStyle>
#include <QLabel>
namespace KWMTheme {
/* static QPixmap stretchPixmap(QPixmap& src, bool stretchVert){
QPixmap dest;
QBitmap *srcMask, *destMask;
int w, h, w2, h2;
QPainter p;
if (src.isNull()) return src;
w = src.width();
h = src.height();
if (stretchVert){
w2 = w;
for (h2=h; h2<100; h2=h2<<1)
;
}
else{
h2 = h;
for (w2=w; w2<100; w2=w2<<1)
;
}
if (w2==w && h2==h) return src;
dest = src;
dest.resize(w2, h2);
p.begin(&dest);
p.drawTiledPixmap(0, 0, w2, h2, src);
p.end();
srcMask = (QBitmap*)src.mask();
if (srcMask){
destMask = (QBitmap*)dest.mask();
p.begin(destMask);
p.drawTiledPixmap(0, 0, w2, h2, *srcMask);
p.end();
}
return dest;
} */
inline const KDecorationOptions* options() { return KDecoration::options(); }
enum FramePixmap{FrameTop=0, FrameBottom, FrameLeft, FrameRight, FrameTopLeft,
FrameTopRight, FrameBottomLeft, FrameBottomRight};
static QPixmap *framePixmaps[8];
static QPixmap *menuPix, *iconifyPix, *closePix, *maxPix, *minmaxPix,
*pinupPix, *pindownPix;
static QPixmap *aTitlePix = 0;
static QPixmap *iTitlePix = 0;
static KPixmapEffect::GradientType grType;
static int maxExtent, titleAlign;
static bool titleGradient = true;
static bool pixmaps_created = false;
static bool titleSunken = false;
static bool titleTransparent;
static void create_pixmaps()
{
const char *keys[] = {"wm_top", "wm_bottom", "wm_left", "wm_right",
"wm_topleft", "wm_topright", "wm_bottomleft", "wm_bottomright"};
if(pixmaps_created)
return;
pixmaps_created = true;
KSharedConfig::Ptr _config = KGlobal::config();
KConfigGroup config(_config, "General");
QString tmpStr;
for(int i=0; i < 8; ++i)
{
framePixmaps[i] = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry(keys[i], " ")));
if(framePixmaps[i]->isNull())
kWarning() << "Unable to load frame pixmap for " << keys[i] ;
}
/*
*framePixmaps[FrameTop] = stretchPixmap(*framePixmaps[FrameTop], false);
*framePixmaps[FrameBottom] = stretchPixmap(*framePixmaps[FrameBottom], false);
*framePixmaps[FrameLeft] = stretchPixmap(*framePixmaps[FrameLeft], true);
*framePixmaps[FrameRight] = stretchPixmap(*framePixmaps[FrameRight], true);
*/
maxExtent = framePixmaps[FrameTop]->height();
if(framePixmaps[FrameBottom]->height() > maxExtent)
maxExtent = framePixmaps[FrameBottom]->height();
if(framePixmaps[FrameLeft]->width() > maxExtent)
maxExtent = framePixmaps[FrameLeft]->width();
if(framePixmaps[FrameRight]->width() > maxExtent)
maxExtent = framePixmaps[FrameRight]->width();
maxExtent++;
menuPix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("menu", " ")));
iconifyPix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("iconify", " ")));
maxPix = new QPixmap(locate("appdata",
"pics/"+config.readEntry("maximize", " ")));
minmaxPix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("maximizedown", " ")));
closePix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("close", " ")));
pinupPix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("pinup", " ")));
pindownPix = new QPixmap(locate("data",
"kwin/pics/"+config.readEntry("pindown", " ")));
if(menuPix->isNull())
menuPix->load(locate("data", "kwin/pics/menu.png"));
if(iconifyPix->isNull())
iconifyPix->load(locate("data", "kwin/pics/iconify.png"));
if(maxPix->isNull())
maxPix->load(locate("data", "kwin/pics/maximize.png"));
if(minmaxPix->isNull())
minmaxPix->load(locate("data", "kwin/pics/maximizedown.png"));
if(closePix->isNull())
closePix->load(locate("data", "kwin/pics/close.png"));
if(pinupPix->isNull())
pinupPix->load(locate("data", "kwin/pics/pinup.png"));
if(pindownPix->isNull())
pindownPix->load(locate("data", "kwin/pics/pindown.png"));
tmpStr = config.readEntry("TitleAlignment");
if(tmpStr == "right")
titleAlign = Qt::AlignRight | Qt::AlignVCenter;
else if(tmpStr == "middle")
titleAlign = Qt::AlignCenter;
else
titleAlign = Qt::AlignLeft | Qt::AlignVCenter;
titleSunken = config.readEntry("TitleFrameShaded", true );
// titleSunken = true; // is this fixed?
titleTransparent = config.readEntry("PixmapUnderTitleText", true);
tmpStr = config.readEntry("TitlebarLook");
if(tmpStr == "shadedVertical"){
aTitlePix = new QPixmap;
aTitlePix->resize(32, 20);
KPixmapEffect::gradient(*aTitlePix,
options()->color(KDecorationOptions::ColorTitleBar, true),
options()->color(KDecorationOptions::ColorTitleBlend, true),
KPixmapEffect::VerticalGradient);
iTitlePix = new QPixmap;
iTitlePix->resize(32, 20);
KPixmapEffect::gradient(*iTitlePix,
options()->color(KDecorationOptions::ColorTitleBar, false),
options()->color(KDecorationOptions::ColorTitleBlend, false),
KPixmapEffect::VerticalGradient);
titleGradient = false; // we can just tile this
}
else if(tmpStr == "shadedHorizontal")
grType = KPixmapEffect::HorizontalGradient;
else if(tmpStr == "shadedDiagonal")
grType = KPixmapEffect::DiagonalGradient;
else if(tmpStr == "shadedCrossDiagonal")
grType = KPixmapEffect::CrossDiagonalGradient;
else if(tmpStr == "shadedPyramid")
grType = KPixmapEffect::PyramidGradient;
else if(tmpStr == "shadedRectangle")
grType = KPixmapEffect::RectangleGradient;
else if(tmpStr == "shadedPipeCross")
grType = KPixmapEffect::PipeCrossGradient;
else if(tmpStr == "shadedElliptic")
grType = KPixmapEffect::EllipticGradient;
else{
titleGradient = false;
tmpStr = config.readEntry("TitlebarPixmapActive", "");
if(!tmpStr.isEmpty()){
aTitlePix = new QPixmap;
aTitlePix->load(locate("data", "kwin/pics/" + tmpStr));
}
else
aTitlePix = NULL;
tmpStr = config.readEntry("TitlebarPixmapInactive", "");
if(!tmpStr.isEmpty()){
iTitlePix = new QPixmap;
iTitlePix->load(locate("data", "kwin/pics/" + tmpStr));
}
else
iTitlePix = NULL;
}
}
static void delete_pixmaps()
{
for(int i=0; i < 8; ++i)
delete framePixmaps[i];
delete menuPix;
delete iconifyPix;
delete closePix;
delete maxPix;
delete minmaxPix;
delete pinupPix;
delete pindownPix;
delete aTitlePix;
aTitlePix = 0;
delete iTitlePix;
iTitlePix = 0;
titleGradient = true;
pixmaps_created = false;
titleSunken = false;
}
void MyButton::drawButtonLabel(QPainter *p)
{
if(pixmap()){
// If we have a theme who's button covers the entire width or
// entire height, we shift down/right by 1 pixel so we have
// some visual notification of button presses. i.e. for MGBriezh
int offset = (isDown() && ((pixmap()->width() >= width()) ||
(pixmap()->height() >= height()))) ? 1 : 0;
style().drawItem(p, QRect( offset, offset, width(), height() ),
AlignCenter, colorGroup(),
true, pixmap(), QString());
}
}
KWMThemeClient::KWMThemeClient( KDecorationBridge* b, KDecorationFactory* f )
: KDecoration( b, f )
{
}
void KWMThemeClient::init()
{
createMainWidget( WResizeNoErase | WStaticContents );
widget()->installEventFilter( this );
stickyBtn = maxBtn = mnuBtn = 0;
layout = new QGridLayout(widget());
layout->addColSpacing(0, maxExtent);
layout->addColSpacing(2, maxExtent);
layout->addRowSpacing(0, maxExtent);
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed,
QSizePolicy::Expanding));
if( isPreview())
layout->addWidget( new QLabel( i18n( "<center><b>KWMTheme</b></center>" ), widget()), 2, 1);
else
layout->addItem( new QSpacerItem( 0, 0 ), 2, 1);
// Without the next line, shading flickers
layout->addItem( new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding) );
layout->addRowSpacing(3, maxExtent);
layout->setRowStretch(2, 10);
layout->setColumnStretch(1, 10);
QBoxLayout* hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
layout->addLayout( hb, 1, 1 );
KSharedConfig::Ptr _config = KGlobal::config();
KConfigGroup config(_config, "Buttons");
QString val;
MyButton *btn;
int i;
static const char *defaultButtons[]={"Menu","Sticky","Off","Iconify",
"Maximize","Close"};
static const char keyOffsets[]={"ABCDEF"};
for(i=0; i < 6; ++i){
if(i == 3){
titlebar = new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum );
hb->addItem( titlebar );
}
QString key("Button");
key += QChar(keyOffsets[i]);
val = config.readEntry(key, defaultButtons[i]);
if(val == "Menu"){
mnuBtn = new MyButton(widget(), "menu");
mnuBtn->setToolTip( i18n("Menu"));
iconChange();
hb->addWidget(mnuBtn);
mnuBtn->setFixedSize(20, 20);
connect(mnuBtn, SIGNAL(pressed()), this,
SLOT(menuButtonPressed()));
}
else if(val == "Sticky"){
stickyBtn = new MyButton(widget(), "sticky");
stickyBtn->setToolTip( i18n("Sticky"));
if (isOnAllDesktops())
stickyBtn->setPixmap(*pindownPix);
else
stickyBtn->setPixmap(*pinupPix);
connect(stickyBtn, SIGNAL( clicked() ), this, SLOT(toggleOnAllDesktops()));
hb->addWidget(stickyBtn);
stickyBtn->setFixedSize(20, 20);
}
else if((val == "Iconify") && isMinimizable()){
btn = new MyButton(widget(), "iconify");
btn->setToolTip( i18n("Minimize"));
btn->setPixmap(*iconifyPix);
connect(btn, SIGNAL(clicked()), this, SLOT(minimize()));
hb->addWidget(btn);
btn->setFixedSize(20, 20);
}
else if((val == "Maximize") && isMaximizable()){
maxBtn = new MyButton(widget(), "max");
maxBtn->setToolTip( i18n("Maximize"));
maxBtn->setPixmap(*maxPix);
connect(maxBtn, SIGNAL(clicked()), this, SLOT(maximize()));
hb->addWidget(maxBtn);
maxBtn->setFixedSize(20, 20);
}
else if((val == "Close") && isCloseable()){
btn = new MyButton(widget(), "close");
btn->setToolTip( i18n("Close"));
btn->setPixmap(*closePix);
connect(btn, SIGNAL(clicked()), this, SLOT(closeWindow()));
hb->addWidget(btn);
btn->setFixedSize(20, 20);
}
else{
if((val != "Off") &&
((val == "Iconify") && !isMinimizable()) &&
((val == "Maximize") && !isMaximizable()))
kWarning() << "KWin: Unrecognized button value: " << val ;
}
}
if(titleGradient){
aGradient = new QPixmap;
iGradient = new QPixmap;
}
else{
aGradient = 0;
iGradient = 0;
}
widget()->setBackgroundMode(NoBackground);
}
void KWMThemeClient::drawTitle(QPainter &dest)
{
QRect titleRect = titlebar->geometry();
QRect r(0, 0, titleRect.width(), titleRect.height());
QPixmap buffer;
if(buffer.width() == r.width())
return;
buffer.resize(r.size());
QPainter p;
p.begin(&buffer);
if(titleSunken){
qDrawShadeRect(&p, r, options()->palette(KDecorationOptions::ColorFrame, isActive()).active(),
true, 1, 0);
r.setRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2);
}
QPixmap *fill = isActive() ? aTitlePix : iTitlePix;
if(fill)
p.drawTiledPixmap(r, *fill);
else if(titleGradient){
fill = isActive() ? aGradient : iGradient;
if(fill->width() != r.width()){
fill->resize(r.width(), 20);
KPixmapEffect::gradient(*fill,
options()->color(KDecorationOptions::ColorTitleBar, isActive()),
options()->color(KDecorationOptions::ColorTitleBlend, isActive()),
grType);
}
p.drawTiledPixmap(r, *fill);
}
else{
p.fillRect(r, options()->palette(KDecorationOptions::ColorTitleBar, isActive()).active().
brush(QPalette::Button));
}
p.setFont(options()->font(isActive()));
p.setPen(options()->color(KDecorationOptions::ColorFont, isActive()));
// Add left & right margin
r.setLeft(r.left()+5);
r.setRight(r.right()-5);
p.drawText(r, titleAlign, caption());
p.end();
dest.drawPixmap(titleRect.x(), titleRect.y(), buffer);
}
void KWMThemeClient::resizeEvent( QResizeEvent* )
{
doShape();
widget()->repaint();
}
void KWMThemeClient::captionChange()
{
widget()->repaint( titlebar->geometry(), false );
}
void KWMThemeClient::paintEvent( QPaintEvent *)
{
QPainter p;
p.begin(widget());
int x,y;
// first the corners
int w1 = framePixmaps[FrameTopLeft]->width();
int h1 = framePixmaps[FrameTopLeft]->height();
if (w1 > width()/2) w1 = width()/2;
if (h1 > height()/2) h1 = height()/2;
p.drawPixmap(0,0,*framePixmaps[FrameTopLeft],
0,0,w1, h1);
int w2 = framePixmaps[FrameTopRight]->width();
int h2 = framePixmaps[FrameTopRight]->height();
if (w2 > width()/2) w2 = width()/2;
if (h2 > height()/2) h2 = height()/2;
p.drawPixmap(width()-w2,0,*framePixmaps[FrameTopRight],
framePixmaps[FrameTopRight]->width()-w2,0,w2, h2);
int w3 = framePixmaps[FrameBottomLeft]->width();
int h3 = framePixmaps[FrameBottomLeft]->height();
if (w3 > width()/2) w3 = width()/2;
if (h3 > height()/2) h3 = height()/2;
p.drawPixmap(0,height()-h3,*framePixmaps[FrameBottomLeft],
0,framePixmaps[FrameBottomLeft]->height()-h3,w3, h3);
int w4 = framePixmaps[FrameBottomRight]->width();
int h4 = framePixmaps[FrameBottomRight]->height();
if (w4 > width()/2) w4 = width()/2;
if (h4 > height()/2) h4 = height()/2;
p.drawPixmap(width()-w4,height()-h4,*(framePixmaps[FrameBottomRight]),
framePixmaps[FrameBottomRight]->width()-w4,
framePixmaps[FrameBottomRight]->height()-h4,
w4, h4);
QPixmap pm;
QMatrix m;
int n,s,w;
//top
pm = *framePixmaps[FrameTop];
if (pm.width() > 0){
s = width()-w2-w1;
n = s/pm.width();
w = n>0?s/n:s;
m.reset();
m.scale(w/(float)pm.width(), 1);
pm = pm.transformed(m);
x = w1;
while (1){
if (pm.width() < width()-w2-x){
p.drawPixmap(x,maxExtent-pm.height()-1,
pm);
x += pm.width();
}
else {
p.drawPixmap(x,maxExtent-pm.height()-1,
pm,
0,0,width()-w2-x,pm.height());
break;
}
}
}
//bottom
pm = *framePixmaps[FrameBottom];
if (pm.width() > 0){
s = width()-w4-w3;
n = s/pm.width();
w = n>0?s/n:s;
m.reset();
m.scale(w/(float)pm.width(), 1);
pm = pm.transformed(m);
x = w3;
while (1){
if (pm.width() < width()-w4-x){
p.drawPixmap(x,height()-maxExtent+1,pm);
x += pm.width();
}
else {
p.drawPixmap(x,height()-maxExtent+1,pm,
0,0,width()-w4-x,pm.height());
break;
}
}
}
//left
pm = *framePixmaps[FrameLeft];
if (pm.height() > 0){
s = height()-h3-h1;
n = s/pm.height();
w = n>0?s/n:s;
m.reset();
m.scale(1, w/(float)pm.height());
pm = pm.transformed(m);
y = h1;
while (1){
if (pm.height() < height()-h3-y){
p.drawPixmap(maxExtent-pm.width()-1, y,
pm);
y += pm.height();
}
else {
p.drawPixmap(maxExtent-pm.width()-1, y,
pm,
0,0, pm.width(),
height()-h3-y);
break;
}
}
}
//right
pm = *framePixmaps[FrameRight];
if (pm.height() > 0){
s = height()-h4-h2;
n = s/pm.height();
w = n>0?s/n:s;
m.reset();
m.scale(1, w/(float)pm.height());
pm = pm.transformed(m);
y = h2;
while (1){
if (pm.height() < height()-h4-y){
p.drawPixmap(width()-maxExtent+1, y,
pm);
y += pm.height();
}
else {
p.drawPixmap(width()-maxExtent+1, y,
pm,
0,0, pm.width(),
height()-h4-y);
break;
}
}
}
drawTitle(p);
QColor c = widget()->colorGroup().background();
// KWM evidently had a 1 pixel border around the client window. We
// emulate it here, but should be removed at some point in order to
// seamlessly mesh widget themes
p.setPen(c);
p.drawRect(maxExtent-1, maxExtent-1, width()-(maxExtent-1)*2,
height()-(maxExtent-1)*2);
// We fill the area behind the wrapped widget to ensure that
// shading animation is drawn as smoothly as possible
QRect r(layout->cellGeometry(2, 1));
p.fillRect( r.x(), r.y(), r.width(), r.height(), c);
p.end();
}
void KWMThemeClient::doShape()
{
QBitmap shapemask(width(), height());
shapemask.fill(color0);
QPainter p;
p.begin(&shapemask);
p.setBrush(color1);
p.setPen(color1);
int x,y;
// first the corners
int w1 = framePixmaps[FrameTopLeft]->width();
int h1 = framePixmaps[FrameTopLeft]->height();
if (w1 > width()/2) w1 = width()/2;
if (h1 > height()/2) h1 = height()/2;
if (framePixmaps[FrameTopLeft]->mask())
p.drawPixmap(0,0,*framePixmaps[FrameTopLeft]->mask(),
0,0,w1, h1);
else
p.fillRect(0,0,w1,h1,color1);
int w2 = framePixmaps[FrameTopRight]->width();
int h2 = framePixmaps[FrameTopRight]->height();
if (w2 > width()/2) w2 = width()/2;
if (h2 > height()/2) h2 = height()/2;
if (framePixmaps[FrameTopRight]->mask())
p.drawPixmap(width()-w2,0,*framePixmaps[FrameTopRight]->mask(),
framePixmaps[FrameTopRight]->width()-w2,0,w2, h2);
else
p.fillRect(width()-w2,0,w2, h2,color1);
int w3 = framePixmaps[FrameBottomLeft]->width();
int h3 = framePixmaps[FrameBottomLeft]->height();
if (w3 > width()/2) w3 = width()/2;
if (h3 > height()/2) h3 = height()/2;
if (framePixmaps[FrameBottomLeft]->mask())
p.drawPixmap(0,height()-h3,*framePixmaps[FrameBottomLeft]->mask(),
0,framePixmaps[FrameBottomLeft]->height()-h3,w3, h3);
else
p.fillRect(0,height()-h3,w3,h3,color1);
int w4 = framePixmaps[FrameBottomRight]->width();
int h4 = framePixmaps[FrameBottomRight]->height();
if (w4 > width()/2) w4 = width()/2;
if (h4 > height()/2) h4 = height()/2;
if (framePixmaps[FrameBottomRight]->mask())
p.drawPixmap(width()-w4,height()-h4,*framePixmaps[FrameBottomRight]->mask(),
framePixmaps[FrameBottomRight]->width()-w4,
framePixmaps[FrameBottomRight]->height()-h4,
w4, h4);
else
p.fillRect(width()-w4,height()-h4,w4,h4,color1);
QPixmap pm;
QMatrix m;
int n,s,w;
//top
if (framePixmaps[FrameTop]->mask())
{
pm = *framePixmaps[FrameTop]->mask();
s = width()-w2-w1;
n = s/pm.width();
w = n>0?s/n:s;
m.reset();
m.scale(w/(float)pm.width(), 1);
pm = pm.transformed(m);
x = w1;
while (1){
if (pm.width() < width()-w2-x){
p.drawPixmap(x,maxExtent-pm.height()-1,
pm);
x += pm.width();
}
else {
p.drawPixmap(x,maxExtent-pm.height()-1,
pm,
0,0,width()-w2-x,pm.height());
break;
}
}
}
//bottom
if (framePixmaps[FrameBottom]->mask())
{
pm = *framePixmaps[FrameBottom]->mask();
s = width()-w4-w3;
n = s/pm.width();
w = n>0?s/n:s;
m.reset();
m.scale(w/(float)pm.width(), 1);
pm = pm.transformed(m);
x = w3;
while (1){
if (pm.width() < width()-w4-x){
p.drawPixmap(x,height()-maxExtent+1,pm);
x += pm.width();
}
else {
p.drawPixmap(x,height()-maxExtent+1,pm,
0,0,width()-w4-x,pm.height());
break;
}
}
}
//left
if (framePixmaps[FrameLeft]->mask())
{
pm = *framePixmaps[FrameLeft]->mask();
s = height()-h3-h1;
n = s/pm.height();
w = n>0?s/n:s;
m.reset();
m.scale(1, w/(float)pm.height());
pm = pm.transformed(m);
y = h1;
while (1){
if (pm.height() < height()-h3-y){
p.drawPixmap(maxExtent-pm.width()-1, y,
pm);
y += pm.height();
}
else {
p.drawPixmap(maxExtent-pm.width()-1, y,
pm,
0,0, pm.width(),
height()-h3-y);
break;
}
}
}
//right
if (framePixmaps[FrameRight]->mask())
{
pm = *framePixmaps[FrameRight]->mask();
s = height()-h4-h2;
n = s/pm.height();
w = n>0?s/n:s;
m.reset();
m.scale(1, w/(float)pm.height());
pm = pm.transformed(m);
y = h2;
while (1){
if (pm.height() < height()-h4-y){
p.drawPixmap(width()-maxExtent+1, y,
pm);
y += pm.height();
}
else {
p.drawPixmap(width()-maxExtent+1, y,
pm,
0,0, pm.width(),
height()-h4-y);
break;
}
}
}
p.fillRect(maxExtent-1, maxExtent-1, width()-2*maxExtent+2, height()-2*maxExtent+2, color1);
setMask(shapemask);
}
void KWMThemeClient::showEvent(QShowEvent *)
{
doShape();
widget()->repaint(false);
}
void KWMThemeClient::mouseDoubleClickEvent( QMouseEvent * e )
{
if (e->button() == LeftButton && titlebar->geometry().contains( e->pos() ) )
titlebarDblClickOperation();
}
void KWMThemeClient::desktopChange()
{
if (stickyBtn) {
bool on = isOnAllDesktops();
stickyBtn->setPixmap(on ? *pindownPix : *pinupPix);
stickyBtn->setToolTip( on ? i18n("Unsticky") : i18n("Sticky") );
}
}
void KWMThemeClient::maximizeChange()
{
if (maxBtn) {
bool m = maximizeMode() == MaximizeFull;
maxBtn->setPixmap(m ? *minmaxPix : *maxPix);
maxBtn->setToolTip( m ? i18n("Restore") : i18n("Maximize"));
}
}
void KWMThemeClient::slotMaximize()
{
maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );
}
void KWMThemeClient::activeChange()
{
widget()->update();
}
KDecoration::Position KWMThemeClient::mousePosition(const QPoint &p) const
{
Position m = KDecoration::mousePosition(p);
// corners
if(p.y() < framePixmaps[FrameTop]->height() &&
p.x() < framePixmaps[FrameLeft]->width()){
m = PositionTopLeft;
}
else if(p.y() < framePixmaps[FrameTop]->height() &&
p.x() > width()-framePixmaps[FrameRight]->width()){
m = PositionTopRight;
}
else if(p.y() > height()-framePixmaps[FrameBottom]->height() &&
p.x() < framePixmaps[FrameLeft]->width()){
m = PositionBottomLeft;
}
else if(p.y() > height()-framePixmaps[FrameBottom]->height() &&
p.x() > width()-framePixmaps[FrameRight]->width()){
m = PositionBottomRight;
} // edges
else if(p.y() < framePixmaps[FrameTop]->height())
m = PositionTop;
else if(p.y() > height()-framePixmaps[FrameBottom]->height())
m = PositionBottom;
else if(p.x() < framePixmaps[FrameLeft]->width())
m = PositionLeft;
else if(p.x() > width()-framePixmaps[FrameRight]->width())
m = PositionRight;
return(m);
}
void KWMThemeClient::menuButtonPressed()
{
mnuBtn->setDown(false); // will stay down if I don't do this
QPoint pos = mnuBtn->mapToGlobal(mnuBtn->rect().bottomLeft());
showWindowMenu( pos );
}
void KWMThemeClient::iconChange()
{
if(mnuBtn){
if( icon().pixmap( QIcon::Small, QIcon::Normal ).isNull()){
mnuBtn->setPixmap(*menuPix);
}
else{
mnuBtn->setPixmap(icon().pixmap( QIcon::Small, QIcon::Normal ));
}
}
}
bool KWMThemeClient::eventFilter( QObject* o, QEvent* e )
{
if ( o != widget() )
return false;
switch ( e->type() )
{
case QEvent::Resize:
resizeEvent( static_cast< QResizeEvent* >( e ) );
return true;
case QEvent::Paint:
paintEvent( static_cast< QPaintEvent* >( e ) );
return true;
case QEvent::MouseButtonDblClick:
mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) );
return true;
case QEvent::MouseButtonPress:
processMousePressEvent( static_cast< QMouseEvent* >( e ) );
return true;
case QEvent::Show:
showEvent( static_cast< QShowEvent* >( e ) );
return true;
default:
return false;
}
}
QSize KWMThemeClient::minimumSize() const
{
return widget()->minimumSize().expandedTo( QSize( 100, 50 ));
}
void KWMThemeClient::resize( const QSize& s )
{
widget()->resize( s );
}
void KWMThemeClient::borders( int& left, int& right, int& top, int& bottom ) const
{
left =
right =
top =
bottom =
TODO
}
KWMThemeFactory::KWMThemeFactory()
{
create_pixmaps();
}
KWMThemeFactory::~KWMThemeFactory()
{
delete_pixmaps();
}
KDecoration* KWMThemeFactory::createDecoration( KDecorationBridge* b )
{
return new KWMThemeClient( b, this );
}
bool KWMThemeFactory::reset( unsigned long mask )
{
bool needHardReset = false;
TODO
// doesn't obey the Border size setting
if( mask & ( SettingFont | SettingButtons ))
needHardReset = true;
if( mask & ( SettingFont | SettingColors )) {
KWMTheme::delete_pixmaps();
KWMTheme::create_pixmaps();
}
if( !needHardReset )
resetDecorations( mask );
return needHardReset;
}
}
extern "C"
{
KDE_EXPORT KDecorationFactory *create_factory()
{
return new KWMTheme::KWMThemeFactory();
}
}
#include "kwmthemeclient.moc"