kwin/default/kdedefault.cpp
Daniel M. Duley 53ae12cbab The new, cool default style! :)
Known errors/bugs:

1) I need to add toolwindows
2) Hiding of buttons isn't working right when the window pops up initially,
only on resize. This one's tough, needs to happen before show but doesn't seem
to work exactly right.

svn path=/trunk/kdebase/kwin/; revision=68366
2000-10-20 00:39:16 +00:00

952 lines
30 KiB
C++

#include <kconfig.h> // up here to avoid X11 header conflict :P
#include "kdedefault.h"
#include <qapplication.h>
#include <qcursor.h>
#include <qabstractlayout.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qdrawutil.h>
#include <kpixmapeffect.h>
#include <kdrawutil.h>
#include <kglobal.h>
#include <kapp.h>
#include <qbitmap.h>
#include "../workspace.h"
#include "../options.h"
extern "C"
{
Client *allocate(Workspace *ws, WId w, int)
{
return(new KDEClient(ws, w));
}
}
static const char *kdelogo[] = {
/* columns rows colors chars-per-pixel */
"16 16 8 1",
" c None",
". c #000000",
"+ c #A0A0A4",
"@ c #FFFFFF",
"# c #585858",
"$ c #C0C0C0",
"% c #808080",
"& c #DCDCDC",
" ",
" .. .. ",
" .+@. .@#. ",
" .@@@. .@@@# ",
" .@@@..$@@$. ",
" .@@@.@@@$. ",
" .@@@%@@$. ",
" .@@@&@@. ",
" .@@@@@@. ",
" .@@@$@@&. ",
" .@@@.@@@. ",
" .@@@.+@@@. ",
" .@@@..$@@&. ",
" .@@%. .@@@. ",
" .... ... ",
" "};
static unsigned char iconify_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char close_bits[] = {
0x00, 0x00, 0x84, 0x00, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00,
0xfc, 0x00, 0xce, 0x01, 0x84, 0x00, 0x00, 0x00};
static unsigned char maximize_bits[] = {
0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x86, 0x01, 0x86, 0x01, 0x86, 0x01,
0x86, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00};
static unsigned char minmax_bits[] = {
0x7f, 0x00, 0x7f, 0x00, 0x63, 0x00, 0xfb, 0x03, 0xfb, 0x03, 0x1f, 0x03,
0x1f, 0x03, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x03};
static unsigned char question_bits[] = {
0x00, 0x00, 0x78, 0x00, 0xcc, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00,
0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00};
static unsigned char pindown_white_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0xa0, 0x03,
0xb0, 0x01, 0x30, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pindown_gray_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pindown_dgray_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x10, 0x70, 0x20, 0x50, 0x20,
0x48, 0x30, 0xc8, 0x38, 0x08, 0x1f, 0x08, 0x18, 0x10, 0x1c, 0x10, 0x0e,
0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pindown_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x1f, 0xf0, 0x3f, 0xf0, 0x3f,
0xf8, 0x3f, 0xf8, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x1f, 0xf0, 0x0f,
0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pinup_white_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x11,
0x3f, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pinup_gray_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x0a, 0xbf, 0x0a, 0x80, 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pinup_dgray_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x40, 0x31, 0x40, 0x2e,
0x40, 0x20, 0x40, 0x20, 0x7f, 0x2a, 0x40, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char pinup_mask_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0xc0, 0x31, 0xc0, 0x3f,
0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xc0, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static QPixmap *titlePix=0;
static KPixmap *aUpperGradient=0;
static KPixmap *iUpperGradient=0;
// buttons active, inactive, and mouse over for both
static KPixmap *btnPix1=0;
static KPixmap *iBtnPix1=0;
static KPixmap *btnDownPix1=0;
static KPixmap *iBtnDownPix1=0;
static KPixmap *pinupPix=0;
static KPixmap *pindownPix=0;
static KPixmap *iPinupPix=0;
static KPixmap *iPindownPix=0;
static KPixmap *pinupPixMO=0;
static KPixmap *pindownPixMO=0;
static KPixmap *iPinupPixMO=0;
static KPixmap *iPindownPixMO=0;
static QColor btnForeground;
static QColor btnMouseOver;
static QPixmap *defaultMenuPix=0;
static bool pixmaps_created = false;
static int titleHeight = 14; // configurable title height not implemented yet
static void drawButtonFrame(KPixmap *pix, const QColorGroup &g, bool sunken)
{
QPainter p;
int w = pix->width();
int h = pix->height();
int x2 = w-1;
int y2 = h-1;
p.begin(pix);
// outer frame
p.setPen(g.mid());
p.drawLine(0, 0, x2, 0);
p.drawLine(0, 0, 0, y2);
p.setPen(g.light());
p.drawLine(x2, 0, x2, y2);
p.drawLine(0, x2, y2, x2);
p.setPen(g.dark());
p.drawRect(1, 1, w-2, h-2);
p.setPen(sunken ? g.mid() : g.light());
p.drawLine(2, 2, x2-2, 2);
p.drawLine(2, 2, 2, y2-2);
p.setPen(sunken ? g.light() : g.mid());
p.drawLine(x2-2, 2, x2-2, y2-2);
p.drawLine(2, x2-2, y2-2, x2-2);
}
static void create_pixmaps()
{
if(pixmaps_created)
return;
pixmaps_created = true;
bool highcolor = QPixmap::defaultDepth() > 8;
// titlebar
QPainter p;
QPainter maskPainter;
int i, x, y;
titlePix = new QPixmap(33, 18);
QBitmap mask(33, 18);
mask.fill(Qt::color0);
p.begin(titlePix);
maskPainter.begin(&mask);
maskPainter.setPen(Qt::color1);
for(i=0, y=2; i < 4; ++i, y+=4){
for(x=1; x <= 33; x+=3){
p.setPen(options->color(Options::TitleBar, true).light(150));
p.drawPoint(x, y);
maskPainter.drawPoint(x, y);
p.setPen(options->color(Options::TitleBar, true).dark(150));
p.drawPoint(x+1, y+1);
maskPainter.drawPoint(x+1, y+1);
}
}
p.end();
maskPainter.end();
titlePix->setMask(mask);
if(highcolor){
aUpperGradient = new KPixmap;
aUpperGradient->resize(32, 18);
iUpperGradient = new KPixmap;
iUpperGradient->resize(32, 18);
QColorGroup bgColor = options->colorGroup(Options::TitleBar, true);
KPixmapEffect::gradient(*aUpperGradient,
bgColor.midlight(),
bgColor.mid(),
KPixmapEffect::VerticalGradient);
bgColor = options->colorGroup(Options::TitleBar, false);
KPixmapEffect::gradient(*iUpperGradient,
bgColor.midlight(),
bgColor.mid(),
KPixmapEffect::VerticalGradient);
}
// pinup and pindown
pinupPix = new KPixmap;
pinupPix->resize(16, 16);
pindownPix = new KPixmap;
pindownPix->resize(16, 16);
iPinupPix = new KPixmap;
iPinupPix->resize(16, 16);
iPindownPix = new KPixmap;
iPindownPix->resize(16, 16);
QBitmap pinupMask(16, 16, pinup_mask_bits, true);
QBitmap pindownMask(16, 16, pindown_mask_bits, true);
p.begin(pinupPix);
if(highcolor)
p.drawPixmap(0, 0, *aUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, true));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, true), 0, 0,
16, 16, true, pinup_white_bits, pinup_gray_bits, NULL,
pinup_dgray_bits, NULL, NULL);
p.end();
p.begin(iPinupPix);
if(highcolor)
p.drawPixmap(0, 0, *iUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, false));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, false), 0, 0,
16, 16, true, pinup_white_bits, pinup_gray_bits, NULL,
pinup_dgray_bits, NULL, NULL);
p.end();
p.begin(pindownPix);
if(highcolor)
p.drawPixmap(0, 0, *aUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, true));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, true), 0, 0,
16, 16, true, pindown_white_bits, pindown_gray_bits, NULL,
pindown_dgray_bits, NULL, NULL);
p.end();
p.begin(iPindownPix);
if(highcolor)
p.drawPixmap(0, 0, *iUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, false));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, false), 0, 0,
16, 16, true, pindown_white_bits, pindown_gray_bits, NULL,
pindown_dgray_bits, NULL, NULL);
p.end();
// pin mouse over
pinupPixMO = new KPixmap;
pinupPixMO->resize(16, 16);
pindownPixMO = new KPixmap;
pindownPixMO->resize(16, 16);
iPinupPixMO = new KPixmap;
iPinupPixMO->resize(16, 16);
iPindownPixMO = new KPixmap;
iPindownPixMO->resize(16, 16);
p.begin(pinupPixMO);
if(highcolor)
p.drawPixmap(0, 0, *aUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, true));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, true), 0, 0,
16, 16, true, pinup_white_bits, pinup_dgray_bits,
pinup_gray_bits, NULL, NULL, NULL);
p.end();
p.begin(iPinupPixMO);
if(highcolor)
p.drawPixmap(0, 0, *iUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, false));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, false), 0, 0,
16, 16, true, pinup_white_bits, pinup_dgray_bits,
pinup_gray_bits, NULL, NULL, NULL);
p.end();
p.begin(pindownPixMO);
if(highcolor)
p.drawPixmap(0, 0, *aUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, true));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, true), 0, 0,
16, 16, true, pindown_white_bits, pindown_dgray_bits,
pindown_gray_bits, NULL, NULL, NULL);
p.end();
p.begin(iPindownPixMO);
if(highcolor)
p.drawPixmap(0, 0, *iUpperGradient);
else
p.fillRect(0, 0, 16, 16, options->color(Options::TitleBar, false));
kColorBitmaps(&p, options->colorGroup(Options::TitleBar, false), 0, 0,
16, 16, true, pindown_white_bits, pindown_dgray_bits,
pindown_gray_bits, NULL, NULL);
p.end();
// buttons (active/inactive, sunken/unsunken, 2 sizes each)
QColorGroup g = options->colorGroup(Options::ButtonBg, true);
QColor c = g.background();
btnPix1 = new KPixmap;
btnPix1->resize(16, 16);
btnDownPix1 = new KPixmap;
btnDownPix1->resize(16, 16);
iBtnPix1 = new KPixmap;
iBtnPix1->resize(16, 16);
iBtnDownPix1 = new KPixmap;
iBtnDownPix1->resize(16, 16);
if(highcolor){
KPixmapEffect::gradient(*btnPix1, c.light(130), c.dark(130),
KPixmapEffect::VerticalGradient);
KPixmapEffect::gradient(*btnDownPix1, c.dark(130), c.light(130),
KPixmapEffect::VerticalGradient);
g = options->colorGroup(Options::ButtonBg, false);
c = g.background();
KPixmapEffect::gradient(*iBtnPix1, c.light(130), c.dark(130),
KPixmapEffect::VerticalGradient);
KPixmapEffect::gradient(*iBtnDownPix1, c.dark(130), c.light(130),
KPixmapEffect::VerticalGradient);
}
else{
btnPix1->fill(c.rgb());
btnDownPix1->fill(c.rgb());
g = options->colorGroup(Options::ButtonBg, false);
c = g.background();
iBtnPix1->fill(c.rgb());
iBtnDownPix1->fill(c.rgb());
}
g = options->colorGroup(Options::ButtonBg, true);
c = g.background();
drawButtonFrame(btnPix1, g, false);
drawButtonFrame(btnDownPix1, g, true);
g = options->colorGroup(Options::ButtonBg, false);
c = g.background();
drawButtonFrame(iBtnPix1, g, false);
drawButtonFrame(iBtnDownPix1, g, true);
if(qGray(options->color(Options::ButtonBg, true).rgb()) > 128){
btnForeground = Qt::black;
btnMouseOver = Qt::darkGray;
}
else{
btnForeground = Qt::white;
btnMouseOver = Qt::lightGray;
}
}
KDEDefaultClientButton::KDEDefaultClientButton(Client *parent, const char *name,
const unsigned char *bitmap)
: QToolButton(parent, name)
{
isMouseOver = false;
client = parent;
setFixedSize(16, 16);
resize(16, 16);
if(bitmap)
setBitmap(bitmap);
//setBackgroundMode(QWidget::NoBackground);
}
QSize KDEDefaultClientButton::sizeHint() const
{
return(QSize(16, 16));
}
void KDEDefaultClientButton::reset()
{
repaint(false);
}
void KDEDefaultClientButton::setBitmap(const unsigned char *bitmap)
{
pix.resize(0, 0);
deco = QBitmap(10, 10, bitmap, true);
deco.setMask(deco);
repaint();
}
void KDEDefaultClientButton::setPixmap(const QPixmap &p,
const QPixmap &mouseOverPix)
{
deco.resize(0, 0);
pix = p;
moPix = mouseOverPix;
setMask(QRect(0, 0, 16, 16));
repaint();
}
void KDEDefaultClientButton::drawButton(QPainter *p)
{
if(pix.isNull()){
if(btnPix1){
if(client->isActive()){
if(isDown())
p->drawPixmap(0, 0, *btnDownPix1);
else
p->drawPixmap(0, 0, *btnPix1);
}
else{
if(isDown())
p->drawPixmap(0, 0, *iBtnDownPix1);
else
p->drawPixmap(0, 0, *iBtnPix1);
}
}
else{
QColorGroup g = options->colorGroup(Options::ButtonBg,
client->isActive());
int w = width();
int h = height();
p->fillRect(1, 1, w-2, h-2, isDown() ? g.mid() : g.button());
p->setPen(isDown() ? g.dark() : g.light());
p->drawLine(0, 0, w-1, 0);
p->drawLine(0, 0, 0, w-1);
p->setPen(isDown() ? g.light() : g.dark());
p->drawLine(w-1, 0, w-1, h-1);
p->drawLine(0, h-1, w-1, h-1);
}
p->setPen(isMouseOver ? btnMouseOver : btnForeground);
int xOff = (width()-10)/2;
int yOff = (height()-10)/2;
p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, deco);
}
else{
if(QPixmap::defaultDepth() > 8)
p->drawPixmap(0, 0, client->isActive()? *aUpperGradient : *iUpperGradient);
else
p->fillRect(0, 0, width(), height(),
options->color(Options::TitleBar, client->isActive()));
p->drawPixmap(0, 0, isMouseOver ? moPix : pix);
}
}
void KDEClient::slotReset()
{
delete titlePix;
delete pinupPix;
delete pindownPix;
delete iPinupPix;
delete iPindownPix;
delete pinupPixMO;
delete pindownPixMO;
delete iPinupPixMO;
delete iPindownPixMO;
if(aUpperGradient){
delete aUpperGradient;
delete iUpperGradient;
delete btnPix1;
delete btnDownPix1;
delete iBtnPix1;
delete iBtnDownPix1;
}
pixmaps_created = false;
create_pixmaps();
int i;
for(i=0; i < 5; ++i){
if(button[i])
button[i]->reset();
}
repaint();
}
KDEClient::KDEClient( Workspace *ws, WId w, QWidget *parent,
const char *name )
: Client( ws, w, parent, name, WResizeNoErase | WNorthWestGravity )
{
if(!defaultMenuPix)
defaultMenuPix = new QPixmap(kdelogo);
lastButtonWidth = 0;
lastBufferWidth = 0;
create_pixmaps();
connect(options, SIGNAL(resetClients()), this, SLOT(slotReset()));
bool help = providesContextHelp();
QGridLayout* g = new QGridLayout(this, 0, 0, 0);
g->setResizeMode(QLayout::FreeResize);
g->addRowSpacing(0, 3);
g->addRowSpacing(2, 1);
g->addWidget(windowWrapper(), 3, 1);
g->setRowStretch(3, 10);
g->addRowSpacing(4, 8); // bottom handles
g->addColSpacing(0, 4);
g->addColSpacing(2, 4);
int th = titleHeight;
if ( isTool() )
th -= 2;
button[BtnMenu] = new KDEDefaultClientButton(this, "menu");
if(!miniIcon().isNull()){
lightIcon = miniIcon();
lightIcon.detach();
lightIcon = KPixmapEffect::intensity(lightIcon, 1.0);
if(miniIcon().mask())
lightIcon.setMask(*miniIcon().mask());
button[BtnMenu]->setPixmap(miniIcon(), lightIcon);
}
else{
lightIcon = *defaultMenuPix;
lightIcon.detach();
lightIcon = KPixmapEffect::intensity(lightIcon, .50);
lightIcon.setMask(*defaultMenuPix->mask());
button[BtnMenu]->setPixmap(*defaultMenuPix, lightIcon);
}
connect(button[BtnMenu], SIGNAL(pressed()), this,
SLOT(menuButtonPressed()));
button[BtnClose] = new KDEDefaultClientButton(this, "close", close_bits);
button[BtnSticky] = new KDEDefaultClientButton(this, "sticky");
if(isSticky()){
if(isActive())
button[BtnSticky]->setPixmap(*pindownPix, *pindownPixMO);
else
button[BtnSticky]->setPixmap(*iPindownPix, *iPindownPixMO);
}
else{
if(isActive())
button[BtnSticky]->setPixmap(*pinupPix, *pinupPixMO);
else
button[BtnSticky]->setPixmap(*iPinupPix, *iPinupPixMO);
}
button[BtnIconify] = new KDEDefaultClientButton(this, "iconify",
iconify_bits);
button[BtnMax] = new KDEDefaultClientButton(this, "maximize",
maximize_bits);
if(help){
button[BtnHelp] = new KDEDefaultClientButton(this, "help",
question_bits);
connect(button[BtnHelp], SIGNAL( clicked() ), this, ( SLOT( contextHelp() ) ) );
}
else
button[BtnHelp] = NULL;
connect( button[BtnClose], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) );
connect( button[BtnSticky], SIGNAL( clicked() ), this, ( SLOT( toggleSticky() ) ) );
connect( button[BtnIconify], SIGNAL( clicked() ), this, ( SLOT( iconify() ) ) );
connect( button[BtnMax], SIGNAL( clicked() ), this, ( SLOT( slotMaximize() ) ) );
hb = new QHBoxLayout();
hb->setResizeMode(QLayout::FreeResize);
g->addLayout( hb, 1, 1 );
hb->addWidget( button[BtnMenu]);
hb->addSpacing(2);
hb->addWidget( button[BtnSticky]);
hb->addSpacing(1);
titlebar = new QSpacerItem(10, th, QSizePolicy::Expanding,
QSizePolicy::Minimum);
hb->addItem(titlebar);
hb->addSpacing(2);
if(help){
hb->addWidget( button[BtnHelp]);
}
hb->addWidget( button[BtnIconify]);
hb->addWidget( button[BtnMax]);
hb->addSpacing(1);
hb->addWidget( button[BtnClose]);
if ( isTransient() || isTool() )
button[BtnSticky]->hide();
if ( !isMinimizable() )
button[BtnIconify]->hide();
if ( !isMaximizable() )
button[BtnMax]->hide();
hiddenItems = false;
bufferDirty = true;
}
void KDEClient::slotMaximize()
{
if ( button[BtnMax]->last_button == MidButton )
maximize( MaximizeVertical );
else if ( button[BtnMax]->last_button == RightButton )
maximize( MaximizeHorizontal );
else
maximize();
}
void KDEClient::resizeEvent( QResizeEvent* e)
{
Client::resizeEvent( e );
doShape();
calcHiddenButtons();
if (isVisibleToTLW()) {
update(rect());
int dx = 0;
int dy = 0;
if ( e->oldSize().width() != width() )
dx = 32 + QABS( e->oldSize().width() - width() );
if ( e->oldSize().height() != height() )
dy = 8 + QABS( e->oldSize().height() - height() );
if ( dy )
update( 0, height() - dy + 1, width(), dy );
if ( dx ) {
update( width() - dx + 1, 0, dx, height() );
update( QRect( QPoint(4,4), titlebar->geometry().bottomLeft() - QPoint(1,0) ) );
update( QRect( titlebar->geometry().topRight(), QPoint( width() - 4, titlebar->geometry().bottom() ) ) );
// titlebar needs no background
QApplication::postEvent( this, new QPaintEvent( titlebar->geometry(), FALSE ) );
}
}
}
void KDEClient::captionChange( const QString& )
{
bufferDirty = true;
repaint( titlebar->geometry(), false );
}
void KDEClient::paintEvent( QPaintEvent* )
{
QPainter p(this);
QRect r(rect());
p.setPen(Qt::black);
p.drawRect(r);
// calc the length of the titlebar (vs frame) color
int titleX2 = r.width() - 6 -
(button[BtnHelp] && button[BtnHelp]->isVisible() ? 16 : 0) -
(button[BtnMax]->isVisible() ? 16 : 0) -
(button[BtnIconify]->isVisible() ? 16 : 0) -
(button[BtnClose]->isVisible() ? 16 : 0);
// draw the part of the frame shaded to the titlebar color
// is the height large enough to handle the extended left titlebar color?
int leftFrameStart = r.height() > 54 ? r.y()+42 : r.y()+18;
QColorGroup g = options->colorGroup(Options::TitleBar, isActive());
p.setPen(g.light());
p.drawLine(r.x()+1, r.y()+1, titleX2-1, r.y()+1);
p.drawLine(r.x()+1, r.y()+1, r.x()+1, leftFrameStart);
if(r.height() > 42){
p.setPen(Qt::black);
p.drawLine(r.x()+1, leftFrameStart, r.x()+2, leftFrameStart-1);
p.setPen(options->color(Options::Frame, isActive()));
p.drawPoint(r.x()+2, leftFrameStart);
p.setPen(g.mid());
p.drawLine(r.x()+2, r.y()+19, r.x()+2, leftFrameStart-2);
}
p.setPen(g.dark());
p.drawLine(titleX2-1, r.y()+1, titleX2-1, r.y()+18);
// part of the frame that is the frame color
g = options->colorGroup(Options::Frame, isActive());
p.setPen(g.light());
p.drawLine(titleX2, r.y()+1, r.right()-1, r.y()+1);
p.drawLine(r.x()+1, leftFrameStart+1, r.x()+1, r.bottom()-1);
p.setPen(g.dark());
p.drawLine(r.right()-1, r.y()+1, r.right()-1, r.bottom()-1);
p.drawLine(r.x()+1, r.bottom()-1, r.right()-1, r.bottom()-1);
int th = titleHeight;
if ( isTool() )
th -= 2;
// inner rect
p.drawRect(r.x()+3, r.y()+16+3, r.width()-6,
r.height()-16-10);
// handles
if(r.width() > 44){
qDrawShadePanel(&p, r.x()+1, r.bottom()-6, 20,
6, g, false, 1, &g.brush(QColorGroup::Mid));
qDrawShadePanel(&p, r.x()+21, r.bottom()-6, r.width()-42, 6,
g, false, 1, isActive() ?
&g.brush(QColorGroup::Background) :
&g.brush(QColorGroup::Mid));
qDrawShadePanel(&p, r.right()-20, r.bottom()-6, 20, 6,
g, false, 1, &g.brush(QColorGroup::Mid));
}
else
qDrawShadePanel(&p, r.x()+1, r.bottom()-6, r.width()-2, 6, g,
false, 1, isActive() ?
&g.brush(QColorGroup::Background) :
&g.brush(QColorGroup::Mid));
r.setRight(r.right()-1);
if(isActive()){
/*
updateActiveBuffer();
p.drawPixmap(r.x(), r.y(), activeBuffer);
*/
if(aUpperGradient){
p.drawTiledPixmap(r.x()+2, r.y()+2, titleX2-3, r.y()+17,
*aUpperGradient);
}
else{
p.fillRect(QRect(QPoint(r.x()+2, r.y()+2),
QPoint(titleX2-2, r.y()+18)),
options->color(Options::TitleBar, true));
}
r = titlebar->geometry();
QFontMetrics fm(options->font(true));
p.setFont(options->font(true));
p.setPen(options->color(Options::Font, true));
p.drawText(r.x(), r.y(), r.width(), r.height()-1,
AlignLeft, caption() );
p.drawTiledPixmap(r.x()+fm.width(caption()), 2,
r.width()-fm.width(caption())-2,
r.height(), *titlePix);
}
else{
if(iUpperGradient){
p.drawTiledPixmap(r.x()+2, r.y()+2, titleX2-3, r.y()+17,
*iUpperGradient);
}
else{
p.fillRect(QRect(QPoint(r.x()+2, r.y()+2),
QPoint(titleX2-2, r.y()+18)),
options->color(Options::TitleBar, false));
}
r = titlebar->geometry();
QFontMetrics fm(options->font(false));
p.setFont(options->font(false));
p.setPen(options->color(Options::Font, false));
p.drawText(r.x(), r.y(), r.width(), r.height()-1,
AlignLeft, caption() );
}
}
#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2)
void KDEClient::doShape()
{
QRegion mask(QRect(0, 0, width(), height()));
mask -= QRect(0, 0, 1, 1);
mask -= QRect(width()-1, 0, 1, 1);
mask -= QRect(0, height()-1, 1, 1);
mask -= QRect(width()-1, height()-1, 1, 1);
setMask(mask);
}
void KDEClient::showEvent(QShowEvent *ev)
{
Client::showEvent(ev);
doShape();
calcHiddenButtons();
repaint();
}
void KDEClient::windowWrapperShowEvent( QShowEvent* )
{
doShape();
}
void KDEClient::mouseDoubleClickEvent( QMouseEvent * e )
{
if (titlebar->geometry().contains( e->pos() ) )
workspace()->performWindowOperation( this, options->operationTitlebarDblClick() );
workspace()->requestFocus( this );
}
void KDEClient::stickyChange(bool on)
{
if(on){
if(isActive())
button[BtnSticky]->setPixmap(*pindownPix, *pindownPixMO);
else
button[BtnSticky]->setPixmap(*iPindownPix, *iPindownPixMO);
}
else{
if(isActive())
button[BtnSticky]->setPixmap(*pinupPix, *pinupPixMO);
else
button[BtnSticky]->setPixmap(*iPinupPix, *iPinupPixMO);
}
}
void KDEClient::maximizeChange(bool m)
{
button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
}
void KDEClient::init()
{
//
}
void KDEClient::activeChange(bool)
{
repaint(false);
int i;
stickyChange(isSticky()); // redo gradient
if(!miniIcon().isNull()){
button[BtnMenu]->setPixmap(miniIcon(), lightIcon); // reset gradient
}
else
button[BtnMenu]->setPixmap(kdelogo, lightIcon);
// TODO KLOGO reset?
for(i=0; i < 6; ++i){
if(button[i])
button[i]->reset();
}
}
void KDEClient::calcHiddenButtons()
{
// order of hiding is help, sticky, maximize, minimize, close, then menu;
// buttons can have
int minWidth = 32 + 16*4 + (providesContextHelp() ? 16*2 :
16);
if(lastButtonWidth > width()){ // shrinking
lastButtonWidth = width();
if(width() < minWidth){
hiddenItems = true;
int i;
for(i=0; i<6; ++i){
if(button[i]){
if( !button[i]->isHidden() ) {
button[i]->hide();
}
minWidth-=button[i]->sizeHint().width();
if(width() >= minWidth)
return;
}
}
}
}
else if(hiddenItems){ // expanding
lastButtonWidth = width();
int i;
int totalSize=32;
for(i=5; i>=0; --i){
if(button[i]){
if(button[i]->sizeHint().width() + totalSize <= width()){
totalSize+=button[i]->sizeHint().width();
if(button[i]->isHidden() &&
( !isTransient() || !isTransient() || i != BtnSticky ) &&
( isMinimizable() || i != BtnIconify ) &&
( isMaximizable() || ( i != BtnIconify && i != BtnSticky && i != BtnMax ) )
) {
button[i]->resize(button[i]->sizeHint());
button[i]->show();
}
}
else
return;
}
}
// all items shown now
hiddenItems = false;
}
else
lastButtonWidth = width();
}
// not used right now
void KDEClient::updateActiveBuffer( )
{
int titleX2 = width() - 6 -
(button[BtnHelp] && button[BtnHelp]->isVisible() ? 16 : 0) -
(button[BtnMax]->isVisible() ? 16 : 0) -
(button[BtnIconify]->isVisible() ? 16 : 0) -
(button[BtnClose]->isVisible() ? 16 : 0);
if(!bufferDirty && (lastBufferWidth == titleX2))
return;
lastBufferWidth = titleX2;
bufferDirty = false;
activeBuffer.resize(titleX2-3, 16);
QPainter p(&activeBuffer);
p.drawTiledPixmap(0, 0, activeBuffer.width(), activeBuffer.height(),
*aUpperGradient);
QRect r = titlebar->geometry();
QFontMetrics fm(options->font(true));
p.setFont(options->font(true));
p.setPen(options->color(Options::Font, true));
p.drawText(r.x(), r.y(), r.width(), r.height()-1,
AlignLeft, caption() );
p.drawTiledPixmap(r.x()+fm.width(caption()), 2,
r.width()-fm.width(caption())-2,
r.height(), *titlePix);
p.end();
}
Client::MousePosition
KDEClient::mousePosition( const QPoint& p ) const
{
MousePosition m = Nowhere;
if (p.y() < (height() - 7))
m = Client::mousePosition(p);
else {
if (p.x() >= (width() - 20))
m = BottomRight;
else if (p.x() <= 20)
m = BottomLeft;
else
m = Bottom;
}
return m;
}
void KDEClient::menuButtonPressed()
{
//workspace()->clientPopup(this)->
// popup(button[BtnMenu]->mapToGlobal(button[BtnMenu]->
// rect().bottomLeft()));
static QTime* t = 0;
static KDEClient* tc = 0;
if ( !t )
t = new QTime;
if ( tc != this || t->elapsed() > QApplication::doubleClickInterval() ){
workspace()->clientPopup(this)->
popup(button[BtnMenu]->mapToGlobal(button[BtnMenu]->
rect().bottomLeft()));
}
else {
button[BtnMenu]->setPopup( 0 );
closeWindow();
}
t->start();
tc = this;
}
#include "kdedefault.moc"