a33f4313ab
clients by adding an unnecessary 'enable-bidi' checkbox which was never agreed upon on the kwin mailing list. The use of --reverse is sufficient without needing this checkbox. Please discuss largish patches like these first, especially during a feature freeze! (Everyone also seems to forget the kwin-styles in kdeartwork) - Make clients look the same with --reverse instead of the broken state they were in previously. If the button ordering is not to your liking in reverse mode, just change the button positions. (Or send patches for those clients that have not got these features yet). - Clean up popupMenu handling somewhat. - Remove a global static object in keramik. svn path=/trunk/kdebase/kwin/; revision=174079
790 lines
21 KiB
C++
790 lines
21 KiB
C++
/*
|
|
* $Id$
|
|
*
|
|
* Redmond KWin client
|
|
*
|
|
* Copyright 2001
|
|
* Karol Szwed <gallium@kde.org>
|
|
* http://gallium.n3.net/
|
|
*
|
|
* Based on the default KWin client.
|
|
*
|
|
* Updated to support toolwindows 3/2001 (KS)
|
|
*
|
|
*/
|
|
|
|
#include "redmond.h"
|
|
#include <qlayout.h>
|
|
#include <qdrawutil.h>
|
|
#include <qdatetime.h>
|
|
#include <kpixmapeffect.h>
|
|
#include <kimageeffect.h>
|
|
#include <kdrawutil.h>
|
|
#include <klocale.h>
|
|
#include <qbitmap.h>
|
|
#include "../../workspace.h"
|
|
#include "../../options.h"
|
|
#include <qimage.h>
|
|
|
|
using namespace KWinInternal;
|
|
|
|
|
|
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00};
|
|
|
|
static unsigned char close_bits[] = {
|
|
0x00, 0x00, 0x86, 0x01, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x78, 0x00,
|
|
0xcc, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00};
|
|
|
|
static unsigned char maximize_bits[] = {
|
|
0xff, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x00, 0x00};
|
|
|
|
static unsigned char minmax_bits[] = {
|
|
0xfc, 0x00, 0xfc, 0x00, 0x84, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xe1, 0x00,
|
|
0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x00, 0x00};
|
|
|
|
static unsigned char question_bits[] = {
|
|
0x00, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
|
|
0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00};
|
|
|
|
|
|
// Up / Down titlebar button images
|
|
static KPixmap *btnPix1;
|
|
static KPixmap *iBtnPix1;
|
|
static KPixmap *btnDownPix1;
|
|
static KPixmap *iBtnDownPix1;
|
|
|
|
static KPixmap *miniBtnPix1;
|
|
static KPixmap *iMiniBtnPix1;
|
|
static KPixmap *miniBtnDownPix1;
|
|
static KPixmap *iMiniBtnDownPix1;
|
|
|
|
static QPixmap *defaultMenuPix;
|
|
static QColor *btnForeground;
|
|
static bool pixmaps_created = false;
|
|
|
|
|
|
static void drawButtonFrame( KPixmap *pix, const QColorGroup &g, bool sunken )
|
|
{
|
|
QPainter p;
|
|
int x2 = pix->width() - 1;
|
|
int y2 = pix->height() - 1;
|
|
p.begin(pix);
|
|
|
|
// titlebar button frame
|
|
p.setPen( sunken ? Qt::black : g.light());
|
|
p.drawLine(0, 0, x2-1, 0);
|
|
p.drawLine(0, 0, 0, y2-1);
|
|
|
|
if (sunken)
|
|
{
|
|
p.setPen( g.dark() );
|
|
p.drawLine(1, 1, x2-2, 1);
|
|
p.drawLine(1, 1, 1, y2-2);
|
|
}
|
|
|
|
p.setPen( sunken ? g.light() : g.dark());
|
|
p.drawLine(1, y2-1, x2-1, y2-1);
|
|
p.drawLine(x2-1, 1, x2-1, y2-1);
|
|
|
|
p.setPen( sunken ? g.light() : Qt::black);
|
|
p.drawLine(0, y2, x2, y2);
|
|
p.drawLine(x2, 0, x2, y2);
|
|
}
|
|
|
|
|
|
static void create_pixmaps( )
|
|
{
|
|
if(pixmaps_created)
|
|
return;
|
|
|
|
pixmaps_created = true;
|
|
|
|
bool highcolor = QPixmap::defaultDepth() > 8;
|
|
|
|
btnPix1 = new KPixmap;
|
|
btnDownPix1 = new KPixmap;
|
|
iBtnPix1 = new KPixmap;
|
|
iBtnDownPix1 = new KPixmap;
|
|
miniBtnPix1 = new KPixmap;
|
|
miniBtnDownPix1 = new KPixmap;
|
|
iMiniBtnPix1 = new KPixmap;
|
|
iMiniBtnDownPix1 = new KPixmap;
|
|
defaultMenuPix = new QPixmap(kdelogo);
|
|
|
|
// buttons (active/inactive, sunken/unsunken)
|
|
QColorGroup g = options->colorGroup(Options::ButtonBg, true);
|
|
QColor c = g.background();
|
|
btnPix1->resize(16, 14);
|
|
btnDownPix1->resize(16, 14);
|
|
iBtnPix1->resize(16, 14);
|
|
iBtnDownPix1->resize(16, 14);
|
|
|
|
miniBtnPix1->resize(12, 12);
|
|
miniBtnDownPix1->resize(12, 12);
|
|
iMiniBtnPix1->resize(12, 12);
|
|
iMiniBtnDownPix1->resize(12, 12);
|
|
|
|
if(highcolor)
|
|
{
|
|
KPixmapEffect::gradient(*btnPix1, c.light(130), c.dark(130),
|
|
KPixmapEffect::VerticalGradient);
|
|
KPixmapEffect::gradient(*btnDownPix1, c.dark(130), c.light(130),
|
|
KPixmapEffect::VerticalGradient);
|
|
|
|
KPixmapEffect::gradient(*miniBtnPix1, c.light(130), c.dark(130),
|
|
KPixmapEffect::VerticalGradient);
|
|
KPixmapEffect::gradient(*miniBtnDownPix1, 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);
|
|
KPixmapEffect::gradient(*iMiniBtnPix1, c.light(130), c.dark(130),
|
|
KPixmapEffect::VerticalGradient);
|
|
KPixmapEffect::gradient(*iMiniBtnDownPix1, c.dark(130), c.light(130),
|
|
KPixmapEffect::VerticalGradient);
|
|
}
|
|
else
|
|
{
|
|
btnPix1->fill(c.rgb());
|
|
btnDownPix1->fill(c.rgb());
|
|
miniBtnPix1->fill(c.rgb());
|
|
miniBtnDownPix1->fill(c.rgb());
|
|
|
|
g = options->colorGroup(Options::ButtonBg, false);
|
|
c = g.background();
|
|
iBtnPix1->fill(c.rgb());
|
|
iBtnDownPix1->fill(c.rgb());
|
|
iMiniBtnPix1->fill(c.rgb());
|
|
iMiniBtnDownPix1->fill(c.rgb());
|
|
}
|
|
|
|
g = options->colorGroup(Options::ButtonBg, true);
|
|
drawButtonFrame(btnPix1, g, false);
|
|
drawButtonFrame(btnDownPix1, g, true);
|
|
drawButtonFrame(miniBtnPix1, g, false);
|
|
drawButtonFrame(miniBtnDownPix1, g, true);
|
|
|
|
g = options->colorGroup(Options::ButtonBg, false);
|
|
drawButtonFrame(iBtnPix1, g, false);
|
|
drawButtonFrame(iBtnDownPix1, g, true);
|
|
drawButtonFrame(iMiniBtnPix1, g, false);
|
|
drawButtonFrame(iMiniBtnDownPix1, g, true);
|
|
|
|
// Make sure button pixmaps contrast with the current colour scheme.
|
|
if(qGray(options->color(Options::ButtonBg, true).rgb()) > 127)
|
|
btnForeground = new QColor(Qt::black);
|
|
else
|
|
btnForeground = new QColor(Qt::white);
|
|
}
|
|
|
|
void delete_pixmaps()
|
|
{
|
|
delete btnPix1;
|
|
delete btnDownPix1;
|
|
delete iBtnPix1;
|
|
delete iBtnDownPix1;
|
|
delete miniBtnPix1;
|
|
delete miniBtnDownPix1;
|
|
delete iMiniBtnPix1;
|
|
delete iMiniBtnDownPix1;
|
|
delete defaultMenuPix;
|
|
delete btnForeground;
|
|
pixmaps_created = false;
|
|
}
|
|
|
|
|
|
GalliumButton::GalliumButton(Client *parent, const char *name,
|
|
const unsigned char *bitmap, bool menuButton, bool isMini, const QString& tip)
|
|
: KWinButton(parent, name, tip)
|
|
{
|
|
// Eliminate background flicker
|
|
setBackgroundMode( QWidget::NoBackground );
|
|
|
|
menuBtn = menuButton;
|
|
miniBtn = isMini;
|
|
client = parent;
|
|
|
|
// Use larger button for the menu, or mini-buttons for toolwindows.
|
|
if ( isMini )
|
|
{
|
|
setFixedSize(12, 12);
|
|
resize(12, 12);
|
|
} else
|
|
if ( menuButton )
|
|
{
|
|
setFixedSize(16, 16);
|
|
resize(16, 16);
|
|
}
|
|
else
|
|
{
|
|
setFixedSize(16, 14);
|
|
resize(16, 14);
|
|
}
|
|
|
|
if(bitmap)
|
|
setBitmap(bitmap);
|
|
}
|
|
|
|
|
|
QSize GalliumButton::sizeHint() const
|
|
{
|
|
if ( miniBtn )
|
|
return(QSize(12, 12));
|
|
|
|
if ( menuBtn )
|
|
return(QSize(16, 16));
|
|
else
|
|
return(QSize(16, 14));
|
|
}
|
|
|
|
|
|
void GalliumButton::reset()
|
|
{
|
|
repaint(false);
|
|
}
|
|
|
|
|
|
void GalliumButton::setBitmap(const unsigned char *bitmap)
|
|
{
|
|
pix.resize(0, 0);
|
|
deco = QBitmap(10, 10, bitmap, true);
|
|
deco.setMask(deco);
|
|
repaint( false );
|
|
}
|
|
|
|
|
|
void GalliumButton::setPixmap( const QPixmap &p )
|
|
{
|
|
deco.resize(0, 0);
|
|
pix = p;
|
|
|
|
if (miniBtn)
|
|
setMask(QRect(0, 0, 12, 12));
|
|
else if (menuBtn)
|
|
setMask(QRect(0, 0, 16, 16));
|
|
else
|
|
setMask(QRect(0, 0, 16, 14));
|
|
|
|
repaint( false );
|
|
}
|
|
|
|
|
|
void GalliumButton::mousePressEvent( QMouseEvent* e )
|
|
{
|
|
last_button = e->button();
|
|
QMouseEvent me ( e->type(), e->pos(), e->globalPos(),
|
|
LeftButton, e->state() );
|
|
KWinButton::mousePressEvent( &me );
|
|
}
|
|
|
|
|
|
void GalliumButton::mouseReleaseEvent( QMouseEvent* e )
|
|
{
|
|
last_button = e->button();
|
|
QMouseEvent me ( e->type(), e->pos(), e->globalPos(),
|
|
LeftButton, e->state() );
|
|
KWinButton::mouseReleaseEvent( &me );
|
|
}
|
|
|
|
|
|
void GalliumButton::drawButton(QPainter *p)
|
|
{
|
|
if(pix.isNull())
|
|
{
|
|
if(client->isActive())
|
|
{
|
|
if(isDown())
|
|
p->drawPixmap(0, 0, miniBtn ? *miniBtnDownPix1 : *btnDownPix1);
|
|
else
|
|
p->drawPixmap(0, 0, miniBtn ? *miniBtnPix1 : *btnPix1);
|
|
}
|
|
else
|
|
{
|
|
if(isDown())
|
|
p->drawPixmap(0, 0, miniBtn ? *iMiniBtnDownPix1 : *iBtnDownPix1);
|
|
else
|
|
p->drawPixmap(0, 0, miniBtn ? *iMiniBtnPix1 : *iBtnPix1);
|
|
}
|
|
|
|
p->setPen( *btnForeground );
|
|
int xOff = (width()-10)/2;
|
|
int yOff = (height()-10)/2;
|
|
p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, deco);
|
|
}
|
|
else
|
|
{
|
|
p->fillRect(0, 0, width(), height(),
|
|
options->color(Options::TitleBar, client->isActive()));
|
|
|
|
if ( menuBtn && miniBtn )
|
|
{
|
|
QPixmap tmpPix;
|
|
|
|
// Smooth scale the menu button pixmap
|
|
tmpPix.convertFromImage( pix.convertToImage().smoothScale(12, 12));
|
|
|
|
p->drawPixmap( 0, 0, tmpPix );
|
|
} else
|
|
p->drawPixmap( 0, 0, pix );
|
|
}
|
|
}
|
|
|
|
|
|
GalliumClient::GalliumClient( Workspace *ws, WId w, QWidget *parent,
|
|
const char *name )
|
|
: Client( ws, w, parent, name, WResizeNoErase | WStaticContents |
|
|
WRepaintNoErase )
|
|
{
|
|
setBackgroundMode( QWidget::NoBackground );
|
|
|
|
// Finally, toolwindows look small
|
|
if ( isTool() ) {
|
|
titleHeight = 14;
|
|
smallButtons = true;
|
|
} else {
|
|
titleHeight = 18;
|
|
smallButtons = false;
|
|
}
|
|
|
|
lastButtonWidth = 0;
|
|
|
|
QGridLayout* g = new QGridLayout(this, 0, 0, 0);
|
|
g->setResizeMode(QLayout::FreeResize);
|
|
g->addRowSpacing(0, 4); // Top grab bar
|
|
g->addWidget(windowWrapper(), 3, 1);
|
|
// without the next line, unshade flickers
|
|
g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed,
|
|
QSizePolicy::Expanding ) );
|
|
g->setRowStretch(3, 10); // Wrapped window
|
|
g->addRowSpacing(4, 4); // bottom handles
|
|
g->addRowSpacing(2, 1); // Line below title bar
|
|
g->addColSpacing(0, 4);
|
|
g->addColSpacing(2, 4);
|
|
|
|
button[BtnMenu] = new GalliumButton(this, "menu", NULL, true, smallButtons,
|
|
i18n("Menu"));
|
|
button[BtnClose] = new GalliumButton(this, "close", close_bits, false, smallButtons,
|
|
i18n("Close"));
|
|
button[BtnIconify] = new GalliumButton(this, "iconify", iconify_bits, false, smallButtons,
|
|
i18n("Minimize"));
|
|
button[BtnMax] = new GalliumButton(this, "maximize", maximize_bits, false, smallButtons,
|
|
i18n("Maximize"));
|
|
|
|
// Connect required stuff together
|
|
connect( button[BtnMenu], SIGNAL(pressed()), this, SLOT( menuButtonPressed() ));
|
|
connect( button[BtnClose], SIGNAL( clicked() ), this, SLOT( closeWindow() ));
|
|
connect( button[BtnIconify], SIGNAL( clicked() ), this, SLOT( iconify() ));
|
|
connect( button[BtnMax], SIGNAL( clicked() ), this, SLOT( slotMaximize() ));
|
|
connect( options, SIGNAL(resetClients()), this, SLOT( slotReset() ));
|
|
|
|
// Pack the titleBar hbox with items
|
|
hb = new QBoxLayout(0, QBoxLayout::LeftToRight, 0, 0, 0);
|
|
hb->setResizeMode(QLayout::FreeResize);
|
|
g->addLayout( hb, 1, 1 );
|
|
hb->addSpacing(2);
|
|
hb->addWidget( button[BtnMenu] );
|
|
titlebar = new QSpacerItem(10, titleHeight, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
hb->addItem(titlebar);
|
|
hb->addSpacing(2);
|
|
|
|
if( providesContextHelp() )
|
|
{
|
|
button[BtnHelp] = new GalliumButton(this, "help", question_bits, false, smallButtons,
|
|
i18n("Help"));
|
|
connect( button[BtnHelp], SIGNAL( clicked() ), this, SLOT( contextHelp() ));
|
|
hb->addWidget( button[BtnHelp] );
|
|
}
|
|
else
|
|
button[BtnHelp] = NULL;
|
|
|
|
hb->addWidget( button[BtnIconify] );
|
|
hb->addWidget( button[BtnMax] );
|
|
hb->addSpacing(2);
|
|
hb->addWidget( button[BtnClose] );
|
|
hb->addSpacing(2);
|
|
|
|
// Hide buttons which are not required
|
|
// We can un-hide them if required later
|
|
if ( !isMinimizable() )
|
|
button[BtnIconify]->hide();
|
|
if ( !isMaximizable() )
|
|
button[BtnMax]->hide();
|
|
|
|
hiddenItems = false;
|
|
|
|
// Make sure that the menu button uses the correct mini-icon
|
|
iconChange();
|
|
}
|
|
|
|
|
|
void GalliumClient::slotReset()
|
|
{
|
|
// 0 to 3 ( 4 buttons - Help, Max, Iconify, Close )
|
|
for(int i = GalliumClient::BtnHelp; i <= GalliumClient::BtnClose; i++)
|
|
if(button[i])
|
|
button[i]->reset();
|
|
|
|
// The menu is reset by iconChange()
|
|
|
|
repaint( false );
|
|
}
|
|
|
|
|
|
void GalliumClient::iconChange()
|
|
{
|
|
if(!miniIcon().isNull())
|
|
button[BtnMenu]->setPixmap(miniIcon());
|
|
else
|
|
button[BtnMenu]->setPixmap(*defaultMenuPix);
|
|
|
|
if (button[BtnMenu]->isVisible())
|
|
button[BtnMenu]->repaint(false);
|
|
}
|
|
|
|
|
|
void GalliumClient::slotMaximize()
|
|
{
|
|
if ( button[BtnMax]->last_button == MidButton )
|
|
maximize( MaximizeVertical );
|
|
else if ( button[BtnMax]->last_button == RightButton )
|
|
maximize( MaximizeHorizontal );
|
|
else
|
|
maximize();
|
|
}
|
|
|
|
|
|
void GalliumClient::resizeEvent( QResizeEvent* e)
|
|
{
|
|
Client::resizeEvent( e );
|
|
|
|
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 paint event
|
|
QApplication::postEvent( this, new QPaintEvent( titlebar->geometry(), FALSE ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void GalliumClient::captionChange( const QString& )
|
|
{
|
|
repaint( titlebar->geometry(), false );
|
|
}
|
|
|
|
|
|
void GalliumClient::paintEvent( QPaintEvent* )
|
|
{
|
|
bool hicolor = QPixmap::defaultDepth() > 8;
|
|
int fontoffset = 1;
|
|
|
|
QPainter p(this);
|
|
|
|
// Obtain widget bounds.
|
|
QRect r(rect());
|
|
int x = r.x();
|
|
int y = r.y();
|
|
int x2 = r.width()-1;
|
|
int y2 = r.height()-1;
|
|
int w = r.width();
|
|
int h = r.height();
|
|
|
|
// Draw part of the frame that is the frame color
|
|
// ==============================================
|
|
QColorGroup g = options->colorGroup(Options::Frame, isActive());
|
|
p.setPen( g.background() );
|
|
p.drawLine( x, y, x2-1, y );
|
|
p.drawLine( x, y, x, y2-1 );
|
|
|
|
// Draw line under title bar
|
|
p.drawLine( x + 4, y + titleHeight + 4, x2 - 4, y + titleHeight + 4 );
|
|
// Draw a hidden line that appears during shading
|
|
p.drawLine( x + 4, y2 - 4, x2 - 4, y2 - 4 );
|
|
|
|
// Fill out the border edges
|
|
p.drawRect( x+2, y+2, w-4, h-4 );
|
|
p.drawRect( x+3, y+3, w-6, h-6 );
|
|
|
|
// Draw highlights and lowlights
|
|
p.setPen(g.light());
|
|
p.drawLine( x+1, y+1, x2-2, y+1);
|
|
p.drawLine( x+1, y+1, x+1, y2-2);
|
|
|
|
p.setPen(g.dark());
|
|
p.drawLine( x2-1, y+1, x2-1, y2-1);
|
|
p.drawLine( x+1, y2-1, x2-1, y2-1);
|
|
|
|
// Draw black edges
|
|
p.setPen( Qt::black );
|
|
p.drawLine(x2, y, x2, y2);
|
|
p.drawLine(x, y2, x2, y2);
|
|
|
|
// Draw the title bar.
|
|
// ===================
|
|
r = titlebar->geometry();
|
|
QFontMetrics fm(options->font(true));
|
|
|
|
// Obtain blend colours.
|
|
QColor c1 = options->color(Options::TitleBar, isActive() );
|
|
QColor c2 = options->color(Options::TitleBlend, isActive() );
|
|
|
|
// Paint without a buffer if the colours are the same to
|
|
// improve performance, and only draw gradients on hicolor displays.
|
|
if ((c1 != c2) && hicolor)
|
|
{
|
|
// KS - Add gradient caching if needed at a later stage.
|
|
|
|
// Create a disposable pixmap buffer for the title blend
|
|
KPixmap* titleBuffer = new KPixmap;
|
|
titleBuffer->resize(w-8, titleHeight);
|
|
|
|
if (titleBuffer->depth() > 16)
|
|
{
|
|
KPixmapEffect::gradient(*titleBuffer, c1, c2,
|
|
KPixmapEffect::HorizontalGradient);
|
|
}
|
|
else
|
|
{
|
|
// This enables dithering on 15 and 16bit displays, preventing
|
|
// some pretty horrible banding effects
|
|
QImage image = KImageEffect::gradient(titleBuffer->size(), c1, c2,
|
|
KImageEffect::HorizontalGradient);
|
|
|
|
titleBuffer->convertFromImage(image, Qt::OrderedDither);
|
|
}
|
|
|
|
QPainter p2( titleBuffer, this );
|
|
|
|
// Since drawing the gradient is (relatively) slow, it is best
|
|
// to draw the title text on the pixmap.
|
|
|
|
// Reduce the font size and weight for toolwindows.
|
|
QFont fnt = options->font(true);
|
|
if ( smallButtons )
|
|
{
|
|
fnt.setPointSize( fnt.pointSize() - 2 ); // Shrink font by 2 pt.
|
|
fnt.setWeight( QFont::Normal );
|
|
fontoffset = 0;
|
|
}
|
|
p2.setFont( fnt );
|
|
p2.setPen( options->color(Options::Font, isActive() ));
|
|
p2.drawText( r.x(), fontoffset, r.width()-3, r.height()-1,
|
|
AlignLeft | AlignVCenter, caption() );
|
|
p2.end();
|
|
|
|
p.drawPixmap( 4, 4, *titleBuffer );
|
|
|
|
delete titleBuffer;
|
|
|
|
} else
|
|
{
|
|
// Assume lower ended hardware, so don't use buffers.
|
|
// Don't draw a gradient either.
|
|
p.fillRect( 4, 4, w-8, titleHeight, c1 );
|
|
|
|
// Draw the title text.
|
|
QFont fnt = options->font(true);
|
|
if ( smallButtons )
|
|
{
|
|
fnt.setPointSize( fnt.pointSize() - 2 ); // Shrink font by 2 pt.
|
|
fnt.setWeight( QFont::Normal );
|
|
fontoffset = 0;
|
|
}
|
|
p.setFont( fnt );
|
|
p.setPen(options->color(Options::Font, isActive() ));
|
|
p.drawText(r.x()+4, r.y()+fontoffset, r.width()-3, r.height()-1,
|
|
AlignLeft | AlignVCenter, caption() );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void GalliumClient::showEvent(QShowEvent *ev)
|
|
{
|
|
calcHiddenButtons();
|
|
show();
|
|
Client::showEvent(ev);
|
|
}
|
|
|
|
|
|
void GalliumClient::mouseDoubleClickEvent( QMouseEvent * e )
|
|
{
|
|
if (titlebar->geometry().contains( e->pos() ) )
|
|
workspace()->performWindowOperation( this, options->operationTitlebarDblClick() );
|
|
}
|
|
|
|
|
|
void GalliumClient::maximizeChange(bool m)
|
|
{
|
|
button[BtnMax]->setBitmap(m ? minmax_bits : maximize_bits);
|
|
button[BtnMax]->setTipText(m ? i18n("Restore") : i18n("Maximize"));
|
|
}
|
|
|
|
|
|
void GalliumClient::activeChange(bool)
|
|
{
|
|
|
|
if(!miniIcon().isNull())
|
|
{
|
|
button[BtnMenu]->setPixmap(miniIcon());
|
|
}
|
|
else
|
|
button[BtnMenu]->setPixmap(kdelogo);
|
|
|
|
for(int i=GalliumClient::BtnHelp; i < GalliumClient::BtnMenu; i++)
|
|
{
|
|
if(button[i])
|
|
button[i]->reset();
|
|
}
|
|
// Reset the menu button ?
|
|
|
|
repaint(false);
|
|
}
|
|
|
|
|
|
void GalliumClient::calcHiddenButtons()
|
|
{
|
|
// order of hiding is help, maximize, minimize, close, then menu;
|
|
int minWidth = 32 + 16*4 + (providesContextHelp() ? 16*2 : 16 );
|
|
|
|
if(lastButtonWidth > width()) // Shrinking
|
|
{
|
|
lastButtonWidth = width();
|
|
if(width() < minWidth)
|
|
{
|
|
hiddenItems = true;
|
|
|
|
for(int i = GalliumClient::BtnHelp; i <= GalliumClient::BtnMenu; 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 totalSize = 16*3;
|
|
|
|
for(int i = GalliumClient::BtnMenu; i >= GalliumClient::BtnHelp; i--)
|
|
{
|
|
if(button[i])
|
|
{
|
|
if(button[i]->sizeHint().width() + totalSize <= width())
|
|
{
|
|
totalSize += button[i]->sizeHint().width();
|
|
button[i]->resize(button[i]->sizeHint());
|
|
button[i]->show();
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
}
|
|
|
|
// all items shown now
|
|
hiddenItems = false;
|
|
}
|
|
else
|
|
lastButtonWidth = width();
|
|
}
|
|
|
|
|
|
void GalliumClient::menuButtonPressed()
|
|
{
|
|
QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-3,
|
|
button[BtnMenu]->rect().bottomLeft().y()+2 );
|
|
workspace()->showWindowMenu( button[BtnMenu]->mapToGlobal( menupoint ), this );
|
|
button[BtnMenu]->setDown(false);
|
|
}
|
|
|
|
extern "C"
|
|
{
|
|
Client *allocate(Workspace *ws, WId w, int)
|
|
{
|
|
return(new GalliumClient(ws, w));
|
|
}
|
|
|
|
void init()
|
|
{
|
|
create_pixmaps();
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
delete_pixmaps();
|
|
create_pixmaps();
|
|
Workspace::self()->slotResetAllClientsDelayed();
|
|
}
|
|
|
|
void deinit()
|
|
{
|
|
delete_pixmaps();
|
|
}
|
|
}
|
|
|
|
|
|
#include "redmond.moc"
|
|
// vim: ts=4
|