From ed52142183ad2733872aa3b2835638bbaf75abdc Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 20 Jun 2001 11:42:49 +0000 Subject: [PATCH] Neil Stevens said he would maintain this one. svn path=/trunk/kdebase/kwin/; revision=103161 --- clients/system/Makefile.am | 21 ++ clients/system/system.desktop | 23 ++ clients/system/systemclient.cpp | 555 ++++++++++++++++++++++++++++++++ clients/system/systemclient.h | 79 +++++ 4 files changed, 678 insertions(+) create mode 100644 clients/system/Makefile.am create mode 100644 clients/system/system.desktop create mode 100644 clients/system/systemclient.cpp create mode 100644 clients/system/systemclient.h diff --git a/clients/system/Makefile.am b/clients/system/Makefile.am new file mode 100644 index 0000000000..21d3f1e107 --- /dev/null +++ b/clients/system/Makefile.am @@ -0,0 +1,21 @@ + +INCLUDES = $(all_includes) + +kde_module_LTLIBRARIES = libkwinsystem.la + +libkwinsystem_la_SOURCES = systemclient.cpp +libkwinsystem_la_LIBADD = ../../kwin.la +libkwinsystem_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) + +METASOURCES = AUTO +noinst_HEADERS = systemclient.h + +lnkdir = $(kde_datadir)/kwin/ +lnk_DATA = system.desktop + +EXTRA_DIST = $(lnk_DATA) + + +###KMAKE-start (don't edit or delete this block) + +###KMAKE-end diff --git a/clients/system/system.desktop b/clients/system/system.desktop new file mode 100644 index 0000000000..8fb5c70c14 --- /dev/null +++ b/clients/system/system.desktop @@ -0,0 +1,23 @@ +[Desktop Entry] +Name=System++ +Name[az]=Sistem++ +Name[br]=Reizhiad++ +Name[ca]=Sistema++ +Name[cs]=Systém++ +Name[eo]=Sistemo++ +Name[et]=Süsteem++ +Name[fi]=Järjestelmä++ +Name[fr]=Système++ +Name[is]=Kerfi++ +Name[ko]=시스템++ +Name[lt]=Sistema++ +Name[lv]=Sistēma++ +Name[mk]=Систем++ +Name[nl]=Systeem++ +Name[oc]=Sistemo++ +Name[ro]=Sistem++ +Name[sk]=Systém++ +Name[sl]=Sistem++ +Name[tr]=Sistem++ +Name[zh_TW.Big5]=系統++ +X-KDE-Library=libkwinsystem diff --git a/clients/system/systemclient.cpp b/clients/system/systemclient.cpp new file mode 100644 index 0000000000..8751e89d57 --- /dev/null +++ b/clients/system/systemclient.cpp @@ -0,0 +1,555 @@ +#include "systemclient.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../workspace.h" +#include "../../options.h" + +using namespace KWinInternal; + + +static unsigned char iconify_bits[] = { + 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00}; + +static unsigned char maximize_bits[] = { + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00}; + +static unsigned char minmax_bits[] = { + 0x0c, 0x18, 0x33, 0x67, 0xcf, 0x9f, 0x3f, 0x3f}; + +static unsigned char unsticky_bits[] = { + 0x00, 0x18, 0x18, 0x7e, 0x7e, 0x18, 0x18, 0x00}; + +static unsigned char sticky_bits[] = { + 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00}; + +static unsigned char question_bits[] = { + 0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18}; + +static KPixmap *aUpperGradient=0; +static KPixmap *iUpperGradient=0; + +static KPixmap *btnPix=0; +static KPixmap *btnPixDown=0; +static KPixmap *iBtnPix=0; +static KPixmap *iBtnPixDown=0; +static QColor *btnForeground; + +static bool pixmaps_created = false; + +static void drawButtonFrame(KPixmap *pix, const QColorGroup &g) +{ + QPainter p; + p.begin(pix); + p.setPen(g.mid()); + p.drawLine(0, 0, 13, 0); + p.drawLine(0, 0, 0, 13); + p.setPen(g.light()); + p.drawLine(13, 0, 13, 13); + p.drawLine(0, 13, 13, 13); + p.setPen(g.dark()); + p.drawRect(1, 1, 12, 12); + p.end(); +} + +static void create_pixmaps() +{ + if(pixmaps_created) + return; + pixmaps_created = true; + + if(QPixmap::defaultDepth() > 8){ + // titlebar + aUpperGradient = new KPixmap; + aUpperGradient->resize(32, 18); + iUpperGradient = new KPixmap; + iUpperGradient->resize(32, 18); + QColor bgColor = kapp->palette().normal().background(); + KPixmapEffect::gradient(*aUpperGradient, + options->color(Options::Frame, true).light(130), + bgColor, + KPixmapEffect::VerticalGradient); + KPixmapEffect::gradient(*iUpperGradient, + options->color(Options::Frame, false).light(130), + bgColor, + KPixmapEffect::VerticalGradient); + + // buttons + KPixmap aPix; + aPix.resize(12, 12); + KPixmap iPix; + iPix.resize(12, 12); + KPixmap aInternal; + aInternal.resize(8, 8); + KPixmap iInternal; + iInternal.resize(8, 8); + + QColor hColor(options->color(Options::ButtonBg, false)); + KPixmapEffect::gradient(iInternal, + hColor.dark(120), + hColor.light(120), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(iPix, + hColor.light(150), + hColor.dark(150), + KPixmapEffect::DiagonalGradient); + + hColor =options->color(Options::ButtonBg, true); + KPixmapEffect::gradient(aInternal, + hColor.dark(120), + hColor.light(120), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(aPix, + hColor.light(150), + hColor.dark(150), + KPixmapEffect::DiagonalGradient); + bitBlt(&aPix, 1, 1, &aInternal, 0, 0, 8, 8, Qt::CopyROP, true); + bitBlt(&iPix, 1, 1, &iInternal, 0, 0, 8, 8, Qt::CopyROP, true); + + // normal buttons + btnPix = new KPixmap; + btnPix->resize(14, 14); + bitBlt(btnPix, 2, 2, &aPix, 0, 0, 10, 10, Qt::CopyROP, true); + drawButtonFrame(btnPix, options->colorGroup(Options::Frame, true)); + + iBtnPix = new KPixmap; + iBtnPix->resize(14, 14); + bitBlt(iBtnPix, 2, 2, &iPix, 0, 0, 10, 10, Qt::CopyROP, true); + drawButtonFrame(iBtnPix, options->colorGroup(Options::Frame, false)); + + + // pressed buttons + hColor = options->color(Options::ButtonBg, false); + KPixmapEffect::gradient(iInternal, + hColor.light(130), + hColor.dark(130), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(iPix, + hColor.light(150), + hColor.dark(150), + KPixmapEffect::DiagonalGradient); + + hColor =options->color(Options::ButtonBg, true); + KPixmapEffect::gradient(aInternal, + hColor.light(130), + hColor.dark(130), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(aPix, + hColor.light(150), + hColor.dark(150), + KPixmapEffect::DiagonalGradient); + bitBlt(&aPix, 1, 1, &aInternal, 0, 0, 8, 8, Qt::CopyROP, true); + bitBlt(&iPix, 1, 1, &iInternal, 0, 0, 8, 8, Qt::CopyROP, true); + + btnPixDown = new KPixmap; + btnPixDown->resize(14, 14); + bitBlt(btnPixDown, 2, 2, &aPix, 0, 0, 10, 10, Qt::CopyROP, true); + drawButtonFrame(btnPixDown, options->colorGroup(Options::Frame, + true)); + + iBtnPixDown = new KPixmap; + iBtnPixDown->resize(14, 14); + bitBlt(iBtnPixDown, 2, 2, &iPix, 0, 0, 10, 10, Qt::CopyROP, true); + drawButtonFrame(iBtnPixDown, options->colorGroup(Options::Frame, + false)); + } + if(qGray(options->color(Options::ButtonBg, true).rgb()) > 128) + btnForeground = new QColor(Qt::black); + else + btnForeground = new QColor(Qt::white); +} + +static void delete_pixmaps() +{ + if(aUpperGradient){ + delete aUpperGradient; + delete iUpperGradient; + delete btnPix; + delete btnPixDown; + delete iBtnPix; + delete iBtnPixDown; + aUpperGradient = 0; + } + delete btnForeground; + pixmaps_created = false; +} + +SystemButton::SystemButton(Client *parent, const char *name, + const unsigned char *bitmap) + : QToolButton(parent, name) +{ + setBackgroundMode( NoBackground ); + resize(14, 14); + connect( this, SIGNAL( clicked() ), this, SLOT( handleClicked() ) ); + if(bitmap) + setBitmap(bitmap); + client = parent; +} + +QSize SystemButton::sizeHint() const +{ + return(QSize(14, 14)); +} + +void SystemButton::reset() +{ + repaint(false); +} + +void SystemButton::setBitmap(const unsigned char *bitmap) +{ + deco = QBitmap(8, 8, bitmap, true); + deco.setMask(deco); + repaint(); +} + +void SystemButton::drawButton(QPainter *p) +{ + if(btnPixDown){ + if(client->isActive()) + p->drawPixmap(0, 0, isDown() ? *btnPixDown : *btnPix); + else + p->drawPixmap(0, 0, isDown() ? *iBtnPixDown : *iBtnPix); + } + else{ + QColorGroup g = options->colorGroup(Options::Frame, + client->isActive()); + int x2 = width()-1; + int y2 = height()-1; + // 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, width()-2, height()-2); + // inner frame + g = options->colorGroup(Options::ButtonBg, client->isActive()); + p->fillRect(3, 3, width()-6, height()-6, g.background()); + p->setPen(isDown() ? g.mid() : g.light()); + p->drawLine(2, 2, x2-2, 2); + p->drawLine(2, 2, 2, y2-2); + p->setPen(isDown() ? g.light() : g.mid()); + p->drawLine(x2-2, 2, x2-2, y2-2); + p->drawLine(2, x2-2, y2-2, x2-2); + + } + + if(!deco.isNull()){ + p->setPen(*btnForeground); + p->drawPixmap(isDown() ? 4 : 3, isDown() ? 4 : 3, deco); + } + + +} + +void SystemButton::mousePressEvent( QMouseEvent* e ) +{ + last_button = e->button(); + QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() ); + QToolButton::mousePressEvent( &me ); +} + +void SystemButton::mouseReleaseEvent( QMouseEvent* e ) +{ + QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() ); + QToolButton::mouseReleaseEvent( &me ); +} + +void SystemButton::handleClicked() +{ + emit clicked( last_button ); +} + + +void SystemClient::slotReset() +{ + titleBuffer.resize(0, 0); + recalcTitleBuffer(); + repaint(); + button[0]->reset(); + button[1]->reset(); + button[2]->reset(); + button[3]->reset(); + if(button[4]) + button[4]->reset(); +} + +void SystemClient::maxButtonClicked( int button ) +{ + switch ( button ){ + case MidButton: + maximize( MaximizeVertical ); + break; + case RightButton: + maximize( MaximizeHorizontal ); + break; + default: //LeftButton: + maximize( MaximizeFull ); + break; + } +} + +SystemClient::SystemClient( Workspace *ws, WId w, QWidget *parent, + const char *name ) + : Client( ws, w, parent, name, WResizeNoErase ) +{ + connect(options, SIGNAL(resetClients()), this, SLOT(slotReset())); + bool help = providesContextHelp(); + + QGridLayout* g = new QGridLayout(this, 0, 0, 2); + g->setRowStretch(1, 10); + g->addWidget(windowWrapper(), 1, 1 ); + g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) ); + + g->addColSpacing(0, 2); + g->addColSpacing(2, 2); + g->addRowSpacing(2, 6); + + button[0] = new SystemButton(this, "close"/*, close_bits*/); + button[1] = new SystemButton(this, "sticky"); + if(isSticky()) + button[1]->setBitmap(unsticky_bits); + else + button[1]->setBitmap(sticky_bits); + button[2] = new SystemButton(this, "iconify", iconify_bits); + button[3] = new SystemButton(this, "maximize", maximize_bits); + if(help){ + button[4] = new SystemButton(this, "help", question_bits); + connect( button[4], SIGNAL( clicked() ), this, ( SLOT( contextHelp() ) ) ); + } + else + button[4] = NULL; + + connect( button[0], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) ); + connect( button[1], SIGNAL( clicked() ), this, ( SLOT( toggleSticky() ) ) ); + connect( button[2], SIGNAL( clicked() ), this, ( SLOT( iconify() ) ) ); + connect( button[3], SIGNAL( clicked(int) ), this, ( SLOT( maxButtonClicked(int) ) ) ); + + QHBoxLayout* hb = new QHBoxLayout(0); + hb->setResizeMode(QLayout::FreeResize); + g->addLayout( hb, 0, 1 ); + hb->addSpacing(3); + hb->addWidget( button[0]); + titlebar = new QSpacerItem(10, 14, QSizePolicy::Expanding, + QSizePolicy::Minimum); + hb->addSpacing(3); + hb->addItem(titlebar); + hb->addSpacing(3); + if(help){ + hb->addWidget( button[4]); + hb->addSpacing(1); + } + hb->addWidget( button[1]); + hb->addSpacing(1); + hb->addWidget( button[2]); + hb->addSpacing(1); + hb->addWidget( button[3]); + hb->addSpacing(3); + + setBackgroundMode(NoBackground); + recalcTitleBuffer(); + +} + +void SystemClient::resizeEvent( QResizeEvent* ) +{ + //Client::resizeEvent( e ); + recalcTitleBuffer(); + doShape(); + /* + if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity )) { + QPainter p( this ); + QRect t = titlebar->geometry(); + t.setTop( 0 ); + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.eraseRect( rect() ); + }*/ +} + +void SystemClient::recalcTitleBuffer() +{ + if(oldTitle == caption() && width() == titleBuffer.width()) + return; + QFontMetrics fm(options->font(true)); + titleBuffer.resize(width(), 18); + QPainter p; + p.begin(&titleBuffer); + if(aUpperGradient) + p.drawTiledPixmap(0, 0, width(), 18, *aUpperGradient); + else + p.fillRect(0, 0, width(), 18, + options->colorGroup(Options::Frame, true). + brush(QColorGroup::Button)); + + QRect t = titlebar->geometry(); + t.setTop( 2 ); + t.setLeft( t.left() + 4 ); + t.setRight( t.right() - 2 ); + + QRegion r(t.x(), 0, t.width(), 18); + r -= QRect(t.x()+((t.width()-fm.width(caption()))/2)-4, + 0, fm.width(caption())+8, 18); + p.setClipRegion(r); + int i, ly; + for(i=0, ly=4; i < 4; ++i, ly+=3){ + p.setPen(options->color(Options::TitleBar, true).light(150)); + p.drawLine(0, ly, width()-1, ly); + p.setPen(options->color(Options::TitleBar, true).dark(120)); + p.drawLine(0, ly+1, width()-1, ly+1); + } + p.setClipRect(t); + p.setPen(options->color(Options::Font, true)); + p.setFont(options->font(true)); + + p.drawText(t.x()+((t.width()-fm.width(caption()))/2)-4, + 0, fm.width(caption())+8, 18, AlignCenter, caption()); + p.setClipping(false); + p.end(); + oldTitle = caption(); +} + +void SystemClient::captionChange( const QString &) +{ + recalcTitleBuffer(); + repaint( titlebar->geometry(), false ); +} + +void SystemClient::drawRoundFrame(QPainter &p, int x, int y, int w, int h) +{ + kDrawRoundButton(&p, x, y, w, h, + options->colorGroup(Options::Frame, isActive()), false); + +} + +void SystemClient::paintEvent( QPaintEvent* ) +{ + QPainter p( this ); + QRect t = titlebar->geometry(); + + QBrush fillBrush(colorGroup().brush(QColorGroup::Background).pixmap() ? + colorGroup().brush(QColorGroup::Background) : + options->colorGroup(Options::Frame, isActive()). + brush(QColorGroup::Button)); + + p.fillRect(1, 18, width()-2, height()-19, fillBrush); + + t.setTop( 2 ); + t.setLeft( t.left() + 4 ); + t.setRight( t.right() - 2 ); + + if(isActive()) + p.drawPixmap(0, 0, titleBuffer); + else{ + if(iUpperGradient) + p.drawTiledPixmap(0, 0, width(), 18, *iUpperGradient); + else + p.fillRect(0, 0, width(), 18, fillBrush); + p.setPen(options->color(Options::Font, isActive())); + p.setFont(options->font(isActive())); + p.drawText(t, AlignCenter, caption() ); + } + + + + p.setPen(options->colorGroup(Options::Frame, isActive()).light()); + p.drawLine(width()-20, height()-7, width()-10, height()-7); + p.drawLine(width()-20, height()-5, width()-10, height()-5); + p.setPen(options->colorGroup(Options::Frame, isActive()).dark()); + p.drawLine(width()-20, height()-6, width()-10, height()-6); + p.drawLine(width()-20, height()-4, width()-10, height()-4); + + drawRoundFrame(p, 0, 0, width(), height()); +} + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + +void SystemClient::doShape() +{ + // using a bunch of QRect lines seems much more efficent than bitmaps or + // point arrays + + QRegion mask; + kRoundMaskRegion(mask, 0, 0, width(), height()); + setMask(mask); +} + +void SystemClient::showEvent(QShowEvent *ev) +{ + Client::showEvent(ev); + doShape(); + repaint(); +} + +void SystemClient::windowWrapperShowEvent( QShowEvent* ) +{ + doShape(); +} + +void SystemClient::mouseDoubleClickEvent( QMouseEvent * e ) +{ + if (titlebar->geometry().contains( e->pos() ) ) + workspace()->performWindowOperation( this, options->operationTitlebarDblClick() ); + workspace()->requestFocus( this ); +} + +void SystemClient::stickyChange(bool on) +{ + button[1]->setBitmap(on ? unsticky_bits : sticky_bits); +} + +void SystemClient::maximizeChange(bool m) +{ + button[3]->setBitmap(m ? minmax_bits : maximize_bits); +} + +void SystemClient::init() +{ + // +} + +void SystemClient::activeChange(bool) +{ + repaint(false); + button[0]->reset(); + button[1]->reset(); + button[2]->reset(); + button[3]->reset(); + if(button[4]) + button[4]->reset(); +} + +extern "C" +{ + Client *allocate(Workspace *ws, WId w, int) + { + return(new SystemClient(ws, w)); + } + void init() + { + create_pixmaps(); + } + void reset() + { + delete_pixmaps(); + create_pixmaps(); + } + void deinit() + { + delete_pixmaps(); + } +} + +#include "systemclient.moc" diff --git a/clients/system/systemclient.h b/clients/system/systemclient.h new file mode 100644 index 0000000000..49991427bb --- /dev/null +++ b/clients/system/systemclient.h @@ -0,0 +1,79 @@ +#ifndef __SYSTEMCLIENT_H +#define __SYSTEMCLIENT_H + +#include +#include + +#include +#include +#include "../../client.h" + + +class QLabel; +class QSpacerItem; + +namespace KWinInternal { + +class SystemButton : public QToolButton +{ + Q_OBJECT +public: + SystemButton(Client *parent=0, const char *name=0, + const unsigned char *bitmap=NULL); + void setBitmap(const unsigned char *bitmap); + void reset(); + QSize sizeHint() const; +signals: + void clicked( int ); +protected: + virtual void drawButton(QPainter *p); + void drawButtonLabel(QPainter *){;} + QBitmap deco; + Client *client; + + void mousePressEvent( QMouseEvent* e ); + void mouseReleaseEvent( QMouseEvent* e ); + +private slots: + void handleClicked(); + +private: + int last_button; + +}; + +class SystemClient : public KWinInternal::Client +{ + Q_OBJECT +public: + SystemClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 ); + ~SystemClient(){;} +protected: + void drawRoundFrame(QPainter &p, int x, int y, int w, int h); + void resizeEvent( QResizeEvent* ); + void paintEvent( QPaintEvent* ); + void showEvent( QShowEvent* ); + void windowWrapperShowEvent( QShowEvent* ); + void mouseDoubleClickEvent( QMouseEvent * ); + void init(); + void captionChange( const QString& name ); + void stickyChange(bool on); + void maximizeChange(bool m); + void doShape(); + void recalcTitleBuffer(); + void activeChange(bool); +protected slots: + void slotReset(); +private slots: + void maxButtonClicked( int ); + +private: + SystemButton* button[5]; + QSpacerItem* titlebar; + QPixmap titleBuffer; + QString oldTitle; +}; + +}; + +#endif